I checked out Kernel APIs, Part 1: Invoking user - space applications from the kernel, and Executing a user-space function from the kernel space - Stack Overflow - and here is a small kernel module, callmodule.c
, demonstrating that:
// http://people.ee.ethz.ch/~arkeller/linux/code/usermodehelper.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
static int __init callmodule_init(void)
{
int ret = 0;
char userprog[] = "/path/to/mytest";
char *argv[] = {userprog, "2", NULL };
char *envp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
printk("callmodule: init %s\n", userprog);
/* last parameter: 1 -> wait until execution has finished, 0 go ahead without waiting*/
/* returns 0 if usermode process was started successfully, errorvalue otherwise*/
/* no possiblity to get return value of usermode process*/
ret = call_usermodehelper(userprog, argv, envp, UMH_WAIT_EXEC);
if (ret != 0)
printk("error in call to usermodehelper: %i\n", ret);
else
printk("everything all right\n");
return 0;
}
static void __exit callmodule_exit(void)
{
printk("callmodule: exit\n");
}
module_init(callmodule_init);
module_exit(callmodule_exit);
MODULE_LICENSE("GPL");
... with Makefile
:
obj-m += callmodule.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
When I run this via sudo insmod ./callmodule.ko && sudo rmmod callmodule
, I get in /var/log/syslog
:
Feb 10 00:42:45 mypc kernel: [71455.260355] callmodule: init /path/to/mytest
Feb 10 00:42:45 mypc kernel: [71455.261218] everything all right
Feb 10 00:42:45 mypc kernel: [71455.286131] callmodule: exit
... which apparently means all went fine. (Using Linux 2.6.38-16-generic #67-Ubuntu SMP)
My question is - how can I get the PID of the process instantiated from a kernel module? Is there a similar process other than call_usermodehelper
, that will allow me to instantiate a user-space process in kernel space, and obtain its pid?
Note that it may not be possible to use call_usermodehelper
and get the instantiated process PID:
Re: call_usermodehelper's pid ? — Linux Kernel Newbies
I want to create a user space process from within a kernel module, and be able to kill it, send signals to it, etc...
can I know its pid ?
No, you can't. But since inside the implementation the pid is known, patch that makes it available would not be too hard (note, that errors are always negative in kernel and pids are positive, limited to 2**16). You would have to modify all callers that expect 0 on success though.
I poked around the sources a bit, and it seems ultimately there is a call chain: call_usermodehelper
-> call_usermodehelper_setup
-> __call_usermodehelper
, which looks like:
static void __call_usermodehelper(struct work_struct *work)
{
struct subprocess_info *sub_info =
container_of(work, struct subprocess_info, work);
// ...
if (wait == UMH_WAIT_PROC)
pid = kernel_thread(wait_for_helper, sub_info,
CLONE_FS | CLONE_FILES | SIGCHLD);
else
pid = kernel_thread(____call_usermodehelper, sub_info,
CLONE_VFORK | SIGCHLD);
...
... so a PID of a kernel thread is used, but it is saved nowhere; also, neither work_struct
nor subprocess_info
have a pid
field (task_struct
does, but nothing here seems to use task_struct
). Recording this pid would require changing the kernel sources - and as I'd like to avoid that, this is the reason why I'm also interested in approaches other than call_usermodehelper
...
A tentative answer from my understanding of the implementation in kmod.c.
If you look at the code of call_usermodehelper
you will see it calls call_usermodehelper_setup
and then call_usermodehelper_exec
.
call_usermodehelper_setup
takes as parameter an init function that will be executed just before the do_execve
. I believe the value of current
when the init function gets executed will get you the task_struct
of the user process.
So to get the pid you will need to:
call_usermodehelper
in your code.call_usermodehelper_setup
.task_struct
and in turn the PID.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With