Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about writing my own system call in FreeBSD

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?

like image 974
pippoflow Avatar asked Feb 23 '23 17:02

pippoflow


1 Answers

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
like image 98
cnicutar Avatar answered Mar 05 '23 18:03

cnicutar