2023-11-22 09:53:25

by syzbot

[permalink] [raw]
Subject: [syzbot] [kernel?] general protection fault in joydev_connect

Hello,

syzbot found the following issue on:

HEAD commit: 0468be89b3fa Merge tag 'iommu-updates-v6.6' of git://git.k..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=15d71367a80000
kernel config: https://syzkaller.appspot.com/x/.config?x=39744401c57166fc
dashboard link: https://syzkaller.appspot.com/bug?extid=786b124fe4ce4dc99357
compiler: gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/7bc7510fe41f/non_bootable_disk-0468be89.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/7feba36779de/vmlinux-0468be89.xz
kernel image: https://storage.googleapis.com/syzbot-assets/b1cdc0506491/bzImage-0468be89.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: [email protected]

RBP: 00007fa0905fe120 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000002
R13: 000000000000000b R14: 00007fa091b9bf80 R15: 00007ffd2d08f908
</TASK>
general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 3 PID: 7070 Comm: syz-executor.3 Not tainted 6.5.0-syzkaller-10885-g0468be89b3fa #0
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
RIP: 0010:strchr+0x1b/0xb0 lib/string.c:329
Code: 48 ad f7 48 8b 74 24 08 48 8b 14 24 eb 89 90 f3 0f 1e fa 48 b8 00 00 00 00 00 fc ff df 48 89 fa 55 48 c1 ea 03 53 48 83 ec 10 <0f> b6 04 02 48 89 fa 83 e2 07 38 d0 7f 04 84 c0 75 51 0f b6 07 89
RSP: 0018:ffffc90006d479e0 EFLAGS: 00010282
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffc9000c2ca000
RDX: 0000000000000000 RSI: 0000000000000025 RDI: 0000000000000000
RBP: ffffc90006d47a70 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: ffffc90006d47a70
R13: 0000000000000cc0 R14: ffff888029f072f0 R15: 0000000000000001
FS: 00007fa0905fe6c0(0000) GS:ffff88806b900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00005595cf80f000 CR3: 000000010b7d5000 CR4: 0000000000350ee0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
kvasprintf_const+0x25/0x190 lib/kasprintf.c:45
kobject_set_name_vargs+0x5a/0x130 lib/kobject.c:272
kobject_add_varg lib/kobject.c:366 [inline]
kobject_add+0x12a/0x240 lib/kobject.c:424
device_add+0x290/0x1ac0 drivers/base/core.c:3560
cdev_device_add+0x12b/0x270 fs/char_dev.c:556
joydev_connect+0xbdc/0x1030 drivers/input/joydev.c:1001
input_attach_handler.isra.0+0x17c/0x250 drivers/input/input.c:1064
input_register_device+0xb1e/0x1130 drivers/input/input.c:2396
uinput_create_device drivers/input/misc/uinput.c:365 [inline]
uinput_ioctl_handler.isra.0+0x1308/0x1d70 drivers/input/misc/uinput.c:904
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl fs/ioctl.c:857 [inline]
__x64_sys_ioctl+0x18f/0x210 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fa091a7cae9
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fa0905fe0c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007fa091b9bf80 RCX: 00007fa091a7cae9
RDX: 0000000000000000 RSI: 0000000000005501 RDI: 0000000000000003
RBP: 00007fa0905fe120 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000002
R13: 000000000000000b R14: 00007fa091b9bf80 R15: 00007ffd2d08f908
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:strchr+0x1b/0xb0 lib/string.c:329
Code: 48 ad f7 48 8b 74 24 08 48 8b 14 24 eb 89 90 f3 0f 1e fa 48 b8 00 00 00 00 00 fc ff df 48 89 fa 55 48 c1 ea 03 53 48 83 ec 10 <0f> b6 04 02 48 89 fa 83 e2 07 38 d0 7f 04 84 c0 75 51 0f b6 07 89
RSP: 0018:ffffc90006d479e0 EFLAGS: 00010282
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffc9000c2ca000
RDX: 0000000000000000 RSI: 0000000000000025 RDI: 0000000000000000
RBP: ffffc90006d47a70 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: ffffc90006d47a70
R13: 0000000000000cc0 R14: ffff888029f072f0 R15: 0000000000000001
FS: 00007fa0905fe6c0(0000) GS:ffff88806b900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00005595cf80f000 CR3: 000000010b7d5000 CR4: 0000000000350ee0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
----------------
Code disassembly (best guess):
0: 48 ad lods %ds:(%rsi),%rax
2: f7 48 8b 74 24 08 48 testl $0x48082474,-0x75(%rax)
9: 8b 14 24 mov (%rsp),%edx
c: eb 89 jmp 0xffffff97
e: 90 nop
f: f3 0f 1e fa endbr64
13: 48 b8 00 00 00 00 00 movabs $0xdffffc0000000000,%rax
1a: fc ff df
1d: 48 89 fa mov %rdi,%rdx
20: 55 push %rbp
21: 48 c1 ea 03 shr $0x3,%rdx
25: 53 push %rbx
26: 48 83 ec 10 sub $0x10,%rsp
* 2a: 0f b6 04 02 movzbl (%rdx,%rax,1),%eax <-- trapping instruction
2e: 48 89 fa mov %rdi,%rdx
31: 83 e2 07 and $0x7,%edx
34: 38 d0 cmp %dl,%al
36: 7f 04 jg 0x3c
38: 84 c0 test %al,%al
3a: 75 51 jne 0x8d
3c: 0f b6 07 movzbl (%rdi),%eax
3f: 89 .byte 0x89


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at [email protected].

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup


