| From: Danila Chernetsov <listdansp@mail.ru> |
| Subject: ntfs: do not dereference a null ctx on error |
| Date: Fri, 7 Apr 2023 19:44:33 +0000 |
| |
| In ntfs_mft_data_extend_allocation_nolock(), if an error condition occurs |
| prior to 'ctx' being set to a non-NULL value, avoid dereferencing the NULL |
| 'ctx' pointer in error handling. |
| |
| Found by Linux Verification Center (linuxtesting.org) with SVACE. |
| |
| Link: https://lkml.kernel.org/r/20230407194433.25659-1-listdansp@mail.ru |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Signed-off-by: Danila Chernetsov <listdansp@mail.ru> |
| Cc: Anton Altaparmakov <anton@tuxera.com> |
| Cc: Bagas Sanjaya <bagasdotme@gmail.com> |
| Cc: Konstantin Komarov <almaz.alexandrovich@paragon-software.com> |
| Cc: Christian Brauner <brauner@kernel.org> |
| Cc: Namjae Jeon <linkinjeon@kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| fs/ntfs/mft.c | 38 +++++++++++++++++++++----------------- |
| 1 file changed, 21 insertions(+), 17 deletions(-) |
| |
| --- a/fs/ntfs/mft.c~ntfs-do-not-dereference-a-null-ctx-on-error |
| +++ a/fs/ntfs/mft.c |
| @@ -1955,36 +1955,40 @@ undo_alloc: |
| "attribute.%s", es); |
| NVolSetErrors(vol); |
| } |
| - a = ctx->attr; |
| + |
| if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) { |
| ntfs_error(vol->sb, "Failed to truncate mft data attribute " |
| "runlist.%s", es); |
| NVolSetErrors(vol); |
| } |
| - if (mp_rebuilt && !IS_ERR(ctx->mrec)) { |
| - if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( |
| + if (ctx) { |
| + a = ctx->attr; |
| + if (mp_rebuilt && !IS_ERR(ctx->mrec)) { |
| + if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( |
| a->data.non_resident.mapping_pairs_offset), |
| old_alen - le16_to_cpu( |
| - a->data.non_resident.mapping_pairs_offset), |
| + a->data.non_resident.mapping_pairs_offset), |
| rl2, ll, -1, NULL)) { |
| - ntfs_error(vol->sb, "Failed to restore mapping pairs " |
| + ntfs_error(vol->sb, "Failed to restore mapping pairs " |
| "array.%s", es); |
| - NVolSetErrors(vol); |
| - } |
| - if (ntfs_attr_record_resize(ctx->mrec, a, old_alen)) { |
| - ntfs_error(vol->sb, "Failed to restore attribute " |
| + NVolSetErrors(vol); |
| + } |
| + if (ntfs_attr_record_resize(ctx->mrec, a, old_alen)) { |
| + ntfs_error(vol->sb, "Failed to restore attribute " |
| "record.%s", es); |
| - NVolSetErrors(vol); |
| + NVolSetErrors(vol); |
| + } |
| + flush_dcache_mft_record_page(ctx->ntfs_ino); |
| + mark_mft_record_dirty(ctx->ntfs_ino); |
| } |
| - flush_dcache_mft_record_page(ctx->ntfs_ino); |
| - mark_mft_record_dirty(ctx->ntfs_ino); |
| - } else if (IS_ERR(ctx->mrec)) { |
| - ntfs_error(vol->sb, "Failed to restore attribute search " |
| + else if (IS_ERR(ctx->mrec)) { |
| + ntfs_error(vol->sb, "Failed to restore attribute search " |
| "context.%s", es); |
| - NVolSetErrors(vol); |
| + NVolSetErrors(vol); |
| + } |
| + if (ctx) |
| + ntfs_attr_put_search_ctx(ctx); |
| } |
| - if (ctx) |
| - ntfs_attr_put_search_ctx(ctx); |
| if (!IS_ERR(mrec)) |
| unmap_mft_record(mft_ni); |
| up_write(&mft_ni->runlist.lock); |
| _ |