1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-01 00:51:24 +03:00

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.
This commit is contained in:
Lennart Poettering 2015-04-22 13:05:26 +02:00
parent 163ab29612
commit 03091baac3

View File

@ -5988,9 +5988,22 @@ int same_fd(int a, int b) {
int chattr_fd(int fd, unsigned value, unsigned mask) { int chattr_fd(int fd, unsigned value, unsigned mask) {
unsigned old_attr, new_attr; unsigned old_attr, new_attr;
struct stat st;
assert(fd >= 0); 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) if (mask == 0)
return 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) { int read_attr_fd(int fd, unsigned *ret) {
struct stat st;
assert(fd >= 0); 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) if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
return -errno; return -errno;