[Cluster-devel] kernel BUG in gfs2_fill_super

王海弛 wanghaichi at tju.edu.cn
Tue Aug 23 01:43:21 UTC 2022


Dear Linux maintainers and reviewers:
We would like to report a linux kernel bug, found by a modified version of syzkaller.
May affected file: fs/gfs2/ops_fstype.c
Kernel Version: 8fe31e0995f048d16b378b90926793a0aa4af1e5
Kernel Config: see attach, linux.config
Syzkaller Version: 3666edfeb55080ebe138d77417fa96fe2555d6bb
reproducing program: see attach, reproducing.txt (There are syz-reproducing program, C reproducing program and crash report created by syzkaller, both of which can replay the crash)
Feel free to  email us if any other infomations are needed. Hope the provided materials will help finding and fixing the bug.


The full log crash log are as follows:(also in the attach, crash.report)
-----------------------------------------
loop0: detected capacity change from 0 to 256
detected buffer overflow in strlen
------------[ cut here ]------------
kernel BUG at lib/string.c:1165!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 14888 Comm: syz-executor.0 Not tainted 5.15.0-rc5+ #6
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
RIP: 0010:fortify_panic+0xf/0x11 lib/string.c:1165
Code: 04 48 83 c4 10 48 c7 c7 a0 75 e7 89 5b 5d 41 5c 41 5d 41 5e 41 5f e9 92 33 f1 ff 48 89 fe 48 c7 c7 60 76 e7 89 e8 83 33 f1 ff <0f> 0b e8 2c c4 75 f8 e8 b7 49 bd f8 48 c7 c7 80 9d e7 89 e8 d9 ff
RSP: 0018:ffffc900060cfae8 EFLAGS: 00010282
RAX: 0000000000000022 RBX: ffff88803775a000 RCX: 0000000000000000
RDX: ffffc90002c31000 RSI: ffff88810863c700 RDI: fffff52000c19f4f
RBP: ffffc900060cfcd0 R08: 0000000000000022 R09: 0000000000000000
R10: 0000000000000005 R11: ffffed100c7c57f8 R12: ffff88810d6bc000
R13: 0000000000000040 R14: ffff88810d6bd4ce R15: ffff88810d6bc128
FS:  00007faa5f79e700(0000) GS:ffff888135c00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000000c009e5b000 CR3: 0000000107880000 CR4: 0000000000750ee0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
 strlen include/linux/fortify-string.h:63 [inline]
 strlcpy include/linux/fortify-string.h:88 [inline]
 init_names fs/gfs2/ops_fstype.c:388 [inline]
 gfs2_fill_super+0x135a/0x2980 fs/gfs2/ops_fstype.c:1191
 get_tree_bdev+0x440/0x760 fs/super.c:1293
 gfs2_get_tree+0x4a/0x270 fs/gfs2/ops_fstype.c:1327
 vfs_get_tree+0x89/0x2f0 fs/super.c:1498
 do_new_mount fs/namespace.c:2988 [inline]
 path_mount+0x1228/0x1cb0 fs/namespace.c:3318
 do_mount+0xf3/0x110 fs/namespace.c:3331
 __do_sys_mount fs/namespace.c:3539 [inline]
 __se_sys_mount fs/namespace.c:3516 [inline]
 __x64_sys_mount+0x18f/0x230 fs/namespace.c:3516
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7faa60e2f25e
Code: 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007faa5f79da08 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 0000000020000200 RCX: 00007faa60e2f25e
RDX: 0000000020000000 RSI: 0000000020000100 RDI: 00007faa5f79da60
RBP: 00007faa5f79daa0 R08: 00007faa5f79daa0 R09: 0000000020000000
R10: 0000000000000000 R11: 0000000000000202 R12: 0000000020000000
R13: 0000000020000100 R14: 00007faa5f79da60 R15: 0000000020001440
Modules linked in:
---[ end trace 9967ea4018002a53 ]---
RIP: 0010:fortify_panic+0xf/0x11 lib/string.c:1165
Code: 04 48 83 c4 10 48 c7 c7 a0 75 e7 89 5b 5d 41 5c 41 5d 41 5e 41 5f e9 92 33 f1 ff 48 89 fe 48 c7 c7 60 76 e7 89 e8 83 33 f1 ff <0f> 0b e8 2c c4 75 f8 e8 b7 49 bd f8 48 c7 c7 80 9d e7 89 e8 d9 ff
RSP: 0018:ffffc900060cfae8 EFLAGS: 00010282
RAX: 0000000000000022 RBX: ffff88803775a000 RCX: 0000000000000000
RDX: ffffc90002c31000 RSI: ffff88810863c700 RDI: fffff52000c19f4f
RBP: ffffc900060cfcd0 R08: 0000000000000022 R09: 0000000000000000
R10: 0000000000000005 R11: ffffed100c7c57f8 R12: ffff88810d6bc000
R13: 0000000000000040 R14: ffff88810d6bd4ce R15: ffff88810d6bc128
FS:  00007faa5f79e700(0000) GS:ffff888135c00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000000c00c19e000 CR3: 0000000107880000 CR4: 0000000000750ee0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20220823/1a8bcbb4/attachment.htm>
-------------- next part --------------
Syzkaller hit 'kernel BUG in gfs2_fill_super' bug.

