Message ID | 20240320113156.22283-1-mheyne@amazon.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: allocate btrfs_ioctl_defrag_range_args on stack | expand |
On Wed, Mar 20, 2024 at 11:31:56AM +0000, Maximilian Heyne wrote: > From: Goldwyn Rodrigues <rgoldwyn@suse.com> > > commit c853a5783ebe123847886d432354931874367292 upstream. > > Instead of using kmalloc() to allocate btrfs_ioctl_defrag_range_args, > allocate btrfs_ioctl_defrag_range_args on stack, the size is reasonably > small and ioctls are called in process context. > > sizeof(btrfs_ioctl_defrag_range_args) = 48 > > Reviewed-by: Anand Jain <anand.jain@oracle.com> > Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> > Reviewed-by: David Sterba <dsterba@suse.com> > Signed-off-by: David Sterba <dsterba@suse.com> > CC: stable@vger.kernel.org # 4.14+ > [ This patch is needed to fix a memory leak of "range" that was > introduced when commit 173431b274a9 ("btrfs: defrag: reject unknown > flags of btrfs_ioctl_defrag_range_args") was backported to kernels > lacking this patch. Now with these two patches applied in reverse order, > range->flags needed to change back to range.flags. > This bug was discovered and resolved using Coverity Static Analysis > Security Testing (SAST) by Synopsys, Inc.] > Signed-off-by: Maximilian Heyne <mheyne@amazon.de> Acked-by: David Sterba <dsterba@suse.com> for backport to stable as a prerequisite for 173431b274a9a5 ("btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args").
On Wed, Mar 20, 2024 at 05:14:33PM +0100, David Sterba wrote: > On Wed, Mar 20, 2024 at 11:31:56AM +0000, Maximilian Heyne wrote: > > From: Goldwyn Rodrigues <rgoldwyn@suse.com> > > > > commit c853a5783ebe123847886d432354931874367292 upstream. > > > > Instead of using kmalloc() to allocate btrfs_ioctl_defrag_range_args, > > allocate btrfs_ioctl_defrag_range_args on stack, the size is reasonably > > small and ioctls are called in process context. > > > > sizeof(btrfs_ioctl_defrag_range_args) = 48 > > > > Reviewed-by: Anand Jain <anand.jain@oracle.com> > > Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> > > Reviewed-by: David Sterba <dsterba@suse.com> > > Signed-off-by: David Sterba <dsterba@suse.com> > > CC: stable@vger.kernel.org # 4.14+ > > [ This patch is needed to fix a memory leak of "range" that was > > introduced when commit 173431b274a9 ("btrfs: defrag: reject unknown > > flags of btrfs_ioctl_defrag_range_args") was backported to kernels > > lacking this patch. Now with these two patches applied in reverse order, > > range->flags needed to change back to range.flags. > > This bug was discovered and resolved using Coverity Static Analysis > > Security Testing (SAST) by Synopsys, Inc.] > > Signed-off-by: Maximilian Heyne <mheyne@amazon.de> > > Acked-by: David Sterba <dsterba@suse.com> > > for backport to stable as a prerequisite for 173431b274a9a5 ("btrfs: > defrag: reject unknown flags of btrfs_ioctl_defrag_range_args"). > Now queued up, thanks! greg k-h
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 049b837934e5..ab8ed187746e 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3148,7 +3148,7 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) { struct inode *inode = file_inode(file); struct btrfs_root *root = BTRFS_I(inode)->root; - struct btrfs_ioctl_defrag_range_args *range; + struct btrfs_ioctl_defrag_range_args range = {0}; int ret; ret = mnt_want_write_file(file); @@ -3180,37 +3180,28 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) goto out; } - range = kzalloc(sizeof(*range), GFP_KERNEL); - if (!range) { - ret = -ENOMEM; - goto out; - } - if (argp) { - if (copy_from_user(range, argp, - sizeof(*range))) { + if (copy_from_user(&range, argp, sizeof(range))) { ret = -EFAULT; - kfree(range); goto out; } - if (range->flags & ~BTRFS_DEFRAG_RANGE_FLAGS_SUPP) { + if (range.flags & ~BTRFS_DEFRAG_RANGE_FLAGS_SUPP) { ret = -EOPNOTSUPP; goto out; } /* compression requires us to start the IO */ - if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { - range->flags |= BTRFS_DEFRAG_RANGE_START_IO; - range->extent_thresh = (u32)-1; + if ((range.flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { + range.flags |= BTRFS_DEFRAG_RANGE_START_IO; + range.extent_thresh = (u32)-1; } } else { /* the rest are all set to zero by kzalloc */ - range->len = (u64)-1; + range.len = (u64)-1; } ret = btrfs_defrag_file(file_inode(file), file, - range, BTRFS_OLDEST_GENERATION, 0); + &range, BTRFS_OLDEST_GENERATION, 0); if (ret > 0) ret = 0; - kfree(range); break; default: ret = -EINVAL;