Trong môi trường Linux, việc khởi chạy ứng dụng ở không gian người dùng trực tiếp từ mã nhân là khả thi nhờ vào cơ chế usermode-helper. Cơ chế này cung cấp một cầu nối an toàn để nhân thực thi các chương trình bên ngoài mà không vi phạm nguyên tắc phân tách quyền.
1. Gọi ứng dụng người dùng từ nhân
Hàm call_usermodehelper() là API chính được sử dụng cho mục đích này. Dưới đây là một ví dụ minh họa cách lập lịch tắt hệ thống sau một khoảng thời gian ngắn:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/kmod.h>
static struct delayed_work poweroff_task;
static void execute_poweroff(struct work_struct *work)
{
char *binary = "/sbin/shutdown";
char *args[] = {
binary,
"-h",
"now",
NULL
};
char *env[] = {
"HOME=/",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin",
NULL
};
call_usermodehelper(binary, args, env, UMH_WAIT_EXEC);
}
static int __init trigger_init(void)
{
INIT_DELAYED_WORK(&poweroff_task, execute_poweroff);
schedule_delayed_work(&poweroff_task, msecs_to_jiffies(200));
return 0;
}
static void __exit trigger_exit(void) {}
module_init(trigger_init);
module_exit(trigger_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Trigger system shutdown from kernel space");
Ở đây, hàm call_usermodehelper() được gọi với chế độ UMH_WAIT_EXEC, đảm bảo rằng quá trình khởi tạo lệnh được hoàn tất trước khi hàm trả về. API này thường được nhân sử dụng trong các tình huống như nạp/xoá module hoặc quản lý cgroup.
2. Thực thi script shell từ nhân
Để chạy một đoạn script shell, ta có thể gọi trình thông dịch (ví dụ: /bin/bash) kèm theo tùy chọn -c và chuỗi lệnh cần thực thi:
static int run_shell_command(void)
{
char interpreter[] = "/bin/bash";
char *argv[] = {
interpreter,
"-c",
"/bin/ls >> /tmp/list",
NULL
};
char *envp[] = {
"HOME=/",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin",
NULL
};
int ret = call_usermodehelper(interpreter, argv, envp, UMH_WAIT_PROC);
printk(KERN_DEBUG "Shell command executed with status: %d\n", ret);
return ret;
}
Lưu ý rằng tham số thứ tư của call_usermodehelper() — trong trường hợp này là UMH_WAIT_PROC — yêu cầu nhân chờ đến khi tiến trình con kết thúc hoàn toàn. Điều này hữu ích khi cần kiểm tra mã thoát hoặc đảm bảo tính tuần tự trong luồng thực thi.