mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									fb45550d76
								
							
						
					
					
						commit
						a74fb73c12
					
				
					 5 changed files with 27 additions and 8 deletions
				
			
		|  | @ -261,6 +261,9 @@ config ARCH_WANT_OLD_COMPAT_IPC | |||
| config GENERIC_KERNEL_THREAD | ||||
| 	bool | ||||
| 
 | ||||
| config GENERIC_KERNEL_EXECVE | ||||
| 	bool | ||||
| 
 | ||||
| config HAVE_ARCH_SECCOMP_FILTER | ||||
| 	bool | ||||
| 	help | ||||
|  |  | |||
|  | @ -827,7 +827,15 @@ asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, | |||
| 				  const char  __user *pathname); | ||||
| asmlinkage long sys_syncfs(int fd); | ||||
| 
 | ||||
| #ifndef CONFIG_GENERIC_KERNEL_EXECVE | ||||
| int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]); | ||||
| #else | ||||
| #define kernel_execve(filename, argv, envp) \ | ||||
| 	do_execve(filename, \ | ||||
| 		(const char __user *const __user *)argv, \ | ||||
| 		(const char __user *const __user *)envp, \ | ||||
| 		current_pt_regs()) | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| asmlinkage long sys_perf_event_open( | ||||
|  |  | |||
							
								
								
									
										20
									
								
								init/main.c
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								init/main.c
									
										
									
									
									
								
							|  | @ -69,6 +69,7 @@ | |||
| #include <linux/slab.h> | ||||
| #include <linux/perf_event.h> | ||||
| #include <linux/file.h> | ||||
| #include <linux/ptrace.h> | ||||
| 
 | ||||
| #include <asm/io.h> | ||||
| #include <asm/bugs.h> | ||||
|  | @ -788,10 +789,10 @@ static void __init do_pre_smp_initcalls(void) | |||
| 		do_one_initcall(*fn); | ||||
| } | ||||
| 
 | ||||
| static void run_init_process(const char *init_filename) | ||||
| static int run_init_process(const char *init_filename) | ||||
| { | ||||
| 	argv_init[0] = init_filename; | ||||
| 	kernel_execve(init_filename, argv_init, envp_init); | ||||
| 	return kernel_execve(init_filename, argv_init, envp_init); | ||||
| } | ||||
| 
 | ||||
| static void __init kernel_init_freeable(void); | ||||
|  | @ -810,7 +811,8 @@ static int __ref kernel_init(void *unused) | |||
| 	flush_delayed_fput(); | ||||
| 
 | ||||
| 	if (ramdisk_execute_command) { | ||||
| 		run_init_process(ramdisk_execute_command); | ||||
| 		if (!run_init_process(ramdisk_execute_command)) | ||||
| 			return 0; | ||||
| 		printk(KERN_WARNING "Failed to execute %s\n", | ||||
| 				ramdisk_execute_command); | ||||
| 	} | ||||
|  | @ -822,14 +824,16 @@ static int __ref kernel_init(void *unused) | |||
| 	 * trying to recover a really broken machine. | ||||
| 	 */ | ||||
| 	if (execute_command) { | ||||
| 		run_init_process(execute_command); | ||||
| 		if (!run_init_process(execute_command)) | ||||
| 			return 0; | ||||
| 		printk(KERN_WARNING "Failed to execute %s.  Attempting " | ||||
| 					"defaults...\n", execute_command); | ||||
| 	} | ||||
| 	run_init_process("/sbin/init"); | ||||
| 	run_init_process("/etc/init"); | ||||
| 	run_init_process("/bin/init"); | ||||
| 	run_init_process("/bin/sh"); | ||||
| 	if (!run_init_process("/sbin/init") || | ||||
| 	    !run_init_process("/etc/init") || | ||||
| 	    !run_init_process("/bin/init") || | ||||
| 	    !run_init_process("/bin/sh")) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	panic("No init found.  Try passing init= option to kernel. " | ||||
| 	      "See Linux Documentation/init.txt for guidance."); | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ | |||
| #include <linux/notifier.h> | ||||
| #include <linux/suspend.h> | ||||
| #include <linux/rwsem.h> | ||||
| #include <linux/ptrace.h> | ||||
| #include <asm/uaccess.h> | ||||
| 
 | ||||
| #include <trace/events/module.h> | ||||
|  | @ -221,6 +222,8 @@ static int ____call_usermodehelper(void *data) | |||
| 	retval = kernel_execve(sub_info->path, | ||||
| 			       (const char *const *)sub_info->argv, | ||||
| 			       (const char *const *)sub_info->envp); | ||||
| 	if (!retval) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* Exec failed? */ | ||||
| fail: | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ | |||
| #include <linux/mutex.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/freezer.h> | ||||
| #include <linux/ptrace.h> | ||||
| #include <trace/events/sched.h> | ||||
| 
 | ||||
| static DEFINE_SPINLOCK(kthread_create_lock); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Al Viro
						Al Viro