blob: 5064fb691eb57df91ee48dbb54a0acbecfb98d97 [file] [log] [blame]
Jeff Dike1d3468a2006-07-10 04:45:13 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * 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"
Alexey Dobriyan4e950f62007-07-30 02:36:13 +04009#include "linux/fs.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include "asm/ptrace.h"
11#include "asm/pgtable.h"
12#include "asm/tlbflush.h"
13#include "asm/uaccess.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include "kern_util.h"
Jeff Dike4ff83ce2007-05-06 14:51:08 -070015#include "as-layout.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include "mem_user.h"
17#include "kern.h"
18#include "irq_user.h"
19#include "tlb.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include "os.h"
Jeff Dike77bf4402007-10-16 01:26:58 -070021#include "skas/skas.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070022
23void flush_thread(void)
24{
Jeff Dike77bf4402007-10-16 01:26:58 -070025 void *data = NULL;
26 unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
27 int ret;
28
Paolo 'Blaisorblade' Giarrussoaa6758d2006-03-31 02:30:22 -080029 arch_flush_thread(&current->thread.arch);
Jeff Dike77bf4402007-10-16 01:26:58 -070030
31 ret = unmap(&current->mm->context.skas.id, 0, end, 1, &data);
32 if(ret){
33 printk("flush_thread - clearing address space failed, "
34 "err = %d\n", ret);
35 force_sig(SIGKILL, current);
36 }
37
38 __switch_mm(&current->mm->context.skas.id);
Linus Torvalds1da177e2005-04-16 15:20:36 -070039}
40
41void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
42{
Jeff Dike77bf4402007-10-16 01:26:58 -070043 set_fs(USER_DS);
44 PT_REGS_IP(regs) = eip;
45 PT_REGS_SP(regs) = esp;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046}
47
Jeff Dike1d3468a2006-07-10 04:45:13 -070048#ifdef CONFIG_TTY_LOG
49extern void log_exec(char **argv, void *tty);
50#endif
51
Linus Torvalds1da177e2005-04-16 15:20:36 -070052static long execve1(char *file, char __user * __user *argv,
Paolo 'Blaisorblade' Giarrusso42947cb2006-02-01 03:06:29 -080053 char __user *__user *env)
Linus Torvalds1da177e2005-04-16 15:20:36 -070054{
55 long error;
Jeff Dikef9795222007-02-10 01:44:03 -080056#ifdef CONFIG_TTY_LOG
Peter Zijlstra24ec8392006-12-08 02:36:04 -080057 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Alan Coxb1fc0b12006-09-25 23:33:08 -070059 mutex_lock(&tty_mutex);
Peter Zijlstra24ec8392006-12-08 02:36:04 -080060 tty = get_current_tty();
61 if (tty)
62 log_exec(argv, tty);
Alan Coxb1fc0b12006-09-25 23:33:08 -070063 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064#endif
65 error = do_execve(file, argv, env, &current->thread.regs);
66 if (error == 0){
67 task_lock(current);
68 current->ptrace &= ~PT_DTRACE;
Jeff Dike1d3468a2006-07-10 04:45:13 -070069#ifdef SUBARCH_EXECVE1
70 SUBARCH_EXECVE1(&current->thread.regs.regs);
71#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 task_unlock(current);
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 }
74 return(error);
75}
76
77long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
78{
79 long err;
80
81 err = execve1(file, argv, env);
82 if(!err)
83 do_longjmp(current->thread.exec_buf, 1);
84 return(err);
85}
86
Al Viro4d338e12006-03-31 02:30:15 -080087long sys_execve(char __user *file, char __user *__user *argv,
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 char __user *__user *env)
89{
90 long error;
91 char *filename;
92
93 lock_kernel();
Al Viro4d338e12006-03-31 02:30:15 -080094 filename = getname(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 error = PTR_ERR(filename);
96 if (IS_ERR(filename)) goto out;
97 error = execve1(filename, argv, env);
98 putname(filename);
99 out:
100 unlock_kernel();
101 return(error);
102}