From 03091baac3c37094af6a30be31e4962dd26f8404 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Apr 2015 13:05:26 +0200 Subject: 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(+) (limited to 'src/shared') diff --git a/src/shared/util.c b/src/shared/util.c index f14d9ee90b..4a044840bd 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -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; -- cgit v1.2.3-54-g00ecf