# Calling sys_execve from a kernel module



## silent_control (Jan 3, 2017)

I have a kernel module (which is actually a char device) that has this function, which tries to execute execve "/bin/ls".


```
static void funct()
{
    struct execve_args args;

    args.fname = 0x8008090; // userspace address
    args.argv = 0x8008220; // userspace address
    args.envv = 0x8008210; // userspace address

   uprintf("Here: funct\n");
 
    int ret = sys_execve(curthread, &args);
    uprintf("Returned with %d\n", ret);
}
```

CASE A:
I have a process (in userspace) that opens the char device and writes to it. In the write function, I call funct() and it basically executes "/bin/ls", and it outputs the files and folders from the current folder.

CASE B:
If I try to call funct by performing a buffer overflow attack in the kernel (the process will feed a payload to the device), by overwriting a return address on the stack with funct()'s address, there is no "/bin/ls" output, although funct() gets called - "Here: funct" gets printed.

Why is that happening? Is it because the kernel crashes and some post-sys_execve routines are not able to give the control back to the process or to actually print the result of "/bin/ls"? (sys_execve returns with 0 in both cases). What can I do in order to get the respective output to show before the crash/panic takes place?

P.S. The same thing as in CASE B happens if I try to inject a shellcode that puts the right arguments in rdi, rsi and calls sys_execve.
P.S.S. It's for academic purposes.


----------



## aribi (Jan 6, 2017)

silent_control said:


> args.fname = 0x8008090; // userspace address args.argv = 0x8008220; // userspace address args.envv = 0x8008210; // userspace address


The comment suggest you're thinking this is an address in userspace. If this really is code in a kernel module, then this probably is an address in kernelspace (kernel modules use kernelmem AFAIK)
Take a look at https://www.freebsd.org/doc/en_US.ISO8859-1/books/arch-handbook/driverbasics-char.html 
It includes <sys/malloc.h>; it moves data from kernelspace to userspace by calling uiomove.
If you really have a pointer to userspace within your kernel module, please explain how you got that.


----------



## silent_control (Jan 7, 2017)

aribi said:


> The comment suggest you're thinking this is an address in userspace. If this really is code in a kernel module, then this probably is an address in kernelspace (kernel modules use kernelmem AFAIK)
> Take a look at https://www.freebsd.org/doc/en_US.ISO8859-1/books/arch-handbook/driverbasics-char.html
> It includes <sys/malloc.h>; it moves data from kernelspace to userspace by calling uiomove.
> If you really have a pointer to userspace within your kernel module, please explain how you got that.


They are indeed user space addresses. It's because sys_execve takes userspace pointers and then the data is moved to the kernel space from the user space.


----------



## aribi (Jan 7, 2017)

Taking the risk of pointing to the obvious, but since you mentioned the kernel crashed.
What does kgdb say about your crashdump:
`# cd /usr/obj/usr/src/sys/[I]YOUR_KERNEL_CONFIG[/I]
# kgdb kernel.debug /var/crash/YOUR_LATEST_CORE`
from https://www.freebsd.org/doc/en/books/developers-handbook/kerneldebug-gdb.html
This will show you the panic messages as well as give you the opportunity to look around on the stack to see where your overwrite failed.


----------



## _martin (Jan 11, 2017)

How can you call execve() in kernel land ? Should it be an exploit you do the magic in kernel (elevate privileges, etc.) and return back to userspace. Userspace then executes whatever is there to execute under new creds..


----------