2023-11-22 11:57:38

by lee bruce

[permalink] [raw]
Subject: Re: [syzbot] [kernel?] general protection fault in joydev_connect

Hi. I have reproduced this bug with repro.txt and repro.c below:

repro.txt
r0 = openat$uinput(0xffffffffffffff9c, &(0x7f0000000500), 0x802, 0x0)
ioctl$UI_DEV_SETUP(r0, 0x405c5503, &(0x7f0000000080)={{0x0, 0xffff,
0x3}, 'syz0\x00'})
ioctl$UI_DEV_CREATE(r0, 0x5501) (fail_nth: 51)

repro.c
#define _GNU_SOURCE

#include <dirent.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

static void sleep_ms(uint64_t ms)
{
usleep(ms * 1000);
}

static uint64_t current_time_ms(void)
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts))
exit(1);
return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
}

static bool write_file(const char* file, const char* what, ...)
{
char buf[1024];
va_list args;
va_start(args, what);
vsnprintf(buf, sizeof(buf), what, args);
va_end(args);
buf[sizeof(buf) - 1] = 0;
int len = strlen(buf);
int fd = open(file, O_WRONLY | O_CLOEXEC);
if (fd == -1)
return false;
if (write(fd, buf, len) != len) {
int err = errno;
close(fd);
errno = err;
return false;
}
close(fd);
return true;
}

static int inject_fault(int nth)
{
int fd;
fd = open("/proc/thread-self/fail-nth", O_RDWR);
if (fd == -1)
exit(1);
char buf[16];
sprintf(buf, "%d", nth);
if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf))
exit(1);
return fd;
}

static void kill_and_wait(int pid, int* status)
{
kill(-pid, SIGKILL);
kill(pid, SIGKILL);
for (int i = 0; i < 100; i++) {
if (waitpid(-1, status, WNOHANG | __WALL) == pid)
return;
usleep(1000);
}
DIR* dir = opendir("/sys/fs/fuse/connections");
if (dir) {
for (;;) {
struct dirent* ent = readdir(dir);
if (!ent)
break;
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
continue;
char abort[300];
snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
ent->d_name);
int fd = open(abort, O_WRONLY);
if (fd == -1) {
continue;
}
if (write(fd, abort, 1) < 0) {
}
close(fd);
}
closedir(dir);
} else {
}
while (waitpid(-1, status, __WALL) != pid) {
}
}

static void setup_test()
{
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
setpgrp();
write_file("/proc/self/oom_score_adj", "1000");
}

static void setup_fault()
{
static struct {
const char* file;
const char* val;
bool fatal;
} files[] = {
{"/sys/kernel/debug/failslab/ignore-gfp-wait", "N", true},
{"/sys/kernel/debug/fail_futex/ignore-private", "N", false},
{"/sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem", "N", false},
{"/sys/kernel/debug/fail_page_alloc/ignore-gfp-wait", "N", false},
{"/sys/kernel/debug/fail_page_alloc/min-order", "0", false},
};
unsigned i;
for (i = 0; i < sizeof(files) / sizeof(files[0]); i++) {
if (!write_file(files[i].file, files[i].val)) {
if (files[i].fatal)
exit(1);
}
}
}

static void execute_one(void);

#define WAIT_FLAGS __WALL

static void loop(void)
{
int iter = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
exit(1);
if (pid == 0) {
setup_test();
execute_one();
exit(0);
}
int status = 0;
uint64_t start = current_time_ms();
for (;;) {
if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
break;
sleep_ms(1);
if (current_time_ms() - start < 5000)
continue;
kill_and_wait(pid, &status);
break;
}
}
}

uint64_t r[1] = {0xffffffffffffffff};

