fcntl: Cast commands with int args explicitly
authorLuca Vizzarro <Luca.Vizzarro@arm.com>
Thu, 2 Feb 2023 11:58:31 +0000 (11:58 +0000)
committerChristian Brauner <brauner@kernel.org>
Mon, 10 Jul 2023 12:36:11 +0000 (14:36 +0200)
According to the fcntl API specification commands that expect an
integer, hence not a pointer, always take an int and not long. In
order to avoid access to undefined bits, we should explicitly cast
the argument to int.

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jeff Layton <jlayton@kernel.org>
Cc: Chuck Lever <chuck.lever@oracle.com>
Cc: Kevin Brodsky <Kevin.Brodsky@arm.com>
Cc: Vincenzo Frascino <Vincenzo.Frascino@arm.com>
Cc: Szabolcs Nagy <Szabolcs.Nagy@arm.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: David Laight <David.Laight@ACULAB.com>
Cc: Mark Rutland <Mark.Rutland@arm.com>
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-morello@op-lists.linaro.org
Signed-off-by: Luca Vizzarro <Luca.Vizzarro@arm.com>
Message-Id: <20230414152459.816046-2-Luca.Vizzarro@arm.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/fcntl.c
include/linux/fs.h

index b622be119706a1a643e5b382af576e693d0ca4b8..e871009f6c8895cdcb2787040e268247439b0e92 100644 (file)
@@ -34,7 +34,7 @@
 
 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
 
-static int setfl(int fd, struct file * filp, unsigned long arg)
+static int setfl(int fd, struct file * filp, unsigned int arg)
 {
        struct inode * inode = file_inode(filp);
        int error = 0;
@@ -112,11 +112,11 @@ void __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
 }
 EXPORT_SYMBOL(__f_setown);
 
-int f_setown(struct file *filp, unsigned long arg, int force)
+int f_setown(struct file *filp, int who, int force)
 {
        enum pid_type type;
        struct pid *pid = NULL;
-       int who = arg, ret = 0;
+       int ret = 0;
 
        type = PIDTYPE_TGID;
        if (who < 0) {
@@ -317,28 +317,29 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
                struct file *filp)
 {
        void __user *argp = (void __user *)arg;
+       int argi = (int)arg;
        struct flock flock;
        long err = -EINVAL;
 
        switch (cmd) {
        case F_DUPFD:
-               err = f_dupfd(arg, filp, 0);
+               err = f_dupfd(argi, filp, 0);
                break;
        case F_DUPFD_CLOEXEC:
-               err = f_dupfd(arg, filp, O_CLOEXEC);
+               err = f_dupfd(argi, filp, O_CLOEXEC);
                break;
        case F_GETFD:
                err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
                break;
        case F_SETFD:
                err = 0;
-               set_close_on_exec(fd, arg & FD_CLOEXEC);
+               set_close_on_exec(fd, argi & FD_CLOEXEC);
                break;
        case F_GETFL:
                err = filp->f_flags;
                break;
        case F_SETFL:
-               err = setfl(fd, filp, arg);
+               err = setfl(fd, filp, argi);
                break;
 #if BITS_PER_LONG != 32
        /* 32-bit arches must use fcntl64() */
@@ -375,7 +376,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
                force_successful_syscall_return();
                break;
        case F_SETOWN:
-               err = f_setown(filp, arg, 1);
+               err = f_setown(filp, argi, 1);
                break;
        case F_GETOWN_EX:
                err = f_getown_ex(filp, arg);
@@ -391,28 +392,28 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
                break;
        case F_SETSIG:
                /* arg == 0 restores default behaviour. */
-               if (!valid_signal(arg)) {
+               if (!valid_signal(argi)) {
                        break;
                }
                err = 0;
-               filp->f_owner.signum = arg;
+               filp->f_owner.signum = argi;
                break;
        case F_GETLEASE:
                err = fcntl_getlease(filp);
                break;
        case F_SETLEASE:
-               err = fcntl_setlease(fd, filp, arg);
+               err = fcntl_setlease(fd, filp, argi);
                break;
        case F_NOTIFY:
-               err = fcntl_dirnotify(fd, filp, arg);
+               err = fcntl_dirnotify(fd, filp, argi);
                break;
        case F_SETPIPE_SZ:
        case F_GETPIPE_SZ:
-               err = pipe_fcntl(filp, cmd, arg);
+               err = pipe_fcntl(filp, cmd, argi);
                break;
        case F_ADD_SEALS:
        case F_GET_SEALS:
-               err = memfd_fcntl(filp, cmd, arg);
+               err = memfd_fcntl(filp, cmd, argi);
                break;
        case F_GET_RW_HINT:
        case F_SET_RW_HINT:
index 6867512907d6e593ec18cbd27dc52471b66418a0..8e546433c781186c08511d95f528faefde70cc92 100644 (file)
@@ -1069,7 +1069,7 @@ extern void fasync_free(struct fasync_struct *);
 extern void kill_fasync(struct fasync_struct **, int, int);
 
 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
-extern int f_setown(struct file *filp, unsigned long arg, int force);
+extern int f_setown(struct file *filp, int who, int force);
 extern void f_delown(struct file *filp);
 extern pid_t f_getown(struct file *filp);
 extern int send_sigurg(struct fown_struct *fown);