Commit a74fb73c12398b250fdc5e333a11e15a9e3a84fc
1 parent
fb45550d76
Exists in
master
and in
20 other branches
infrastructure for saner ret_from_kernel_thread semantics
* allow kernel_execve() leave the actual return to userland to caller (selected by CONFIG_GENERIC_KERNEL_EXECVE). Callers updated accordingly. * architecture that does select GENERIC_KERNEL_EXECVE in its Kconfig should have its ret_from_kernel_thread() do this: call schedule_tail call the callback left for it by copy_thread(); if it ever returns, that's because it has just done successful kernel_execve() jump to return from syscall IOW, its only difference from ret_from_fork() is that it does call the callback. * such an architecture should also get rid of ret_from_kernel_execve() and __ARCH_WANT_KERNEL_EXECVE This is the last part of infrastructure patches in that area - from that point on work on different architectures can live independently. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 5 changed files with 27 additions and 8 deletions Side-by-side Diff
arch/Kconfig
include/linux/syscalls.h
... | ... | @@ -827,7 +827,15 @@ |
827 | 827 | const char __user *pathname); |
828 | 828 | asmlinkage long sys_syncfs(int fd); |
829 | 829 | |
830 | +#ifndef CONFIG_GENERIC_KERNEL_EXECVE | |
830 | 831 | int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]); |
832 | +#else | |
833 | +#define kernel_execve(filename, argv, envp) \ | |
834 | + do_execve(filename, \ | |
835 | + (const char __user *const __user *)argv, \ | |
836 | + (const char __user *const __user *)envp, \ | |
837 | + current_pt_regs()) | |
838 | +#endif | |
831 | 839 | |
832 | 840 | |
833 | 841 | asmlinkage long sys_perf_event_open( |
init/main.c
... | ... | @@ -69,6 +69,7 @@ |
69 | 69 | #include <linux/slab.h> |
70 | 70 | #include <linux/perf_event.h> |
71 | 71 | #include <linux/file.h> |
72 | +#include <linux/ptrace.h> | |
72 | 73 | |
73 | 74 | #include <asm/io.h> |
74 | 75 | #include <asm/bugs.h> |
75 | 76 | |
... | ... | @@ -788,10 +789,10 @@ |
788 | 789 | do_one_initcall(*fn); |
789 | 790 | } |
790 | 791 | |
791 | -static void run_init_process(const char *init_filename) | |
792 | +static int run_init_process(const char *init_filename) | |
792 | 793 | { |
793 | 794 | argv_init[0] = init_filename; |
794 | - kernel_execve(init_filename, argv_init, envp_init); | |
795 | + return kernel_execve(init_filename, argv_init, envp_init); | |
795 | 796 | } |
796 | 797 | |
797 | 798 | static void __init kernel_init_freeable(void); |
... | ... | @@ -810,7 +811,8 @@ |
810 | 811 | flush_delayed_fput(); |
811 | 812 | |
812 | 813 | if (ramdisk_execute_command) { |
813 | - run_init_process(ramdisk_execute_command); | |
814 | + if (!run_init_process(ramdisk_execute_command)) | |
815 | + return 0; | |
814 | 816 | printk(KERN_WARNING "Failed to execute %s\n", |
815 | 817 | ramdisk_execute_command); |
816 | 818 | } |
817 | 819 | |
... | ... | @@ -822,14 +824,16 @@ |
822 | 824 | * trying to recover a really broken machine. |
823 | 825 | */ |
824 | 826 | if (execute_command) { |
825 | - run_init_process(execute_command); | |
827 | + if (!run_init_process(execute_command)) | |
828 | + return 0; | |
826 | 829 | printk(KERN_WARNING "Failed to execute %s. Attempting " |
827 | 830 | "defaults...\n", execute_command); |
828 | 831 | } |
829 | - run_init_process("/sbin/init"); | |
830 | - run_init_process("/etc/init"); | |
831 | - run_init_process("/bin/init"); | |
832 | - run_init_process("/bin/sh"); | |
832 | + if (!run_init_process("/sbin/init") || | |
833 | + !run_init_process("/etc/init") || | |
834 | + !run_init_process("/bin/init") || | |
835 | + !run_init_process("/bin/sh")) | |
836 | + return 0; | |
833 | 837 | |
834 | 838 | panic("No init found. Try passing init= option to kernel. " |
835 | 839 | "See Linux Documentation/init.txt for guidance."); |
kernel/kmod.c
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | #include <linux/notifier.h> |
38 | 38 | #include <linux/suspend.h> |
39 | 39 | #include <linux/rwsem.h> |
40 | +#include <linux/ptrace.h> | |
40 | 41 | #include <asm/uaccess.h> |
41 | 42 | |
42 | 43 | #include <trace/events/module.h> |
... | ... | @@ -221,6 +222,8 @@ |
221 | 222 | retval = kernel_execve(sub_info->path, |
222 | 223 | (const char *const *)sub_info->argv, |
223 | 224 | (const char *const *)sub_info->envp); |
225 | + if (!retval) | |
226 | + return 0; | |
224 | 227 | |
225 | 228 | /* Exec failed? */ |
226 | 229 | fail: |