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> --- include/erofs/internal.h | 1 + lib/compress.c | 2 ++ lib/inode.c | 3 +++ lib/rebuild.c | 3 ++- lib/super.c | 8 ++++++++ mkfs/main.c | 2 +- 6 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/erofs/internal.h b/include/erofs/internal.h index 9a82e06..3e1000d 100644 --- a/include/erofs/internal.h +++ b/include/erofs/internal.h @@ -153,6 +153,7 @@ struct erofs_sb_info { struct erofs_buffer_head *bh_sb; struct erofs_buffer_head *bh_devt; bool useqpl; + bool sb_valid; }; /* make sure that any user of the erofs headers has atleast 64bit off_t type */ 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..64779cb 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,6 +428,7 @@ 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); diff --git a/lib/super.c b/lib/super.c index a9ec3aa..4f21efe 100644 --- a/lib/super.c +++ b/lib/super.c @@ -78,6 +78,9 @@ int erofs_read_superblock(struct erofs_sb_info *sbi) struct erofs_super_block *dsb; int read, ret; + if (sbi->sb_valid) + return 0; + read = erofs_io_pread(&sbi->bdev, data, EROFS_MAX_BLOCK_SIZE, 0); if (read < EROFS_SUPER_OFFSET + sizeof(*dsb)) { ret = read < 0 ? read : -EIO; @@ -151,6 +154,9 @@ int erofs_read_superblock(struct erofs_sb_info *sbi) free(sbi->devs); sbi->devs = NULL; } + + sbi->sb_valid = !ret; + return ret; } @@ -170,6 +176,8 @@ void erofs_put_super(struct erofs_sb_info *sbi) erofs_buffer_exit(sbi->bmgr); sbi->bmgr = NULL; } + + sbi->sb_valid = false; } int erofs_writesb(struct erofs_sb_info *sbi) 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(); -- 2.43.0