void execute_one(void)
{
intptr_t res = 0;
memcpy((void*)0x20000500, "/dev/uinput\000", 12);
res = syscall(__NR_openat, /*fd=*/0xffffffffffffff9cul,
/*file=*/0x20000500ul, /*flags=*/0x802ul, /*mode=*/0ul);
if (res != -1)
r[0] = res;
*(uint16_t*)0x20000080 = 0;
*(uint16_t*)0x20000082 = -1;
*(uint16_t*)0x20000084 = 3;
*(uint16_t*)0x20000086 = 0;
memcpy((void*)0x20000088,
"syz0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
80);
*(uint32_t*)0x200000d8 = 0;
syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x405c5503, /*arg=*/0x20000080ul);
inject_fault(51);
syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x5501, 0);

}
int main(void)
{
syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000ul,
/*prot=*/0ul, /*flags=*/0x32ul, /*fd=*/-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul,
/*prot=*/7ul, /*flags=*/0x32ul, /*fd=*/-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul,
/*prot=*/0ul, /*flags=*/0x32ul, /*fd=*/-1, /*offset=*/0ul);
setup_fault();
loop();
return 0;
}

2023-11-23 08:55:28

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [syzbot] [kernel?] general protection fault in joydev_connect

On Wed, Nov 22, 2023 at 07:55:50PM +0800, xingwei lee wrote:
> Hi. I have reproduced this bug with repro.txt and repro.c below:
>
> repro.txt
> r0 = openat$uinput(0xffffffffffffff9c, &(0x7f0000000500), 0x802, 0x0)
> ioctl$UI_DEV_SETUP(r0, 0x405c5503, &(0x7f0000000080)={{0x0, 0xffff,
> 0x3}, 'syz0\x00'})
> ioctl$UI_DEV_CREATE(r0, 0x5501) (fail_nth: 51)

You are using fault injection, which, by it's very name, causes faults :)

Can you reproduce it without causing faults in the kernel? And if so,
can you create a patch to fix this?

thanks,

greg k-h

2023-11-23 09:32:55

by Aleksandr Nogikh

[permalink] [raw]
Subject: Re: [syzbot] [kernel?] general protection fault in joydev_connect

On Thu, Nov 23, 2023 at 9:55 AM [email protected]
<[email protected]> wrote:
>
> On Wed, Nov 22, 2023 at 07:55:50PM +0800, xingwei lee wrote:
> > Hi. I have reproduced this bug with repro.txt and repro.c below:
> >
> > repro.txt
> > r0 = openat$uinput(0xffffffffffffff9c, &(0x7f0000000500), 0x802, 0x0)
> > ioctl$UI_DEV_SETUP(r0, 0x405c5503, &(0x7f0000000080)={{0x0, 0xffff,
> > 0x3}, 'syz0\x00'})
> > ioctl$UI_DEV_CREATE(r0, 0x5501) (fail_nth: 51)
>
> You are using fault injection, which, by it's very name, causes faults :)

But those injected failures (that do not break the kernel, but just
emulate an error returned from a function that should be expected to
sometimes return an error) still should not lead to general protection
fault panics, shouldn't they?

--
Aleksandr

>
> Can you reproduce it without causing faults in the kernel? And if so,
> can you create a patch to fix this?
>
> thanks,
>
> greg k-h
>

2023-11-23 09:44:24

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [syzbot] [kernel?] general protection fault in joydev_connect

On Thu, Nov 23, 2023 at 10:32:26AM +0100, Aleksandr Nogikh wrote:
> On Thu, Nov 23, 2023 at 9:55 AM [email protected]
> <[email protected]> wrote:
> >
> > On Wed, Nov 22, 2023 at 07:55:50PM +0800, xingwei lee wrote:
> > > Hi. I have reproduced this bug with repro.txt and repro.c below:
> > >
> > > repro.txt
> > > r0 = openat$uinput(0xffffffffffffff9c, &(0x7f0000000500), 0x802, 0x0)
> > > ioctl$UI_DEV_SETUP(r0, 0x405c5503, &(0x7f0000000080)={{0x0, 0xffff,
> > > 0x3}, 'syz0\x00'})
> > > ioctl$UI_DEV_CREATE(r0, 0x5501) (fail_nth: 51)
> >
> > You are using fault injection, which, by it's very name, causes faults :)
>
> But those injected failures (that do not break the kernel, but just
> emulate an error returned from a function that should be expected to
> sometimes return an error) still should not lead to general protection
> fault panics, shouldn't they?

It all depends on what exactly the fault is happening for. Some
allocations in the kernel just "will not fail ever" so when you add
fault injection testing, you are doing things that really can not ever
happen.

