From e50b238ba361def3ce7987b0ca58f4f90e6dfd99 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Apr 2015 13:05:26 +0200 Subject: [PATCH] util: make sure fd refers to regular file or directory when applying file attributes 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 | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/shared/util.c b/src/shared/util.c index ce23b4790..f9094cc7e 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5923,9 +5923,22 @@ int fd_setcrtime(int fd, usec_t usec) { 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; @@ -5958,8 +5971,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; -- 2.30.2