From 3432e57493c278c1cb48abc2d69c6c055a19723e Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Thu, 27 Oct 2022 20:49:06 +0800 Subject: [PATCH] jffs2: Fix list_del corruption if compressors initialized failed There is a list_del corruption when remove the jffs2 module: list_del corruption, ffffffffa0623e60->next is NULL WARNING: CPU: 6 PID: 6332 at lib/list_debug.c:49 __list_del_entry_valid+0x98/0x130 Modules linked in: jffs2(-) ] CPU: 6 PID: 6332 Comm: rmmod Tainted: G W 6.1.0-rc2+ #5 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014 RIP: 0010:__list_del_entry_valid+0x98/0x130 ... Call Trace: jffs2_unregister_compressor+0x3e/0xe0 [jffs2] jffs2_zlib_exit+0x11/0x30 [jffs2] jffs2_compressors_exit+0x1e/0x30 [jffs2] exit_jffs2_fs+0x16/0x44f [jffs2] __do_sys_delete_module.constprop.0+0x244/0x370 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 If one of the compressor initialize failed, the module always insert success since jffs2_compressors_init() always return success, then something bad may happen during remove the module. For this scenario, let's insmod failed. Signed-off-by: Zhang Xiaoxu Signed-off-by: Richard Weinberger --- fs/jffs2/compr.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index afe74c65f1e4..764f19dec3f0 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c @@ -364,12 +364,24 @@ void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) int __init jffs2_compressors_init(void) { + int ret = 0; /* Registering compressors */ - jffs2_zlib_init(); - jffs2_rtime_init(); - jffs2_rubinmips_init(); - jffs2_dynrubin_init(); - jffs2_lzo_init(); + ret = jffs2_zlib_init(); + if (ret) + goto exit; + ret = jffs2_rtime_init(); + if (ret) + goto exit_zlib; + ret = jffs2_rubinmips_init(); + if (ret) + goto exit_rtime; + ret = jffs2_dynrubin_init(); + if (ret) + goto exit_runinmips; + ret = jffs2_lzo_init(); + if (ret) + goto exit_dynrubin; + /* Setting default compression mode */ #ifdef CONFIG_JFFS2_CMODE_NONE @@ -389,6 +401,17 @@ int __init jffs2_compressors_init(void) #endif #endif return 0; + +exit_dynrubin: + jffs2_dynrubin_exit(); +exit_runinmips: + jffs2_rubinmips_exit(); +exit_rtime: + jffs2_rtime_exit(); +exit_zlib: + jffs2_zlib_exit(); +exit: + return ret; } int jffs2_compressors_exit(void)