milabs / khook

Linux Kernel hooking engine (x86)
GNU General Public License v2.0
327 stars 50 forks source link

unloading lkm got soft lockup #20

Open lkygithub opened 3 weeks ago

lkygithub commented 3 weeks ago

Hi, I successfully hijacked the ioctl system call by khook, but encountered the following problem when unloading the kernel module using rmmod, it seems that there is some kind of kernel deadlock

Message from syslogd@infiniAI-nxdx-B01-04 at Sep 18 11:36:44 ...
 kernel:[444456.478983] watchdog: BUG: soft lockup - CPU#122 stuck for 22s! [migration/122:745]

Message from syslogd@infiniAI-nxdx-B01-04 at Sep 18 11:36:48 ...
 kernel:[444460.223056] watchdog: BUG: soft lockup - CPU#66 stuck for 22s! [rmmod:2792165]

Message from syslogd@infiniAI-nxdx-B01-04 at Sep 18 11:37:12 ...
 kernel:[444484.479453] watchdog: BUG: soft lockup - CPU#122 stuck for 22s! [migration/122:745]

Message from syslogd@infiniAI-nxdx-B01-04 at Sep 18 11:37:16 ...
 kernel:[444488.223517] watchdog: BUG: soft lockup - CPU#66 stuck for 22s! [rmmod:2792165]

Message from syslogd@infiniAI-nxdx-B01-04 at Sep 18 11:37:40 ...
 kernel:[444512.479922] watchdog: BUG: soft lockup - CPU#122 stuck for 22s! [migration/122:745]

Message from syslogd@infiniAI-nxdx-B01-04 at Sep 18 11:37:56 ...
 kernel:[444528.224183] watchdog: BUG: soft lockup - CPU#66 stuck for 23s! [rmmod:2792165]

Message from syslogd@infiniAI-nxdx-B01-04 at Sep 18 11:38:08 ...
 kernel:[444540.480387] watchdog: BUG: soft lockup - CPU#122 stuck for 22s! [migration/122:745]

Message from syslogd@infiniAI-nxdx-B01-04 at Sep 18 11:38:24 ...

Here is my source code:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/sched.h>
#include <linux/ioctl.h>

#include <khook/engine.h>

KHOOK_EXT(long, __x64_sys_ioctl, const struct pt_regs *);

static long khook___x64_sys_ioctl(const struct pt_regs *regs)
{
    int fd = regs->di;
    unsigned long request = regs->si;
    unsigned long arg = regs->dx;

    unsigned int cmd = _IOC_NR(request);
    unsigned int type = _IOC_TYPE(request);
    unsigned int size = _IOC_SIZE(request);
    unsigned int dir = _IOC_DIR(request);

    pid_t pid = current->pid;
    pid_t tgid = current->tgid;

    printk(KERN_INFO "kernel-hook: ioctl: fd=%d, request=0x%lx, arg=0x%lx, cmd=%u, type=0x%x, size=%u, dir=%u, pid=%d, tgid=%d\n", fd, request, arg, cmd, type, size, dir, pid, tgid);

    return KHOOK_ORIGIN(__x64_sys_ioctl, regs);
}

int init_module(void)
{
    return khook_init(NULL);
}

void cleanup_module(void)
{
    khook_cleanup();
}

MODULE_LICENSE("GPL\0but who really cares?");

According to the answer in stackoverflow unloading a kernel module that hijacking system calls by modifying sys_call_table is unsafe. How can I safely unload such a kernel module?

milabs commented 2 weeks ago

@lkygithub to unload your module you have to be sure no process (thread) sleeps in hooked function(s), for example unhooking of __x64_sys_ioctl might be blocked because there is a user task which currently sleeps