Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I share data between kernel C programs and user level C programs?

I am using Ubuntu 9.04 with kernel 2.8.32. I created a simple system call that counts the number of clone and execve calls. When the user/shell calls this system call, I would like it to pass back to the user these two values. As of now I am using:

#include <linux/sched.h>
#include <linux/asmlinkage>

/* These two variables are extern longs which are defined in sched.h and initialized in process_32.c */

total_execve;
total_clones;

long mycall* (int i){
    int array[2];
    array[0] = total_execve;
    array[1] = total_clones;
    return array;
}

I am not able to compile this as I get an undefined reference.

Regarding returning the array: Will my new call be able to access the array, won't the array be located in kernel memory?

like image 676
ddd Avatar asked Jan 20 '23 12:01

ddd


2 Answers

Don't return pointers into the stack. Have the caller pass pointers into the function. Also, your function declaration syntax is incorrect. Here's what you want to do:

void mycall (int *execve, int *clones)
{
    *execve = total_execve;
    *clones = total_clones;
}
like image 87
nmichaels Avatar answered Jan 23 '23 03:01

nmichaels


Answering your last question first: the array is indeed in "kernel" memory, but it's stack allocated which means it wilL "go away" when the mycall() function exits. Your function may appear to work, but may fail in cases where the memory gets re-used quickly.

To return multiple values, the common pattern is for the caller to pass in pointers to user-space memory, and have the kernel routine to fill them in. For example, you could pass in two pointers for your two values, or define a single struct that contains the values you need and gets filled in by the kernel routine.

like image 43
payne Avatar answered Jan 23 '23 02:01

payne