So the proof is first on the reporter, prove that this type of fault
_can_ actually happen, and then, make a fix to properly handle it.
Don't expect us to make a fix for something that can not actually occur,
as that would be pointless (hint, we have been down this path before, it
doesn't work...)

thanks,

greg k-h

2023-11-23 12:43:10

by Aleksandr Nogikh

[permalink] [raw]
Subject: Re: [syzbot] [kernel?] general protection fault in joydev_connect

On Thu, Nov 23, 2023 at 10:41 AM [email protected]
<[email protected]> wrote:
>
> On Thu, Nov 23, 2023 at 10:32:26AM +0100, Aleksandr Nogikh wrote:
> > On Thu, Nov 23, 2023 at 9:55 AM [email protected]
> > <[email protected]> wrote:
> > >
> > > On Wed, Nov 22, 2023 at 07:55:50PM +0800, xingwei lee wrote:
> > > > Hi. I have reproduced this bug with repro.txt and repro.c below:
> > > >
> > > > repro.txt
> > > > r0 = openat$uinput(0xffffffffffffff9c, &(0x7f0000000500), 0x802, 0x0)
> > > > ioctl$UI_DEV_SETUP(r0, 0x405c5503, &(0x7f0000000080)={{0x0, 0xffff,
> > > > 0x3}, 'syz0\x00'})
> > > > ioctl$UI_DEV_CREATE(r0, 0x5501) (fail_nth: 51)
> > >
> > > You are using fault injection, which, by it's very name, causes faults :)
> >
> > But those injected failures (that do not break the kernel, but just
> > emulate an error returned from a function that should be expected to
> > sometimes return an error) still should not lead to general protection
> > fault panics, shouldn't they?
>
> It all depends on what exactly the fault is happening for. Some
> allocations in the kernel just "will not fail ever" so when you add
> fault injection testing, you are doing things that really can not ever
> happen.

Just in case - are you aware of any specific examples where fault
injection injects failures that should never ever happen? All
automatic kernel testing would benefit by making it not do this then.

From what I see in the code, fault injection already takes care of
avoiding such problems:
https://elixir.bootlin.com/linux/latest/source/mm/failslab.c#L25
https://elixir.bootlin.com/linux/latest/source/mm/fail_page_alloc.c#L30

>
> So the proof is first on the reporter, prove that this type of fault
> _can_ actually happen, and then, make a fix to properly handle it.
> Don't expect us to make a fix for something that can not actually occur,
> as that would be pointless (hint, we have been down this path before, it
> doesn't work...)
>
> thanks,
>
> greg k-h

2023-11-23 13:02:04

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [syzbot] [kernel?] general protection fault in joydev_connect

On Thu, Nov 23, 2023 at 01:42:26PM +0100, Aleksandr Nogikh wrote:
> On Thu, Nov 23, 2023 at 10:41 AM [email protected]
> <[email protected]> wrote:
> >
> > On Thu, Nov 23, 2023 at 10:32:26AM +0100, Aleksandr Nogikh wrote:
> > > On Thu, Nov 23, 2023 at 9:55 AM [email protected]
> > > <[email protected]> wrote:
> > > >
> > > > On Wed, Nov 22, 2023 at 07:55:50PM +0800, xingwei lee wrote:
> > > > > Hi. I have reproduced this bug with repro.txt and repro.c below:
> > > > >
> > > > > repro.txt
> > > > > r0 = openat$uinput(0xffffffffffffff9c, &(0x7f0000000500), 0x802, 0x0)
> > > > > ioctl$UI_DEV_SETUP(r0, 0x405c5503, &(0x7f0000000080)={{0x0, 0xffff,
> > > > > 0x3}, 'syz0\x00'})
> > > > > ioctl$UI_DEV_CREATE(r0, 0x5501) (fail_nth: 51)
> > > >
> > > > You are using fault injection, which, by it's very name, causes faults :)
> > >
> > > But those injected failures (that do not break the kernel, but just
> > > emulate an error returned from a function that should be expected to
> > > sometimes return an error) still should not lead to general protection
> > > fault panics, shouldn't they?
> >
> > It all depends on what exactly the fault is happening for. Some
> > allocations in the kernel just "will not fail ever" so when you add
> > fault injection testing, you are doing things that really can not ever
> > happen.
>
> Just in case - are you aware of any specific examples where fault
> injection injects failures that should never ever happen?

Yes, many places, it's come up in the past, but I can't find the
specifics as some of us get 1000+ emails a day :)

Search the archives?

> All
> automatic kernel testing would benefit by making it not do this then.

I agree, so take a look at the allocation paths and see the ones that
just can not fail and then do not cause a fault on them? As an example,
any "small" allocation that can be done in a way that can sleep (i.e.
GFP_KERNEL) will never fail, right? So don't add failures there.

Or any allocation at boot time, that's never going to fail as there's no
memory pressure yet. Look at the system and make smart faults, don't
just blindly go poking at things and expect it all to work.

good luck!

greg k-h