]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
xattr-util: check if fd has O_PATH and do not try setxattr() twice
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 16 Feb 2023 22:34:13 +0000 (07:34 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 16 Feb 2023 22:34:49 +0000 (07:34 +0900)
Follow-up for a4d2461c46f40c9ae5002a2aea35b35ccb60ef9c.

src/basic/xattr-util.c

index 746e9f369e00764b82d1adbe672e7e8ec64c1b6e..b42bf68f5808a87bb1ebc20d77c458a2a0f02153 100644 (file)
@@ -330,8 +330,14 @@ int xsetxattr(int fd,
 
                 if (fd == AT_FDCWD) /* Both unspecified? Then operate on current working directory */
                         path = ".";
-                else
+                else {
+                        r = fd_is_opath(fd);
+                        if (r < 0)
+                                return r;
+
+                        by_procfs = r;
                         path = NULL;
+                }
 
         } else if (fd != AT_FDCWD) {
 
@@ -345,25 +351,14 @@ int xsetxattr(int fd,
                 by_procfs = true; /* fsetxattr() is not going to work, go via /proc/ link right-away */
         }
 
-        for (;;) {
-                if (path)
-                        r = FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? setxattr(path, name, value, size, 0)
-                                                                : lsetxattr(path, name, value, size, 0);
-                else
-                        r = by_procfs ? setxattr(FORMAT_PROC_FD_PATH(fd), name, value, size, 0)
-                                      : fsetxattr(fd, name, value, size, 0);
-                if (r < 0) {
-                        if (errno == EBADF) {
-                                if (by_procfs || path)
-                                        return -EBADF;
-
-                                by_procfs = true; /* Might be an O_PATH fd, try again via /proc/ link */
-                                continue;
-                        }
-
-                        return -errno;
-                }
+        if (path)
+                r = FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? setxattr(path, name, value, size, 0)
+                                                        : lsetxattr(path, name, value, size, 0);
+        else
+                r = by_procfs ? setxattr(FORMAT_PROC_FD_PATH(fd), name, value, size, 0)
+                              : fsetxattr(fd, name, value, size, 0);
+        if (r < 0)
+                return -errno;
 
-                return 0;
-        }
+        return 0;
 }