tags 986332 +pending
thanks

The following commit should fix things; it will be in the next release
of e2fsprogs.

                                                - Ted

commit a3f844da91f0c01209a5d778a5af57fabe245332
Author: Theodore Ts'o <ty...@mit.edu>
Date:   Fri Jul 16 22:31:26 2021 -0400

    libe2p: use stat to prevent calling EXT2_IOC_[GS]ETFLAGS on devices
    
    Some devices can react badly to the EXT2_IOC_[GS]ETFLAGS ioctls, since
    ioctl codes are not guaranteed to be unique across different device
    drivers and file systems.
    
    Addresses-Debian-Bug: #986332
    Signed-off-by: Theodore Ts'o <ty...@mit.edu>

diff --git a/lib/e2p/fgetflags.c b/lib/e2p/fgetflags.c
index 93e130c6..24a7166b 100644
--- a/lib/e2p/fgetflags.c
+++ b/lib/e2p/fgetflags.c
@@ -79,14 +79,26 @@ int fgetflags (const char * name, unsigned long * flags)
        *flags = f;
        return (save_errno);
 #elif HAVE_EXT2_IOCTLS
+       struct stat buf;
        int fd, r, f, save_errno = 0;
 
+       if (!stat(name, &buf) &&
+           !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
+               errno = EOPNOTSUPP;
+               return -1;
+       }
        fd = open(name, OPEN_FLAGS);
        if (fd == -1) {
                if (errno == ELOOP || errno == ENXIO)
                        errno = EOPNOTSUPP;
                return -1;
        }
+       if (!fstat(fd, &buf) &&
+           !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
+               close(fd);
+               errno = EOPNOTSUPP;
+               return -1;
+       }
        r = ioctl(fd, EXT2_IOC_GETFLAGS, &f);
        if (r == -1) {
                if (errno == ENOTTY)
diff --git a/lib/e2p/fsetflags.c b/lib/e2p/fsetflags.c
index 6455e386..d865d243 100644
--- a/lib/e2p/fsetflags.c
+++ b/lib/e2p/fsetflags.c
@@ -80,14 +80,26 @@ int fsetflags (const char * name, unsigned long flags)
        int f = (int) flags;
        return syscall(SYS_fsctl, name, EXT2_IOC_SETFLAGS, &f, 0);
 #elif HAVE_EXT2_IOCTLS
+       struct stat buf;
        int fd, r, f, save_errno = 0;
 
+       if (!stat(name, &buf) &&
+           !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
+               errno = EOPNOTSUPP;
+               return -1;
+       }
        fd = open(name, OPEN_FLAGS);
        if (fd == -1) {
                if (errno == ELOOP || errno == ENXIO)
                        errno = EOPNOTSUPP;
                return -1;
        }
+       if (!fstat(fd, &buf) &&
+           !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
+               close(fd);
+               errno = EOPNOTSUPP;
+               return -1;
+       }
        f = (int) flags;
        r = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
        if (r == -1) {

Reply via email to