Question about writing my own system call in FreeBSD

走远了吗. 提交于 2019-11-29 22:16:09

问题


OK, so I just finish reading the implementation of kill(2) of FreeBSD, and am trying to write my own "kill". This system call takes uid and signum and sends the signal to processes owned by uid, excluding the calling process.

How can I pass uid to the system call? In kill(2), pid is in argument struct kill_args. Is there a structure that contains uid the way that struct kill_args contains pid? If not, can I define a structure outside the kernel?


回答1:


It's easy, but kind of an involved process. Here's a module that installs a system call.

Include a bunch of stuff

#include <sys/types.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/sysproto.h>

Define your structure to hold arguments

struct mykill_args {
    int pid;
    int signo;
};

Define a handling function

static int
mykill(struct thread *td, void *args)
{
    struct mykill_args *uap = args;

    uprintf("mykill called. pid=%d, signo=%d\n", uap->pid, uap->signo);

    return 0;
}

You need a sysent object

static struct sysent mykill_sysent = {
    2,          /* number of arguments */
    mykill      /* function handling system call */
};

And an offset at which the system call will be installed.

/* Choose "the next" value later. */
static int offset = NO_SYSCALL;

load function

static int
load(struct module *module, int cmd, void *arg)
{
    int error = 0;

    switch (cmd) {
        case MOD_LOAD:
            uprintf("Loading module. Installing syscall at"
                " offset %d\n", offset);
            break;
        case MOD_UNLOAD:
            uprintf("Unloading module. syscall uninstalled from"
                " offset %d\n", offset);
            break;
        default:
            error = EOPNOTSUPP;
            break;
    }

    return error;
}

Install the system call

SYSCALL_MODULE(mykill, &offset, &mykill_sysent, load, NULL);

You can run your system call using syscall(2). Or using perl :)). Here's an example

[root@aiur /home/cnicutar/kld-syscall]# kldload ./mykill.ko
Loading module. Installing syscall at offset 210

[cnicutar@aiur ~/kld-syscall]$ perl -e 'syscall(210, 30, 15);'
mykill called. pid=30, signo=15


来源:https://stackoverflow.com/questions/6542650/question-about-writing-my-own-system-call-in-freebsd

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!