Message ID | 1587452704-1299-4-git-send-email-yangtiezhu@loongson.cn (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Fix some issues about kmod | expand |
On Tue, Apr 21, 2020 at 03:05:03PM +0800, Tiezhu Yang wrote: > The exit status of child process is wrote to the address of variable > "status" after call waitpid() in the user space that corresponds with > kernel_wait4() in the kernel space. NACK, the issue is in umh, I'll send a fix. Luis
diff --git a/kernel/kmod.c b/kernel/kmod.c index 3cd075c..5851444 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -28,6 +28,8 @@ #include <trace/events/module.h> +#define MODULE_NOT_FOUND 256 + /* * Assuming: * @@ -144,6 +146,9 @@ int __request_module(bool wait, const char *fmt, ...) if (ret >= MODULE_NAME_LEN) return -ENAMETOOLONG; + if (strlen(module_name) == 0) + return MODULE_NOT_FOUND; + ret = security_kernel_module_request(module_name); if (ret) return ret;
If module name is empty, it is better to return directly at the beginning of request_module() without doing the needless call_modprobe() operation. (1) In the kernel space Call trace: request_module() | | __request_module() | | call_modprobe() | | call_usermodehelper_exec() -- retval = sub_info->retval; | | call_usermodehelper_exec_work() | | call_usermodehelper_exec_sync() -- sub_info->retval = ret; | | --> call_usermodehelper_exec_async() --> do_execve() | kernel_wait4(pid, (int __user *)&ret, 0, NULL); The exit status of child process is wrote to the address of variable "ret" after call kernel_wait4(), its value is 256 if module name is empty, then sub_info->retval is assigned to "ret" which is 256, the function call_usermodehelper_exec() returns 256, call_modprobe() and __request_module() also return 256. (2)In the user space when build and execute the following application, we can see the exit status is 256. $ ./system exit status = 256 $ ./execl exit status = 256 $ cat system.c #include <stdio.h> #include <stdlib.h> int main() { int status = 0; status = system("modprobe '' > /dev/null 2>&1"); printf("exit status = %d\n", status); return status; } $ cat execl.c #include <sys/wait.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> int main() { pid_t pid, w; int status; pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { execl("/bin/sh", "sh", "-c", "modprobe '' > /dev/null 2>&1", (char *) 0); } else { w = waitpid(pid, &status, 0); if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); } printf("exit status = %d\n", status); exit(EXIT_SUCCESS); } return 0; } The exit status of child process is wrote to the address of variable "status" after call waitpid() in the user space that corresponds with kernel_wait4() in the kernel space. Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> --- v4: - update the commit message with application v3: - no changes v2: - update the commit message to explain the detailed reason kernel/kmod.c | 5 +++++ 1 file changed, 5 insertions(+)