Re: [syzbot] [integrity?] [lsm?] KMSAN: uninit-value in ima_add_template_entry

From: Gao Xiang
Date: Sun Mar 03 2024 - 18:54:07 EST




On 2024/3/3 22:54, Tetsuo Handa wrote:
On 2024/02/20 19:40, Roberto Sassu wrote:
On Mon, 2024-02-19 at 22:41 -0800, syzbot wrote:
Hello,

syzbot found the following issue on:

HEAD commit: 4f5e5092fdbf Merge tag 'net-6.8-rc5' of git://git.kernel.o..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=135ba81c180000
kernel config: https://syzkaller.appspot.com/x/.config?x=e3dd779fba027968
dashboard link: https://syzkaller.appspot.com/bug?extid=7bc44a489f0ef0670bd5
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40

I would add the VFS people in CC, in case they have some ideas.

This is an erofs bug. Since the filesystem image in the reproducer
is crafted, decompression generates bogus result and
z_erofs_transform_plain() misbehaves.

Yes, thanks for looking into this. It seems it was introduced by
a new commit 1ca01520148a this cycle, let me find more clues and
make a fix for this.

Thanks,
Gao Xiang


You can obtain a single-threaded reproducer from
https://syzkaller.appspot.com/x/repro.c?x=1256096a180000 with below diff.

----------------------------------------
--- old/1256096a180000.c
+++ new/1256096a180000.c
@@ -676,6 +676,6 @@
syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul, /*prot=*/0ul,
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
/*offset=*/0ul);
- loop();
+ execute_one();
return 0;
}
----------------------------------------

With CONFIG_EROFS_FS_DEBUG=y, the reproducer hits DBG_BUGON().
With debug printk() shown below, you can get output shown below.

----------------------------------------
diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
index d4cee95af14c..f221133a0731 100644
--- a/fs/erofs/decompressor.c
+++ b/fs/erofs/decompressor.c
@@ -323,7 +323,11 @@ static int z_erofs_transform_plain(struct z_erofs_decompress_req *rq,
unsigned int cur = 0, ni = 0, no, pi, po, insz, cnt;
u8 *kin;
- DBG_BUGON(rq->outputsize > rq->inputsize);
+ if (rq->outputsize > rq->inputsize) {
+ pr_err("rq->inputsize=%u rq->outputsize=%u\n", rq->inputsize, rq->outputsize);
+ pr_err("rq->pageofs_in=%u rq->pageofs_out=%u\n", rq->pageofs_in, rq->pageofs_out);
+ pr_err("nrpages_in=%u nrpages_out=%u\n", nrpages_in, nrpages_out);
+ }
if (rq->alg == Z_EROFS_COMPRESSION_INTERLACED) {
cur = bs - (rq->pageofs_out & (bs - 1));
pi = (rq->pageofs_in + rq->inputsize - cur) & ~PAGE_MASK;
@@ -352,7 +356,8 @@ static int z_erofs_transform_plain(struct z_erofs_decompress_req *rq,
do {
no = (rq->pageofs_out + cur + pi) >> PAGE_SHIFT;
po = (rq->pageofs_out + cur + pi) & ~PAGE_MASK;
- DBG_BUGON(no >= nrpages_out);
+ if (no >= nrpages_out)
+ pr_err("no=%u nrpages_out=%u\n", no, nrpages_out);
cnt = min(insz - pi, PAGE_SIZE - po);
if (rq->out[no] == rq->in[ni]) {
memmove(kin + po,
@@ -366,7 +371,8 @@ static int z_erofs_transform_plain(struct z_erofs_decompress_req *rq,
} while (pi < insz);
kunmap_local(kin);
}
- DBG_BUGON(ni > nrpages_in);
+ if (ni > nrpages_in)
+ pr_err("ni=%u nrpages_in=%u\n", ni, nrpages_in);
return 0;
}
----------------------------------------

----------------------------------------
[ 138.991810][ T2983] loop0: detected capacity change from 0 to 16
[ 139.804002][ T2983] erofs: (device loop0): mounted with root inode @ nid 36.
[ 139.810464][ T87] erofs: rq->inputsize=4096 rq->outputsize=8194
[ 139.821540][ T87] erofs: rq->pageofs_in=0 rq->pageofs_out=0
[ 139.824347][ T87] erofs: nrpages_in=1 nrpages_out=3
[ 139.827008][ T87] erofs: ni=3 nrpages_in=1
[ 139.873777][ T2983] =====================================================
[ 139.881268][ T2983] BUG: KMSAN: uninit-value in ima_add_template_entry+0x626/0xa80
----------------------------------------

#syz set subsystems: erofs