Skip to content

Instantly share code, notes, and snippets.

@TomAPU
Created August 24, 2024 20:50
INFO: task hung in gsm_cleanup_mux
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