2

I'm trying to write a simple TCP server in a kernel module. The code compiles and runs fine except for when a client connects to the server. Once a client connects, it triggers a kernel warning in inet_accept. I was wondering if there was anything obvious that I'm doing wrong. Error checking omitted (it's just a bunch of if rets).

Warning:

---[ end trace 343bcc83461e314f ]---
 ret_from_fork+0x35/0x40
  ? SyS_exit_group+0x10/0x10
  ? do_syscall_64+0x74/0x190
  ? kthread_create_on_node+0x70/0x70
 kthread+0x113/0x130
server_start+0x138/0x170
WARNING: CPU: 0 PID: 2038 at ./include/net/sock.h:1715 inet_accept+0x14d/0x160

Code:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/string.h>
#include <net/sock.h>

struct task_struct *task = NULL;

static int server_start(void *ptr){
    int ret = 0;
    struct sockaddr_in sin;
    struct socket *ssk = NULL, *csk = NULL;

    ret = sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &ssk);

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(4500);
    sin.sin_addr.s_addr = INADDR_ANY;

    ret = ssk->ops->bind(ssk, (struct sockaddr *)&sin, sizeof(sin));

    ret = ssk->ops->listen(ssk, 1);

    ret = sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &csk);

    ret = ssk->ops->accept(ssk, csk, 0, 0);

    sock_release(csk); sock_release(ssk);
    return 0;
}

void server_init(void){
    task = kthread_run(server_start, (void *)NULL, "server_thread");
}

void server_exit(void){
    if (task){
        kthread_stop(task);
    }
}

static int __init init_mod(void){
    server_init();
    return 0;
}

static void __exit exit_mod(void){
    server_exit();
}

MODULE_LICENSE("GPL");

module_init(init_mod);
module_exit(exit_mod);
Chirality
  • 745
  • 8
  • 22

0 Answers0