loop0: detected capacity change from 0 to 256
detected buffer overflow in strlen
------------[ cut here ]------------
kernel BUG at lib/string.c:1165!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN
CPU: 0 PID: 6591 Comm: syz-executor421 Not tainted 5.15.0-rc5+ #6
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
RIP: 0010:fortify_panic+0xf/0x11 lib/string.c:1165
Code: 04 48 83 c4 10 48 c7 c7 a0 75 e7 89 5b 5d 41 5c 41 5d 41 5e 41 5f e9 92 33 f1 ff 48 89 fe 48 c7 c7 60 76 e7 89 e8 83 33 f1 ff <0f> 0b e8 2c c4 75 f8 e8 b7 49 bd f8 48 c7 c7 80 9d e7 89 e8 d9 ff
RSP: 0018:ffffc900017efae8 EFLAGS: 00010282
RAX: 0000000000000022 RBX: ffff8880202dc000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff888018d74700 RDI: fffff520002fdf4f
RBP: ffffc900017efcd0 R08: 0000000000000022 R09: 0000000000000000
R10: 0000000000000005 R11: ffffed100c7c3f53 R12: ffff8880129e8000
R13: 0000000000000040 R14: ffff8880129e94ce R15: ffff8880129e8128
FS:  00005555563db880(0000) GS:ffff888063e00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffe421db000 CR3: 0000000014bdf000 CR4: 0000000000750ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
 strlen include/linux/fortify-string.h:63 [inline]
 strlcpy include/linux/fortify-string.h:88 [inline]
 init_names fs/gfs2/ops_fstype.c:388 [inline]
 gfs2_fill_super+0x135a/0x2980 fs/gfs2/ops_fstype.c:1191
 get_tree_bdev+0x440/0x760 fs/super.c:1293
 gfs2_get_tree+0x4a/0x270 fs/gfs2/ops_fstype.c:1327
 vfs_get_tree+0x89/0x2f0 fs/super.c:1498
 do_new_mount fs/namespace.c:2988 [inline]
 path_mount+0x1228/0x1cb0 fs/namespace.c:3318
 do_mount+0xf3/0x110 fs/namespace.c:3331
 __do_sys_mount fs/namespace.c:3539 [inline]
 __se_sys_mount fs/namespace.c:3516 [inline]
 __x64_sys_mount+0x18f/0x230 fs/namespace.c:3516
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7f7a7c909efe
Code: 83 c4 08 5b 5d c3 66 0f 1f 44 00 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffe421da448 EFLAGS: 00000282 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 0000000020000218 RCX: 00007f7a7c909efe
RDX: 0000000020000000 RSI: 0000000020000100 RDI: 00007ffe421da460
RBP: 00007ffe421da460 R08: 00007ffe421da4a0 R09: 00000000000001e0
R10: 0000000000000000 R11: 0000000000000282 R12: 0000000000000004
R13: 0000000000000003 R14: 0000000000000000 R15: 00007ffe421da4a0
Modules linked in:
---[ end trace 1e0d10455caefdf4 ]---
RIP: 0010:fortify_panic+0xf/0x11 lib/string.c:1165
Code: 04 48 83 c4 10 48 c7 c7 a0 75 e7 89 5b 5d 41 5c 41 5d 41 5e 41 5f e9 92 33 f1 ff 48 89 fe 48 c7 c7 60 76 e7 89 e8 83 33 f1 ff <0f> 0b e8 2c c4 75 f8 e8 b7 49 bd f8 48 c7 c7 80 9d e7 89 e8 d9 ff
RSP: 0018:ffffc900017efae8 EFLAGS: 00010282
RAX: 0000000000000022 RBX: ffff8880202dc000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff888018d74700 RDI: fffff520002fdf4f
RBP: ffffc900017efcd0 R08: 0000000000000022 R09: 0000000000000000
R10: 0000000000000005 R11: ffffed100c7c3f53 R12: ffff8880129e8000
R13: 0000000000000040 R14: ffff8880129e94ce R15: ffff8880129e8128
FS:  00005555563db880(0000) GS:ffff888063e00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055933213110f CR3: 0000000014bdf000 CR4: 0000000000750ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554


