]> git.proxmox.com Git - mirror_ubuntu-hirsute-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)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Mon, 12 Apr 2021 12:50:29 +0000 (09:50 -0300)
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>
fs/shiftfs.c

index 4f1d949035572a21a7e7d1df2268f1f8245b7741..8eab93691d626c0ae2f334cbe44cc9cbef22a6ec 100644 (file)
@@ -1438,6 +1438,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;
 
@@ -1446,23 +1449,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;
        }
 
        /*
@@ -1477,7 +1480,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);
@@ -1492,8 +1496,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;
 }