From: Seth Forshee Date: Fri, 9 Apr 2021 18:01:06 +0000 (-0500) Subject: UBUNTU: SAUCE: shiftfs: free allocated memory in shiftfs_btrfs_ioctl_fd_replace(... X-Git-Tag: Ubuntu-5.4.0-74.83~1162 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=8fee52ab9da87d82bc6de9ebb3480fff9b4d53e6;p=mirror_ubuntu-focal-kernel.git UBUNTU: SAUCE: shiftfs: free allocated memory in shiftfs_btrfs_ioctl_fd_replace() error paths 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 CVE-2021-3492 Signed-off-by: Thadeu Lima de Souza Cascardo Acked-by: Stefan Bader Acked-by: Marcelo Cerri Signed-off-by: Stefan Bader --- diff --git a/fs/shiftfs.c b/fs/shiftfs.c index 6f40cb9272be..5dfa41423697 100644 --- a/fs/shiftfs.c +++ b/fs/shiftfs.c @@ -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; }