diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2014-09-04 07:09:15 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2014-09-08 16:56:42 -0400 |
commit | c47ca32d3aadb234f73389a34c97574085bc9eda (patch) | |
tree | c53ea33e0067560a26f0122b0b606cc5743b8acc | |
parent | dac5705cad20070a70bb028ca52e1f0bc157b42d (diff) |
Btrfs: kfree()ing ERR_PTRs
The "inherit" in btrfs_ioctl_snap_create_v2() and "vol_args" in
btrfs_ioctl_rm_dev() are ERR_PTRs so we can't call kfree() on them.
These kind of bugs are "One Err Bugs" where there is just one error
label that does everything. I could set the "inherit = NULL" and keep
the single out label but it ends up being more complicated that way. It
makes the code simpler to re-order the unwind so it's in the mirror
order of the allocation and introduce some new error labels.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r-- | fs/btrfs/ioctl.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a018ea484d39..8a8e29878c34 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1703,7 +1703,7 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, | |||
1703 | ~(BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY | | 1703 | ~(BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY | |
1704 | BTRFS_SUBVOL_QGROUP_INHERIT)) { | 1704 | BTRFS_SUBVOL_QGROUP_INHERIT)) { |
1705 | ret = -EOPNOTSUPP; | 1705 | ret = -EOPNOTSUPP; |
1706 | goto out; | 1706 | goto free_args; |
1707 | } | 1707 | } |
1708 | 1708 | ||
1709 | if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC) | 1709 | if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC) |
@@ -1713,27 +1713,31 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, | |||
1713 | if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) { | 1713 | if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) { |
1714 | if (vol_args->size > PAGE_CACHE_SIZE) { | 1714 | if (vol_args->size > PAGE_CACHE_SIZE) { |
1715 | ret = -EINVAL; | 1715 | ret = -EINVAL; |
1716 | goto out; | 1716 | goto free_args; |
1717 | } | 1717 | } |
1718 | inherit = memdup_user(vol_args->qgroup_inherit, vol_args->size); | 1718 | inherit = memdup_user(vol_args->qgroup_inherit, vol_args->size); |
1719 | if (IS_ERR(inherit)) { | 1719 | if (IS_ERR(inherit)) { |
1720 | ret = PTR_ERR(inherit); | 1720 | ret = PTR_ERR(inherit); |
1721 | goto out; | 1721 | goto free_args; |
1722 | } | 1722 | } |
1723 | } | 1723 | } |
1724 | 1724 | ||
1725 | ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, | 1725 | ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, |
1726 | vol_args->fd, subvol, ptr, | 1726 | vol_args->fd, subvol, ptr, |
1727 | readonly, inherit); | 1727 | readonly, inherit); |
1728 | if (ret) | ||
1729 | goto free_inherit; | ||
1728 | 1730 | ||
1729 | if (ret == 0 && ptr && | 1731 | if (ptr && copy_to_user(arg + |
1730 | copy_to_user(arg + | 1732 | offsetof(struct btrfs_ioctl_vol_args_v2, |
1731 | offsetof(struct btrfs_ioctl_vol_args_v2, | 1733 | transid), |
1732 | transid), ptr, sizeof(*ptr))) | 1734 | ptr, sizeof(*ptr))) |
1733 | ret = -EFAULT; | 1735 | ret = -EFAULT; |
1734 | out: | 1736 | |
1735 | kfree(vol_args); | 1737 | free_inherit: |
1736 | kfree(inherit); | 1738 | kfree(inherit); |
1739 | free_args: | ||
1740 | kfree(vol_args); | ||
1737 | return ret; | 1741 | return ret; |
1738 | } | 1742 | } |
1739 | 1743 | ||
@@ -2653,7 +2657,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | |||
2653 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 2657 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
2654 | if (IS_ERR(vol_args)) { | 2658 | if (IS_ERR(vol_args)) { |
2655 | ret = PTR_ERR(vol_args); | 2659 | ret = PTR_ERR(vol_args); |
2656 | goto out; | 2660 | goto err_drop; |
2657 | } | 2661 | } |
2658 | 2662 | ||
2659 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 2663 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
@@ -2671,6 +2675,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | |||
2671 | 2675 | ||
2672 | out: | 2676 | out: |
2673 | kfree(vol_args); | 2677 | kfree(vol_args); |
2678 | err_drop: | ||
2674 | mnt_drop_write_file(file); | 2679 | mnt_drop_write_file(file); |
2675 | return ret; | 2680 | return ret; |
2676 | } | 2681 | } |