#c #linux #module #linux-kernel #netfilter
Вопрос:
Я пытаюсь выполнить команду терминала Linux из модуля ядра Linux в linux 5.10 с помощью call_usermodehelper, который вызывается из крючка сетевого фильтра, но поскольку я знаю, что он работает в контексте softirq, я просто не могу выполнить его в любом случае. Используя «UMH_WAIT_EXEC», я получаю scheduling while atomic: nc/16886/0x00000101
при отправке udp-пакета, который я ищу с помощью фильтра, и если я использую «UMH_WAIT», я получаю пустую ссылку. Код выглядит примерно так:
static unsigned int hfunc(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
// --snipp--
if (ntohs(udph->dest) == 1337) {
char *argv[4];
char *envp[4];
argv[0] = "/bin/bash";
argv[1] = "-c";
argv[2] = "/bin/ls";
argv[3] = NULL;
envp[0] = "HOME=/";
envp[1] = "TERM=linux";
envp[2] = "PATH=/sbin:/usr/sbin:/bin:/usr/bin";
envp[3] = NULL;
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
}
}
Как я могу запустить эту программу из контекста softirq крючка netfilter?
Ответ №1:
Я исправил это с помощью планирования.
static struct nf_hook_ops *nfho = NULL;
struct work_arg_struct {
struct work_struct work;
char *data;
};
static struct work_arg_struct my_work;
void bash_work_handler(struct work_struct *work){
struct work_arg_struct *work_arg;
work_arg = container_of(work, struct work_arg_struct, work);
// --snip--
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
return;
}
static unsigned int hfunc(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
if (ntohs(udph->dest) == 1337) {
// setup arguments
schedule_work(amp;my_work.work);
}
}
--snip--
static int __init module_init(void)
{
//--snip--
INIT_WORK(amp;my_work.work, bash_work_handler);
}