]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
util: make sure fd refers to regular file or directory when applying file attributes
authorLennart Poettering <lennart@poettering.net>
Wed, 22 Apr 2015 11:05:26 +0000 (13:05 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 22 Apr 2015 11:27:53 +0000 (13:27 +0200)
Before invoking file system ioctls we need to make sure that the
specified fd actually refers to a file system object, and not a device
node or similar. Otherwise we might by accident invoke unrelated device
driver ioctls. For example, DRM ioctls use the same ioctl numbers as the
various file system ioctls.

src/shared/util.c

index f14d9ee90ba2a95890187f87ae3a1fdd47cf9cdc..4a044840bd40f636a49bfc24edc5ffbda08d3ca6 100644 (file)
@@ -5988,9 +5988,22 @@ int same_fd(int a, int b) {
 
 int chattr_fd(int fd, unsigned value, unsigned mask) {
         unsigned old_attr, new_attr;
+        struct stat st;
 
         assert(fd >= 0);
 
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        /* Explicitly check whether this is a regular file or
+         * directory. If it is anything else (such as a device node or
+         * fifo), then the ioctl will not hit the file systems but
+         * possibly drivers, where the ioctl might have different
+         * effects. Notably, DRM is using the same ioctl() number. */
+
+        if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
+                return -ENOTTY;
+
         if (mask == 0)
                 return 0;
 
@@ -6023,8 +6036,16 @@ int chattr_path(const char *p, unsigned value, unsigned mask) {
 }
 
 int read_attr_fd(int fd, unsigned *ret) {
+        struct stat st;
+
         assert(fd >= 0);
 
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
+                return -ENOTTY;
+
         if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
                 return -errno;