From: Gao Xiang Date: Fri, 21 Mar 2025 09:25:59 +0000 (+0800) Subject: erofs-utils: fix heap-buffer-overflow in fragment cache X-Git-Tag: accepted/tizen/unified/20250610.081809~26 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6d360771f9e07c3f6d585551a7b8a1e738c1280b;p=platform%2Fupstream%2Ferofs-utils.git erofs-utils: fix heap-buffer-overflow in fragment cache Allocated sizes are slightly smaller because the bitmap is `unsigned long *` instead of `unsigned char *`. Fixes: f511cfbbc0da ("erofs-utils: introduce fragment cache") Fixes: b763022c1c98 ("erofs-utils: lib: fix insufficient fragment cache bitmap") Signed-off-by: Gao Xiang Link: https://lore.kernel.org/r/20250321092600.3703493-1-hsiangkao@linux.alibaba.com --- diff --git a/lib/fragments.c b/lib/fragments.c index d300439..fecebb5 100644 --- a/lib/fragments.c +++ b/lib/fragments.c @@ -44,7 +44,7 @@ struct erofs_packed_inode { #if EROFS_MT_ENABLED pthread_mutex_t mutex; #endif - unsigned int uptodate_size; + u64 uptodate_bits; }; const char *erofs_frags_packedname = "packed_file"; @@ -402,8 +402,9 @@ int erofs_packedfile_init(struct erofs_sb_info *sbi, bool fragments_mkfs) err = -errno; goto err_out; } - epi->uptodate_size = DIV_ROUND_UP(BLK_ROUND_UP(sbi, ei.i_size), 8); - epi->uptodate = calloc(1, epi->uptodate_size); + epi->uptodate_bits = round_up(BLK_ROUND_UP(sbi, ei.i_size), + sizeof(epi->uptodate) * 8); + epi->uptodate = calloc(1, epi->uptodate_bits >> 3); if (!epi->uptodate) { err = -ENOMEM; goto err_out; @@ -473,7 +474,7 @@ static void *erofs_packedfile_preload(struct erofs_inode *pi, if (err < 0) { err = -errno; if (err == -ENOSPC) { - memset(epi->uptodate, 0, epi->uptodate_size); + memset(epi->uptodate, 0, epi->uptodate_bits >> 3); (void)!ftruncate(epi->fd, 0); } goto err_out; @@ -524,7 +525,7 @@ int erofs_packedfile_read(struct erofs_sb_info *sbi, erofs_blk_t bnr = erofs_blknr(sbi, pos); bool uptodate; - if (__erofs_unlikely(bnr > (epi->uptodate_size << 3))) { + if (__erofs_unlikely(bnr >= epi->uptodate_bits)) { erofs_err("packed inode EOF exceeded @ %llu", pos | 0ULL); return -EFSCORRUPTED;