Syzkaller reproducer:
# {Threaded:false Repeat:false RepeatTimes:0 Procs:1 Slowdown:1 Sandbox: Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false VhciInjection:false Wifi:false IEEE802154:false Sysctl:false UseTmpDir:false HandleSegv:false Repro:false Trace:false LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}}
syz_mount_image$gfs2(&(0x7f0000000000), &(0x7f0000000100)='./file0\x00', 0x0, 0x1, &(0x7f0000000200)=[{&(0x7f0000000240)="011619700000000100000000000000000000006400000000000007090000076c00000000000010000000000c000000000000000000000002000000000000081b0000000000000000000000000000000c00000000000009276c6f636b5f6e6f6c6f636b7c62e809e17e4423de1ddfda025c078e7b8436641c78fb63a5b59eed9c314ea93ca7226d4c894dfad070f2a8b44918ff712108955c081b2b60e9a47c5b5ba48b1696bc4efe803c201aa054392ade6340d17018ecc1bd622247205abd7cd84a55bddacc5180d400948bcb84d7bfc4f8eeddf322fc43155d759c9a42de2b7579e85ac5a6a7e091a1d6a4dcde084cd28990a08636a467955d11b30000000000000000", 0x104, 0x10000}], 0x0, &(0x7f0000001440)={[{@meta}]})


C reproducer:
// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE 

#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#include <linux/loop.h>

#ifndef __NR_memfd_create
#define __NR_memfd_create 319
#endif

static unsigned long long procid;

struct fs_image_segment {
	void* data;
	uintptr_t size;
	uintptr_t offset;
};

#define IMAGE_MAX_SEGMENTS 4096
#define IMAGE_MAX_SIZE (129 << 20)

static unsigned long fs_image_segment_check(unsigned long size, unsigned long nsegs, struct fs_image_segment* segs)
{
	if (nsegs > IMAGE_MAX_SEGMENTS)
		nsegs = IMAGE_MAX_SEGMENTS;
	for (size_t i = 0; i < nsegs; i++) {
		if (segs[i].size > IMAGE_MAX_SIZE)
			segs[i].size = IMAGE_MAX_SIZE;
		segs[i].offset %= IMAGE_MAX_SIZE;
		if (segs[i].offset > IMAGE_MAX_SIZE - segs[i].size)
			segs[i].offset = IMAGE_MAX_SIZE - segs[i].size;
		if (size < segs[i].offset + segs[i].offset)
			size = segs[i].offset + segs[i].offset;
	}
	if (size > IMAGE_MAX_SIZE)
		size = IMAGE_MAX_SIZE;
	return size;
}
static int setup_loop_device(long unsigned size, long unsigned nsegs, struct fs_image_segment* segs, const char* loopname, int* memfd_p, int* loopfd_p)
{
	int err = 0, loopfd = -1;
	size = fs_image_segment_check(size, nsegs, segs);
	int memfd = syscall(__NR_memfd_create, "syzkaller", 0);
	if (memfd == -1) {
		err = errno;
		goto error;
	}
	if (ftruncate(memfd, size)) {
		err = errno;
		goto error_close_memfd;
	}
	for (size_t i = 0; i < nsegs; i++) {
		if (pwrite(memfd, segs[i].data, segs[i].size, segs[i].offset) < 0) {
		}
	}
	loopfd = open(loopname, O_RDWR);
	if (loopfd == -1) {
		err = errno;
		goto error_close_memfd;
	}
	if (ioctl(loopfd, LOOP_SET_FD, memfd)) {
		if (errno != EBUSY) {
			err = errno;
			goto error_close_loop;
		}
		ioctl(loopfd, LOOP_CLR_FD, 0);
		usleep(1000);
		if (ioctl(loopfd, LOOP_SET_FD, memfd)) {
			err = errno;
			goto error_close_loop;
		}
	}
	*memfd_p = memfd;
	*loopfd_p = loopfd;
	return 0;

error_close_loop:
	close(loopfd);
error_close_memfd:
	close(memfd);
error:
	errno = err;
	return -1;
}

