]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
UBUNTU: SAUCE: shiftfs: free allocated memory in shiftfs_btrfs_ioctl_fd_replace(...
authorSeth Forshee <seth.forshee@canonical.com>
Fri, 9 Apr 2021 18:01:06 +0000 (13:01 -0500)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 12 Apr 2021 15:10:51 +0000 (17:10 +0200)
Many error paths in shiftfs_btrfs_ioctl_fd_replace() do not free memory
allocated near the top of the function. Fix up these error paths to free
the memory.

Additionally, the addresses for the allocated memory are assigned to
return parameters early in the function, before we know whether or not
the function as a whole will return success. Wait to assign these values
until we know the function was successful, and for good measure
initialize the return parameters to NULL at the start.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
CVE-2021-3492
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Marcelo Cerri <marcelo.cerri@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
fs/shiftfs.c

index 6f40cb9272be06eacae7fb9f225236b93f4f69a2..5dfa4142369749f2d0268fe8f33ce4771dc67362 100644 (file)
@@ -1437,6 +1437,9 @@ static int shiftfs_btrfs_ioctl_fd_replace(int cmd, void __user *arg,
        struct btrfs_ioctl_vol_args *v1 = NULL;
        struct btrfs_ioctl_vol_args_v2 *v2 = NULL;
 
+       *b1 = NULL;
+       *b2 = NULL;
+
        if (!is_btrfs_snap_ioctl(cmd))
                return 0;
 
@@ -1445,23 +1448,23 @@ static int shiftfs_btrfs_ioctl_fd_replace(int cmd, void __user *arg,
                if (IS_ERR(v1))
                        return PTR_ERR(v1);
                oldfd = v1->fd;
-               *b1 = v1;
        } else {
                v2 = memdup_user(arg, sizeof(*v2));
                if (IS_ERR(v2))
                        return PTR_ERR(v2);
                oldfd = v2->fd;
-               *b2 = v2;
        }
 
        src = fdget(oldfd);
-       if (!src.file)
-               return -EINVAL;
+       if (!src.file) {
+               ret = -EINVAL;
+               goto err_free;
+       }
 
        ret = shiftfs_real_fdget(src.file, &lfd);
        if (ret) {
                fdput(src);
-               return ret;
+               goto err_free;
        }
 
        /*
@@ -1476,7 +1479,8 @@ static int shiftfs_btrfs_ioctl_fd_replace(int cmd, void __user *arg,
        *newfd = get_unused_fd_flags(lfd.file->f_flags);
        if (*newfd < 0) {
                fdput(lfd);
-               return *newfd;
+               ret = *newfd;
+               goto err_free;
        }
 
        fd_install(*newfd, lfd.file);
@@ -1491,8 +1495,18 @@ static int shiftfs_btrfs_ioctl_fd_replace(int cmd, void __user *arg,
                v2->fd = oldfd;
        }
 
-       if (ret)
+       if (!ret) {
+               *b1 = v1;
+               *b2 = v2;
+       } else {
                shiftfs_btrfs_ioctl_fd_restore(cmd, *newfd, arg, v1, v2);
+       }
+
+       return ret;
+
+err_free:
+       kfree(v1);
+       kfree(v2);
 
        return ret;
 }