identify_ramdisk_image() uses a zero block count to mark compressed images. A malformed legacy filesystem header can also produce a zero block count, causing rd_load_image() to call crd_load() with a NULL decompressor and panic. Track whether the image is compressed separately from its block count. This keeps zero-sized or overflowed legacy image sizes on the normal validation path while preserving the handling of compressed images. Fixes: 30d65dbfe3ad ("bzip2/lzma: config and initramfs support for bzip2/lzma decompression") Cc: stable@vger.kernel.org Reported-by: Vega Assisted-by: LLM Signed-off-by: Zhiling Zou --- init/do_mounts_rd.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 48bfab2fc62f..f113469448e9 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -31,9 +31,9 @@ static int __init crd_load(decompress_fn deco); /* * This routine tries to find a RAM disk image to load, and returns the - * number of blocks to read for a non-compressed image, 0 if the image - * is a compressed image, and -1 if an image with the right magic - * numbers could not be found. + * number of blocks to read for a non-compressed image, and -1 if an + * image with the right magic numbers could not be found. The compressed + * flag is set if the image is compressed. * * We currently check for the following magic numbers: * minix @@ -50,7 +50,7 @@ static int __init crd_load(decompress_fn deco); */ static int __init identify_ramdisk_image(struct file *file, loff_t pos, - decompress_fn *decompressor) + decompress_fn *decompressor, bool *compressed) { const int size = 512; struct minix_super_block *minixsb; @@ -63,6 +63,7 @@ identify_ramdisk_image(struct file *file, loff_t pos, unsigned long n; int start_block = rd_image_start; + *compressed = false; buf = kmalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -87,7 +88,7 @@ identify_ramdisk_image(struct file *file, loff_t pos, printk(KERN_EMERG "RAMDISK: %s decompressor not configured!\n", compress_name); - nblocks = 0; + *compressed = true; goto done; } @@ -185,6 +186,7 @@ int __init rd_load_image(void) char *buf = NULL; unsigned short rotate = 0; decompress_fn decompressor = NULL; + bool compressed; char rotator[4] = { '|' , '/' , '-' , '\\' }; out_file = filp_open("/dev/ram", O_RDWR, 0); @@ -196,15 +198,15 @@ int __init rd_load_image(void) goto noclose_input; in_pos = rd_image_start * BLOCK_SIZE; - nblocks = identify_ramdisk_image(in_file, in_pos, &decompressor); - if (nblocks < 0) - goto done; - - if (nblocks == 0) { + nblocks = identify_ramdisk_image(in_file, in_pos, &decompressor, + &compressed); + if (compressed) { if (crd_load(decompressor) == 0) goto successful_load; goto done; } + if (nblocks < 0) + goto done; /* * NOTE NOTE: nblocks is not actually blocks but -- 2.55.0