static long syz_mount_image(volatile long fsarg, volatile long dir, volatile unsigned long size, volatile unsigned long nsegs, volatile long segments, volatile long flags, volatile long optsarg)
{
	struct fs_image_segment* segs = (struct fs_image_segment*)segments;
	int res = -1, err = 0, loopfd = -1, memfd = -1, need_loop_device = !!segs;
	char* mount_opts = (char*)optsarg;
	char* target = (char*)dir;
	char* fs = (char*)fsarg;
	char* source = NULL;
	char loopname[64];
	if (need_loop_device) {
		memset(loopname, 0, sizeof(loopname));
		snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid);
		if (setup_loop_device(size, nsegs, segs, loopname, &memfd, &loopfd) == -1)
			return -1;
		source = loopname;
	}
	mkdir(target, 0777);
	char opts[256];
	memset(opts, 0, sizeof(opts));
	if (strlen(mount_opts) > (sizeof(opts) - 32)) {
	}
	strncpy(opts, mount_opts, sizeof(opts) - 32);
	if (strcmp(fs, "iso9660") == 0) {
		flags |= MS_RDONLY;
	} else if (strncmp(fs, "ext", 3) == 0) {
		if (strstr(opts, "errors=panic") || strstr(opts, "errors=remount-ro") == 0)
			strcat(opts, ",errors=continue");
	} else if (strcmp(fs, "xfs") == 0) {
		strcat(opts, ",nouuid");
	}
	res = mount(source, target, fs, flags, opts);
	if (res == -1) {
		err = errno;
		goto error_clear_loop;
	}
	res = open(target, O_RDONLY | O_DIRECTORY);
	if (res == -1) {
		err = errno;
	}

error_clear_loop:
	if (need_loop_device) {
		ioctl(loopfd, LOOP_CLR_FD, 0);
		close(loopfd);
		close(memfd);
	}
	errno = err;
	return res;
}

int main(void)
{
		syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
	syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
	syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);

memcpy((void*)0x20000000, "gfs2\000", 5);
memcpy((void*)0x20000100, "./file0\000", 8);
*(uint64_t*)0x20000200 = 0x20000240;
memcpy((void*)0x20000240, "\x01\x16\x19\x70\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x00\x00\x00\x00\x00\x00\x07\x09\x00\x00\x07\x6c\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x08\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x09\x27\x6c\x6f\x63\x6b\x5f\x6e\x6f\x6c\x6f\x63\x6b\x7c\x62\xe8\x09\xe1\x7e\x44\x23\xde\x1d\xdf\xda\x02\x5c\x07\x8e\x7b\x84\x36\x64\x1c\x78\xfb\x63\xa5\xb5\x9e\xed\x9c\x31\x4e\xa9\x3c\xa7\x22\x6d\x4c\x89\x4d\xfa\xd0\x70\xf2\xa8\xb4\x49\x18\xff\x71\x21\x08\x95\x5c\x08\x1b\x2b\x60\xe9\xa4\x7c\x5b\x5b\xa4\x8b\x16\x96\xbc\x4e\xfe\x80\x3c\x20\x1a\xa0\x54\x39\x2a\xde\x63\x40\xd1\x70\x18\xec\xc1\xbd\x62\x22\x47\x20\x5a\xbd\x7c\xd8\x4a\x55\xbd\xda\xcc\x51\x80\xd4\x00\x94\x8b\xcb\x84\xd7\xbf\xc4\xf8\xee\xdd\xf3\x22\xfc\x43\x15\x5d\x75\x9c\x9a\x42\xde\x2b\x75\x79\xe8\x5a\xc5\xa6\xa7\xe0\x91\xa1\xd6\xa4\xdc\xde\x08\x4c\xd2\x89\x90\xa0\x86\x36\xa4\x67\x95\x5d\x11\xb3\x00\x00\x00\x00\x00\x00\x00\x00", 260);
*(uint64_t*)0x20000208 = 0x104;
*(uint64_t*)0x20000210 = 0x10000;
memcpy((void*)0x20001440, "meta", 4);
*(uint8_t*)0x20001444 = 0x2c;
*(uint8_t*)0x20001445 = 0;
syz_mount_image(0x20000000, 0x20000100, 0, 1, 0x20000200, 0, 0x20001440);
	return 0;
}

-------------- next part --------------
A non-text attachment was scrubbed...
Name: crash.report
Type: application/octet-stream
Size: 3730 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20220823/1a8bcbb4/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: linux.config
Type: application/octet-stream
Size: 226314 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20220823/1a8bcbb4/attachment-0001.obj>


More information about the Cluster-devel mailing list