Выполнение ELF в ядре Linux с помощью workqueue или kthread - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь запустить процесс пользовательского пространства (выполнить двоичный файл ELF) внутри ядра при получении сетевого сообщения. В сетевом обработчике событий я инициирую рабочую очередь. В функции обработки рабочей очереди я вызываю do_execve, но возникает паника ядра:

[  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

Код:

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;
}
... ...

Затем я попытался вызвать do_execve в потоке ядра. Но по какой-то причине поток ядра выполняет только printk, никогда не выполняет do_execve.

Так что мне интересно, как я могу выполнить ELF внутри ядра Linux? Спасибо.

1 Ответ

2 голосов
/ 02 мая 2019

Для этого вы должны использовать call_usermodehelper() внутренний API-интерфейс ядра:

#include <linux/kmod.h>

/* ... */ 

{
    char ∗argv[] = { req->exe_path, NULL };
    static char ∗envp[] = {
        "HOME=/",
        "TERM=linux",
        "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL };

    return call_usermodehelper( argv[0], argv, envp, UMH_WAIT_EXEC );
}

Мне также кажется, что ваш struct pcn_kmsg_message вероятно освобожден до запуска рабочей очереди - вам, вероятно, нужно скопироватьexe_path строка в структуру pcn_kmsg_work вместо простого копирования указателя.

...