Commit a74fb73c12398b250fdc5e333a11e15a9e3a84fc

Authored by Al Viro
1 parent fb45550d76

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

... ... @@ -261,6 +261,9 @@
261 261 config GENERIC_KERNEL_THREAD
262 262 bool
263 263  
  264 +config GENERIC_KERNEL_EXECVE
  265 + bool
  266 +
264 267 config HAVE_ARCH_SECCOMP_FILTER
265 268 bool
266 269 help
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(
... ... @@ -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.");
... ... @@ -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:
... ... @@ -16,6 +16,7 @@
16 16 #include <linux/mutex.h>
17 17 #include <linux/slab.h>
18 18 #include <linux/freezer.h>
  19 +#include <linux/ptrace.h>
19 20 #include <trace/events/sched.h>
20 21  
21 22 static DEFINE_SPINLOCK(kthread_create_lock);