summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeth Forshee <seth.forshee@canonical.com>2021-04-09 13:01:06 -0500
committerStefan Bader <stefan.bader@canonical.com>2021-04-12 17:10:51 +0200
commit8fee52ab9da87d82bc6de9ebb3480fff9b4d53e6 (patch)
tree656653efdcdf3ec599efa19cd422f872f84320db
parent75891ef8c55d4b1b899355c50dd3d7d0bae82a89 (diff)
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 <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>
-rw-r--r--fs/shiftfs.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/fs/shiftfs.c b/fs/shiftfs.c
index 6f40cb92..5dfa414 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;
}