| From a7be300de800e755714c71103ae4a0d205e41e99 Mon Sep 17 00:00:00 2001 |
| From: Jan Kara <jack@suse.cz> |
| Date: Tue, 22 Sep 2020 12:20:14 +0200 |
| Subject: udf: Fix memory leak when mounting |
| |
| From: Jan Kara <jack@suse.cz> |
| |
| commit a7be300de800e755714c71103ae4a0d205e41e99 upstream. |
| |
| udf_process_sequence() allocates temporary array for processing |
| partition descriptors on volume which it fails to free. Free the array |
| when it is not needed anymore. |
| |
| Fixes: 7b78fd02fb19 ("udf: Fix handling of Partition Descriptors") |
| CC: stable@vger.kernel.org |
| Reported-by: syzbot+128f4dd6e796c98b3760@syzkaller.appspotmail.com |
| Signed-off-by: Jan Kara <jack@suse.cz> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/udf/super.c | 21 +++++++++++++-------- |
| 1 file changed, 13 insertions(+), 8 deletions(-) |
| |
| --- a/fs/udf/super.c |
| +++ b/fs/udf/super.c |
| @@ -1704,7 +1704,8 @@ static noinline int udf_process_sequence |
| "Pointers (max %u supported)\n", |
| UDF_MAX_TD_NESTING); |
| brelse(bh); |
| - return -EIO; |
| + ret = -EIO; |
| + goto out; |
| } |
| |
| vdp = (struct volDescPtr *)bh->b_data; |
| @@ -1724,7 +1725,8 @@ static noinline int udf_process_sequence |
| curr = get_volume_descriptor_record(ident, bh, &data); |
| if (IS_ERR(curr)) { |
| brelse(bh); |
| - return PTR_ERR(curr); |
| + ret = PTR_ERR(curr); |
| + goto out; |
| } |
| /* Descriptor we don't care about? */ |
| if (!curr) |
| @@ -1746,28 +1748,31 @@ static noinline int udf_process_sequence |
| */ |
| if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) { |
| udf_err(sb, "Primary Volume Descriptor not found!\n"); |
| - return -EAGAIN; |
| + ret = -EAGAIN; |
| + goto out; |
| } |
| ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block); |
| if (ret < 0) |
| - return ret; |
| + goto out; |
| |
| if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) { |
| ret = udf_load_logicalvol(sb, |
| data.vds[VDS_POS_LOGICAL_VOL_DESC].block, |
| fileset); |
| if (ret < 0) |
| - return ret; |
| + goto out; |
| } |
| |
| /* Now handle prevailing Partition Descriptors */ |
| for (i = 0; i < data.num_part_descs; i++) { |
| ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block); |
| if (ret < 0) |
| - return ret; |
| + goto out; |
| } |
| - |
| - return 0; |
| + ret = 0; |
| +out: |
| + kfree(data.part_descs_loc); |
| + return ret; |
| } |
| |
| /* |