I'm trying to start a userspace process (execute an ELF binary) inside the kernel when receiving a network message. In the network event handler, I initiate a work queue. In the workqueue handling function, I call do_execve but there comes a kernel panic with:
[ 113.305996] Unable to handle kernel paging request at virtual address ffffffffffffffd8
[ 113.306375] pgd = ffff8000f9d06000
[ 113.306520] [ffffffffffffffd8] *pgd=0000000000000000
[ 113.306915] Internal error: Oops: 96000004 [#1] SMP
The code:
static void clone_thread(struct work_struct *_work)
{
struct pcn_kmsg_work *work = (struct pcn_kmsg_work *)_work;
network_request_t *req = work->msg;
int ret = 0;
PSPRINTK("%s: exe_path %s\n", __func__, req->exe_path);
ret = do_execve(getname_kernel(req->exe_path), NULL, NULL);
PSPRINTK("%s: filename %p\n", __func__, getname_kernel(req->exe_path));
PSPRINTK("%s: ret %d\n", __func__, ret);
}
static int handle_network_request(struct pcn_kmsg_message *msg)
{
network_request_t *req = (network_request_t *)msg;
struct pcn_kmsg_work *work = kmalloc(sizeof(*work), GFP_ATOMIC);
BUG_ON(!work);
work->msg = req;
INIT_WORK((struct work_struct *)work, clone_thread);
queue_work(pcn_wq, (struct work_struct *)work);
return 0;
}
... ...
Then I tried to call do_execve in a kernel thread. But for some reason, the kernel thread only executes the printk never execute do_execve.
So I'm wondering how can I execute the ELF inside Linux kernel? Thank you.