2006-07-10 15:45:13 +04:00
/*
2007-10-16 12:27:00 +04:00
* Copyright ( C ) 2000 - 2007 Jeff Dike ( jdike @ { addtoit , linux . intel } . com )
2005-04-17 02:20:36 +04:00
* Licensed under the GPL
*/
2007-10-16 12:27:00 +04:00
# include "linux/stddef.h"
# include "linux/fs.h"
2005-04-17 02:20:36 +04:00
# include "linux/smp_lock.h"
# include "linux/ptrace.h"
2007-10-16 12:27:00 +04:00
# include "linux/sched.h"
# include "asm/current.h"
# include "asm/processor.h"
2005-04-17 02:20:36 +04:00
# include "asm/uaccess.h"
# include "mem_user.h"
2007-10-16 12:27:00 +04:00
# include "skas.h"
2005-04-17 02:20:36 +04:00
# include "os.h"
void flush_thread ( void )
{
2007-10-16 12:26:58 +04:00
void * data = NULL ;
unsigned long end = proc_mm ? task_size : CONFIG_STUB_START ;
int ret ;
2006-03-31 14:30:22 +04:00
arch_flush_thread ( & current - > thread . arch ) ;
2007-10-16 12:26:58 +04:00
2007-10-16 12:27:06 +04:00
ret = unmap ( & current - > mm - > context . id , 0 , end , 1 , & data ) ;
2007-10-16 12:27:00 +04:00
if ( ret ) {
printk ( KERN_ERR " flush_thread - clearing address space failed, "
2007-10-16 12:26:58 +04:00
" err = %d \n " , ret ) ;
force_sig ( SIGKILL , current ) ;
}
2007-10-16 12:27:06 +04:00
__switch_mm ( & current - > mm - > context . id ) ;
2005-04-17 02:20:36 +04:00
}
void start_thread ( struct pt_regs * regs , unsigned long eip , unsigned long esp )
{
2007-10-16 12:26:58 +04:00
set_fs ( USER_DS ) ;
PT_REGS_IP ( regs ) = eip ;
PT_REGS_SP ( regs ) = esp ;
2005-04-17 02:20:36 +04:00
}
2006-07-10 15:45:13 +04:00
# ifdef CONFIG_TTY_LOG
extern void log_exec ( char * * argv , void * tty ) ;
# endif
2005-04-17 02:20:36 +04:00
static long execve1 ( char * file , char __user * __user * argv ,
2006-02-01 14:06:29 +03:00
char __user * __user * env )
2005-04-17 02:20:36 +04:00
{
2007-10-16 12:27:00 +04:00
long error ;
2007-02-10 12:44:03 +03:00
# ifdef CONFIG_TTY_LOG
2006-12-08 13:36:04 +03:00
struct tty_struct * tty ;
2005-04-17 02:20:36 +04:00
2006-09-26 10:33:08 +04:00
mutex_lock ( & tty_mutex ) ;
2006-12-08 13:36:04 +03:00
tty = get_current_tty ( ) ;
if ( tty )
log_exec ( argv , tty ) ;
2006-09-26 10:33:08 +04:00
mutex_unlock ( & tty_mutex ) ;
2005-04-17 02:20:36 +04:00
# endif
2007-10-16 12:27:00 +04:00
error = do_execve ( file , argv , env , & current - > thread . regs ) ;
if ( error = = 0 ) {
2005-04-17 02:20:36 +04:00
task_lock ( current ) ;
2007-10-16 12:27:00 +04:00
current - > ptrace & = ~ PT_DTRACE ;
2006-07-10 15:45:13 +04:00
# ifdef SUBARCH_EXECVE1
SUBARCH_EXECVE1 ( & current - > thread . regs . regs ) ;
# endif
2005-04-17 02:20:36 +04:00
task_unlock ( current ) ;
2007-10-16 12:27:00 +04:00
}
return error ;
2005-04-17 02:20:36 +04:00
}
long um_execve ( char * file , char __user * __user * argv , char __user * __user * env )
{
long err ;
err = execve1 ( file , argv , env ) ;
2007-10-16 12:27:00 +04:00
if ( ! err )
2007-10-16 12:27:05 +04:00
UML_LONGJMP ( current - > thread . exec_buf , 1 ) ;
2007-10-16 12:27:00 +04:00
return err ;
2005-04-17 02:20:36 +04:00
}
2006-03-31 14:30:15 +04:00
long sys_execve ( char __user * file , char __user * __user * argv ,
2005-04-17 02:20:36 +04:00
char __user * __user * env )
{
long error ;
char * filename ;
lock_kernel ( ) ;
2006-03-31 14:30:15 +04:00
filename = getname ( file ) ;
2005-04-17 02:20:36 +04:00
error = PTR_ERR ( filename ) ;
if ( IS_ERR ( filename ) ) goto out ;
error = execve1 ( filename , argv , env ) ;
putname ( filename ) ;
out :
unlock_kernel ( ) ;
2007-10-16 12:27:00 +04:00
return error ;
2005-04-17 02:20:36 +04:00
}