| Jeff Dike | 1d3468a | 2006-07-10 04:45:13 -0700 | [diff] [blame] | 1 | /* | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 |  * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) | 
 | 3 |  * Licensed under the GPL | 
 | 4 |  */ | 
 | 5 |  | 
 | 6 | #include "linux/slab.h" | 
 | 7 | #include "linux/smp_lock.h" | 
 | 8 | #include "linux/ptrace.h" | 
 | 9 | #include "asm/ptrace.h" | 
 | 10 | #include "asm/pgtable.h" | 
 | 11 | #include "asm/tlbflush.h" | 
 | 12 | #include "asm/uaccess.h" | 
 | 13 | #include "user_util.h" | 
 | 14 | #include "kern_util.h" | 
 | 15 | #include "mem_user.h" | 
 | 16 | #include "kern.h" | 
 | 17 | #include "irq_user.h" | 
 | 18 | #include "tlb.h" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 19 | #include "os.h" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 | #include "choose-mode.h" | 
 | 21 | #include "mode_kern.h" | 
 | 22 |  | 
 | 23 | void flush_thread(void) | 
 | 24 | { | 
| Paolo 'Blaisorblade' Giarrusso | aa6758d | 2006-03-31 02:30:22 -0800 | [diff] [blame] | 25 | 	arch_flush_thread(¤t->thread.arch); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 26 | 	CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); | 
 | 27 | } | 
 | 28 |  | 
 | 29 | void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) | 
 | 30 | { | 
 | 31 | 	CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); | 
 | 32 | } | 
 | 33 |  | 
| Jeff Dike | 1d3468a | 2006-07-10 04:45:13 -0700 | [diff] [blame] | 34 | #ifdef CONFIG_TTY_LOG | 
 | 35 | extern void log_exec(char **argv, void *tty); | 
 | 36 | #endif | 
 | 37 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 38 | static long execve1(char *file, char __user * __user *argv, | 
| Paolo 'Blaisorblade' Giarrusso | 42947cb | 2006-02-01 03:06:29 -0800 | [diff] [blame] | 39 | 		    char __user *__user *env) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 40 | { | 
 | 41 |         long error; | 
 | 42 |  | 
 | 43 | #ifdef CONFIG_TTY_LOG | 
| Alan Cox | b1fc0b1 | 2006-09-25 23:33:08 -0700 | [diff] [blame] | 44 | 	mutex_lock(&tty_mutex); | 
 | 45 | 	task_lock(current);	/* FIXME:  is this needed ? */ | 
| Jeff Dike | 1d3468a | 2006-07-10 04:45:13 -0700 | [diff] [blame] | 46 | 	log_exec(argv, current->signal->tty); | 
 | 47 | 	task_unlock(current); | 
| Alan Cox | b1fc0b1 | 2006-09-25 23:33:08 -0700 | [diff] [blame] | 48 | 	mutex_unlock(&tty_mutex); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 49 | #endif | 
 | 50 |         error = do_execve(file, argv, env, ¤t->thread.regs); | 
 | 51 |         if (error == 0){ | 
 | 52 | 		task_lock(current); | 
 | 53 |                 current->ptrace &= ~PT_DTRACE; | 
| Jeff Dike | 1d3468a | 2006-07-10 04:45:13 -0700 | [diff] [blame] | 54 | #ifdef SUBARCH_EXECVE1 | 
 | 55 | 		SUBARCH_EXECVE1(¤t->thread.regs.regs); | 
 | 56 | #endif | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 57 | 		task_unlock(current); | 
 | 58 |                 set_cmdline(current_cmd()); | 
 | 59 |         } | 
 | 60 |         return(error); | 
 | 61 | } | 
 | 62 |  | 
 | 63 | long um_execve(char *file, char __user *__user *argv, char __user *__user *env) | 
 | 64 | { | 
 | 65 | 	long err; | 
 | 66 |  | 
 | 67 | 	err = execve1(file, argv, env); | 
 | 68 | 	if(!err) | 
 | 69 | 		do_longjmp(current->thread.exec_buf, 1); | 
 | 70 | 	return(err); | 
 | 71 | } | 
 | 72 |  | 
| Al Viro | 4d338e1 | 2006-03-31 02:30:15 -0800 | [diff] [blame] | 73 | long sys_execve(char __user *file, char __user *__user *argv, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 74 | 		char __user *__user *env) | 
 | 75 | { | 
 | 76 | 	long error; | 
 | 77 | 	char *filename; | 
 | 78 |  | 
 | 79 | 	lock_kernel(); | 
| Al Viro | 4d338e1 | 2006-03-31 02:30:15 -0800 | [diff] [blame] | 80 | 	filename = getname(file); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 81 | 	error = PTR_ERR(filename); | 
 | 82 | 	if (IS_ERR(filename)) goto out; | 
 | 83 | 	error = execve1(filename, argv, env); | 
 | 84 | 	putname(filename); | 
 | 85 |  out: | 
 | 86 | 	unlock_kernel(); | 
 | 87 | 	return(error); | 
 | 88 | } |