On 2025/9/10 13:14 Gao Xiang wrote:
> On 2025/9/10 13:05, Yuezhang Mo wrote:
>> This patch addresses 4 memory leaks and 1 allocation issue to
>> ensure proper cleanup and allocation:
>>
>> 1. Fixed memory leak by freeing sbi->zmgr in z_erofs_compress_exit().
>> 2. Fixed memory leak by freeing inode->chunkindexes in erofs_iput().
>> 3. Fixed incorrect allocation of chunk index array in
>>     erofs_rebuild_write_blob_index() to ensure correct array allocation
>>     and avoid out-of-bounds access.
>> 4. Fixed memory leak of struct erofs_blobchunk not being freed by
>>     calling erofs_blob_exit() in rebuild mode.
>> 5. Fixed memory leak caused by repeated initialization of the first
>>     blob device's sbi by checking whether sbi has been initialized.
>>
>> Signed-off-by: Yuezhang Mo <yuezhang...@sony.com>
>> Reviewed-by: Friendy Su <friendy...@sony.com>
>> Reviewed-by: Daniel Palmer <daniel.pal...@sony.com>
>> ---
>>   lib/compress.c |  2 ++
>>   lib/inode.c    |  3 +++
>>   lib/rebuild.c  | 13 ++++++++-----
>>   mkfs/main.c    |  2 +-
>>   4 files changed, 14 insertions(+), 6 deletions(-)
>>
>> diff --git a/lib/compress.c b/lib/compress.c
>> index 622a205..dd537ec 100644
>> --- a/lib/compress.c
>> +++ b/lib/compress.c
>> @@ -2171,5 +2171,7 @@ int z_erofs_compress_exit(struct erofs_sb_info *sbi)
>>               }
>>   #endif
>>       }
>> +
>> +     free(sbi->zmgr);
>>       return 0;
>>   }
>> diff --git a/lib/inode.c b/lib/inode.c
>> index 7ee6b3d..38e2bb2 100644
>> --- a/lib/inode.c
>> +++ b/lib/inode.c
>> @@ -159,6 +159,9 @@ unsigned int erofs_iput(struct erofs_inode *inode)
>>       } else {
>>               free(inode->i_link);
>>       }
>> +
>> +     if (inode->datalayout == EROFS_INODE_CHUNK_BASED)
>> +             free(inode->chunkindexes);
>>       free(inode);
>>       return 0;
>>   }
>> diff --git a/lib/rebuild.c b/lib/rebuild.c
>> index 0358567..461e18e 100644
>> --- a/lib/rebuild.c
>> +++ b/lib/rebuild.c
>> @@ -186,7 +186,7 @@ static int erofs_rebuild_write_blob_index(struct 
>> erofs_sb_info *dst_sb,
>>
>>       unit = sizeof(struct erofs_inode_chunk_index);
>>       inode->extent_isize = count * unit;
>> -     idx = malloc(max(sizeof(*idx), sizeof(void *)));
>> +     idx = calloc(count, max(sizeof(*idx), sizeof(void *)));
>>       if (!idx)
>>               return -ENOMEM;
>>       inode->chunkindexes = idx;
>> @@ -428,10 +428,13 @@ int erofs_rebuild_load_tree(struct erofs_inode *root, 
>> struct erofs_sb_info *sbi,
>>               erofs_uuid_unparse_lower(sbi->uuid, uuid_str);
>>               fsid = uuid_str;
>>       }
>> -     ret = erofs_read_superblock(sbi);
>> -     if (ret) {
>> -             erofs_err("failed to read superblock of %s", fsid);
>> -             return ret;
>> +
>> +     if (!sbi->devs) {
>
> `sbi->devs` may be NULL if ondisk_extradevs == 0? (see
> erofs_init_devices()).
>
> I think we could just introduce a new `sbi->sb_valid`
> boolean, and set up this in erofs_read_superblock()
> instead in the short term.

For rebuild mode, ondisk_extradevs is not 0, `sbi->devs` is always set.

Is there a case where erofs_read_superblock() is called multiple times
if not in rebuild mode? Or will there be such a case in the future?

>
> Thanks,
> Gao Xiang
>
>> +             ret = erofs_read_superblock(sbi);
>> +             if (ret) {
>> +                     erofs_err("failed to read superblock of %s", fsid);
>> +                     return ret;
>> +             }
>>       }
>>
>>       inode.nid = sbi->root_nid;
>> diff --git a/mkfs/main.c b/mkfs/main.c
>> index 28588db..3dd5815 100644
>> --- a/mkfs/main.c
>> +++ b/mkfs/main.c
>> @@ -1908,7 +1908,7 @@ exit:
>>       erofs_dev_close(&g_sbi);
>>       erofs_cleanup_compress_hints();
>>       erofs_cleanup_exclude_rules();
>> -     if (cfg.c_chunkbits)
>> +     if (cfg.c_chunkbits || source_mode == EROFS_MKFS_SOURCE_REBUILD)
>>               erofs_blob_exit();
>>       erofs_xattr_cleanup_name_prefixes();
>>       erofs_rebuild_cleanup();

Reply via email to