Created
August 24, 2024 20:50
INFO: task hung in gsm_cleanup_mux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Syzkaller hit 'INFO: task hung in gsm_cleanup_mux' bug. | |
INFO: task syz-executor414:8030 blocked for more than 143 seconds. | |
Not tainted 6.10.0 #13 | |
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. | |
task:syz-executor414 state:D stack:24904 pid:8030 tgid:8030 ppid:8029 flags:0x00004006 | |
Call Trace: | |
<TASK> | |
context_switch kernel/sched/core.c:5407 [inline] | |
__schedule+0xf4a/0x15e0 kernel/sched/core.c:6748 | |
__schedule_loop kernel/sched/core.c:6825 [inline] | |
schedule+0x143/0x310 kernel/sched/core.c:6840 | |
gsm_cleanup_mux+0x344/0x930 drivers/tty/n_gsm.c:3136 | |
gsm_config drivers/tty/n_gsm.c:3408 [inline] | |
gsmld_ioctl+0x13c4/0x2540 drivers/tty/n_gsm.c:3839 | |
tty_ioctl+0x98f/0xdb0 drivers/tty/tty_io.c:2812 | |
vfs_ioctl fs/ioctl.c:51 [inline] | |
__do_sys_ioctl fs/ioctl.c:907 [inline] | |
__se_sys_ioctl+0xfe/0x170 fs/ioctl.c:893 | |
do_syscall_x64 arch/x86/entry/common.c:52 [inline] | |
do_syscall_64+0x7e/0x150 arch/x86/entry/common.c:83 | |
entry_SYSCALL_64_after_hwframe+0x67/0x6f | |
RIP: 0033:0x7f2c75cb580d | |
RSP: 002b:00007ffd6f9a67e8 EFLAGS: 00000217 ORIG_RAX: 0000000000000010 | |
RAX: ffffffffffffffda RBX: 000000002000012c RCX: 00007f2c75cb580d | |
RDX: 0000000020000100 RSI: 00000000404c4701 RDI: 0000000000000003 | |
RBP: 0000000000000000 R08: 0000000008000000 R09: 0000000008000000 | |
R10: 00000000ffffffff R11: 0000000000000217 R12: 0000000000000001 | |
R13: 431bde82d7b634db R14: 00007f2c75d324f0 R15: 0000000000000001 | |
</TASK> | |
Showing all locks held in the system: | |
1 lock held by khungtaskd/25: | |
#0: ffffffff8db32fe0 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire include/linux/rcupdate.h:329 [inline] | |
#0: ffffffff8db32fe0 (rcu_read_lock){....}-{1:2}, at: rcu_read_lock include/linux/rcupdate.h:781 [inline] | |
#0: ffffffff8db32fe0 (rcu_read_lock){....}-{1:2}, at: debug_show_all_locks+0x54/0x2d0 kernel/locking/lockdep.c:6614 | |
1 lock held by in:imklog/7651: | |
#0: ffff888016acd9c8 (&f->f_pos_lock){+.+.}-{3:3}, at: __fdget_pos+0x246/0x310 fs/file.c:1191 | |
2 locks held by syz-executor414/8030: | |
#0: ffff88802fc530a0 (&tty->ldisc_sem){++++}-{0:0}, at: tty_ldisc_ref_wait+0x21/0x70 drivers/tty/tty_ldisc.c:243 | |
#1: ffff88801473f0b0 (&gsm->mutex){+.+.}-{3:3}, at: gsm_cleanup_mux+0xb7/0x930 drivers/tty/n_gsm.c:3130 | |
============================================= | |
NMI backtrace for cpu 0 | |
CPU: 0 PID: 25 Comm: khungtaskd Not tainted 6.10.0 #13 | |
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 | |
Call Trace: | |
<TASK> | |
__dump_stack lib/dump_stack.c:88 [inline] | |
dump_stack_lvl+0x23d/0x360 lib/dump_stack.c:114 | |
nmi_cpu_backtrace+0x451/0x480 lib/nmi_backtrace.c:113 | |
nmi_trigger_cpumask_backtrace+0x181/0x2d0 lib/nmi_backtrace.c:62 | |
trigger_all_cpu_backtrace include/linux/nmi.h:162 [inline] | |
check_hung_uninterruptible_tasks kernel/hung_task.c:223 [inline] | |
watchdog+0xdbd/0xe00 kernel/hung_task.c:379 | |
kthread+0x2eb/0x380 kernel/kthread.c:389 | |
ret_from_fork+0x49/0x80 arch/x86/kernel/process.c:147 | |
ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244 | |
</TASK> | |
Syzkaller reproducer: | |
# {Threaded:false Repeat:true RepeatTimes:0 Procs:1 Slowdown:1 Sandbox: SandboxArg:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false NicVF:false USB:false VhciInjection:false Wifi:false IEEE802154:false Sysctl:false Swap:false UseTmpDir:false HandleSegv:false Trace:false LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}} | |
r0 = openat$ptmx(0xffffffffffffff9c, &(0x7f0000000000), 0x400, 0x0) | |
ioctl$TIOCSETD(r0, 0x5423, &(0x7f0000000040)=0x15) | |
ioctl$syz_spec_18446744072138818634_15521(r0, 0x404c4701, &(0x7f0000000100)={0x2, 0x0, 0x1, 0xf20, 0xb4c, 0x7, 0x7, 0x9, 0x8, 0x7, 0x1}) | |
mmap$IORING_OFF_CQ_RING(&(0x7f00007fd000/0x800000)=nil, 0x800000, 0x2, 0x22031, 0xffffffffffffffff, 0x8000000) | |
ioctl$syz_spec_18446744072138818634_15521(r0, 0x404c4701, &(0x7f0000000100)={0x2, 0x0, 0x0, 0x0, 0xb4c, 0x2, 0x40, 0x9, 0x8, 0x2, 0x1}) | |
C reproducer: | |
// autogenerated by syzkaller (https://github.com/google/syzkaller) | |
#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 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 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 (;;) { | |
sleep_ms(10); | |
if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) | |
break; | |
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; | |
if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { | |
} | |
memcpy((void*)0x20000000, "/dev/ptmx\000", 10); | |
res = syscall(__NR_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0x20000000ul, | |
/*flags=O_APPEND*/ 0x400ul, /*mode=*/0ul); | |
if (res != -1) | |
r[0] = res; | |
*(uint32_t*)0x20000040 = 0x15; | |
syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x5423, /*arg=*/0x20000040ul); | |
*(uint32_t*)0x20000100 = 2; | |
*(uint32_t*)0x20000104 = 0; | |
*(uint32_t*)0x20000108 = 1; | |
*(uint32_t*)0x2000010c = 0xf20; | |
*(uint32_t*)0x20000110 = 0xb4c; | |
*(uint32_t*)0x20000114 = 7; | |
*(uint32_t*)0x20000118 = 7; | |
*(uint32_t*)0x2000011c = 9; | |
*(uint32_t*)0x20000120 = 8; | |
*(uint32_t*)0x20000124 = 7; | |
*(uint32_t*)0x20000128 = 1; | |
memset((void*)0x2000012c, 0, 32); | |
syscall(__NR_ioctl, /*fd=*/r[0], /*arg0=*/0x404c4701, /*arg1=*/0x20000100ul); | |
syscall(__NR_mmap, /*addr=*/0x207fd000ul, /*len=*/0x800000ul, | |
/*prot=PROT_WRITE*/ 2ul, | |
/*flags=MAP_STACK|MAP_LOCKED|MAP_FIXED|MAP_ANONYMOUS|0x1*/ 0x22031ul, | |
/*fd=*/-1, /*offset=*/0x8000000ul); | |
*(uint32_t*)0x20000100 = 2; | |
*(uint32_t*)0x20000104 = 0; | |
*(uint32_t*)0x20000108 = 0; | |
*(uint32_t*)0x2000010c = 0; | |
*(uint32_t*)0x20000110 = 0xb4c; | |
*(uint32_t*)0x20000114 = 2; | |
*(uint32_t*)0x20000118 = 0x40; | |
*(uint32_t*)0x2000011c = 9; | |
*(uint32_t*)0x20000120 = 8; | |
*(uint32_t*)0x20000124 = 2; | |
*(uint32_t*)0x20000128 = 1; | |
memset((void*)0x2000012c, 0, 32); | |
syscall(__NR_ioctl, /*fd=*/r[0], /*arg0=*/0x404c4701, /*arg1=*/0x20000100ul); | |
} | |
int main(void) | |
{ | |
syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, | |
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1, | |
/*offset=*/0ul); | |
syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul, | |
/*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, | |
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1, | |
/*offset=*/0ul); | |
syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul, /*prot=*/0ul, | |
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1, | |
/*offset=*/0ul); | |
const char* reason; | |
(void)reason; | |
loop(); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment