Example #1
0
void userspace(union uml_pt_regs *regs)
{
	int err, status, op, pid = userspace_pid[0];
	int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/

	while(1){
		restore_registers(pid, regs);

		/* Now we set local_using_sysemu to be used for one loop */
		local_using_sysemu = get_using_sysemu();

		op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));

		err = ptrace(op, pid, 0, 0);
		if(err)
			panic("userspace - could not resume userspace process, "
			      "pid=%d, ptrace operation = %d, errno = %d\n",
			      op, errno);

		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
		if(err < 0)
			panic("userspace - waitpid failed, errno = %d\n", 
			      errno);

		regs->skas.is_user = 1;
		save_registers(pid, regs);
		UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */

		if(WIFSTOPPED(status)){
		  	switch(WSTOPSIG(status)){
			case SIGSEGV:
                                handle_segv(pid, regs);
				break;
			case SIGTRAP + 0x80:
			        handle_trap(pid, regs, local_using_sysemu);
				break;
			case SIGTRAP:
				relay_signal(SIGTRAP, regs);
				break;
			case SIGIO:
			case SIGVTALRM:
			case SIGILL:
			case SIGBUS:
			case SIGFPE:
			case SIGWINCH:
                                user_signal(WSTOPSIG(status), regs, pid);
				break;
			default:
			        printk("userspace - child stopped with signal "
				       "%d\n", WSTOPSIG(status));
			}
			interrupt_end();

			/* Avoid -ERESTARTSYS handling in host */
			PT_SYSCALL_NR(regs->skas.regs) = -1;
		}
	}
}
Example #2
0
void userspace(union uml_pt_regs *regs)
{
	int err, status, op, pid = userspace_pid[0];

	restore_registers(regs);
		
	err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
	if(err)
		panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
		       errno);
	while(1){
		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
		if(err < 0)
			panic("userspace - waitpid failed, errno = %d\n", 
			      errno);

		regs->skas.is_user = 1;
		save_registers(regs);

		if(WIFSTOPPED(status)){
		  	switch(WSTOPSIG(status)){
			case SIGSEGV:
				handle_segv(pid);
				break;
			case SIGTRAP:
			        handle_trap(pid, regs);
				break;
			case SIGIO:
			case SIGVTALRM:
			case SIGILL:
			case SIGBUS:
			case SIGFPE:
			case SIGWINCH:
				user_signal(WSTOPSIG(status), regs);
				break;
			default:
			        printk("userspace - child stopped with signal "
				       "%d\n", WSTOPSIG(status));
			}
			interrupt_end();
		}

		restore_registers(regs);

		op = singlestepping_skas() ? PTRACE_SINGLESTEP : 
			PTRACE_SYSCALL;
		err = ptrace(op, pid, 0, 0);
		if(err)
			panic("userspace - PTRACE_SYSCALL failed, "
			      "errno = %d\n", errno);
	}
}
Example #3
0
void userspace(union uml_pt_regs *regs)
{
	int err, status, op, pt_syscall_parm, pid = userspace_pid[0];
	int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/

	restore_registers(regs);
		
	local_using_sysemu = get_using_sysemu();

	pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
	err = ptrace(pt_syscall_parm, pid, 0, 0);

	if(err)
		panic("userspace - PTRACE_%s failed, errno = %d\n",
		       local_using_sysemu ? "SYSEMU" : "SYSCALL", errno);
	while(1){
		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
		if(err < 0)
			panic("userspace - waitpid failed, errno = %d\n", 
			      errno);

		regs->skas.is_user = 1;
		save_registers(regs);

		if(WIFSTOPPED(status)){
		  	switch(WSTOPSIG(status)){
			case SIGSEGV:
				handle_segv(pid);
				break;
			case SIGTRAP:
			        handle_trap(pid, regs, local_using_sysemu);
				break;
			case SIGIO:
			case SIGVTALRM:
			case SIGILL:
			case SIGBUS:
			case SIGFPE:
			case SIGWINCH:
				user_signal(WSTOPSIG(status), regs);
				break;
			default:
			        printk("userspace - child stopped with signal "
				       "%d\n", WSTOPSIG(status));
			}
			interrupt_end();
		}

		restore_registers(regs);

		/*Now we ended the syscall, so re-read local_using_sysemu.*/
		local_using_sysemu = get_using_sysemu();
		pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;

		op = singlestepping(NULL) ? PTRACE_SINGLESTEP :
			pt_syscall_parm;

		err = ptrace(op, pid, 0, 0);
		if(err)
			panic("userspace - PTRACE_%s failed, "
			      "errno = %d\n",
			      local_using_sysemu ? "SYSEMU" : "SYSCALL", errno);
	}
}
Example #4
0
long syscall_emu(long call, long arg1, long arg2, long arg3,
                            long arg4, long arg5, long arg6)
{
	long ret;
	switch (call)
	{
 		case __NR_brk:
 		case __NR_mmap2:
 		case __NR_mmap:
 		case __NR_mremap:
 		case __NR_mprotect:
 		case __NR_madvise:

 		case __NR_sigaltstack:
 		case __NR_signal:
 		case __NR_sigaction:
		case __NR_sigreturn:
 		case __NR_rt_sigaction:
		case __NR_rt_sigreturn:

		case __NR_fork:
		case __NR_vfork:
		case __NR_clone:
		case __NR_exit:

		case __NR_execve:
		case __NR_exit_group:
			break;

		case __NR_read:
		case __NR_readv:
		case __NR_open:
		case __NR_creat:
		case __NR_dup:
		case __NR_dup2:
		case __NR_openat:
		case __NR_pipe:
		case __NR_socketcall:
			ret = syscall_intr(call,arg1,arg2,arg3,arg4,arg5,arg6);

			if ( taint_flag == TAINT_ON )
				do_taint(ret,call,arg1,arg2,arg3,arg4,arg5,arg6);

			return ret;

 		case __NR_ipc:
			if ( arg1 == SHMAT )
				break;
			/* fall through */
		default:
			return syscall_intr(call,arg1,arg2,arg3,arg4,arg5,arg6);
	}

	ret = call;
	if (!try_block_signals())
		return ret; /* we have a signal in progress, revert to pre-syscall state */

	switch (call)
	{
		/* these calls are all non-blocking right?
		 * blocked signals during blocking calls is a bad thing
		 */
 		case __NR_brk:
			ret = user_brk(arg1);
			break;
 		case __NR_mmap2:
			ret = user_mmap2(arg1,arg2,arg3,arg4,arg5,arg6);
			break;
 		case __NR_mmap:
			ret = user_old_mmap((struct kernel_mmap_args *)arg1);
			break;
 		case __NR_mremap:
			ret = user_mremap(arg1,arg2,arg3,arg4,arg5);
			break;
 		case __NR_mprotect:
			ret = user_mprotect(arg1,arg2,arg3);
			break;
 		case __NR_madvise:
			ret = user_madvise(arg1,arg2,arg3);
			break;
 		case __NR_ipc:
			if (arg1 == SHMAT)
				ret = user_shmat(arg2,(char *)arg5,arg3,(unsigned long *)arg4);
			else
				die("should not have caught IPC call: %d", arg1);
			break;

 		case __NR_sigaltstack:
			ret = user_sigaltstack((stack_t *)arg1, (stack_t *)arg2);
			break;
 		case __NR_signal:
		{
			ret = (long)user_signal(arg1, (kernel_sighandler_t)arg2);
			break;
		}
 		case __NR_sigaction:
			ret = user_sigaction(arg1, (struct kernel_old_sigaction *)arg2,
			                           (struct kernel_old_sigaction *)arg3);
			break;
 		case __NR_rt_sigaction:
			ret = user_rt_sigaction(arg1, (struct kernel_sigaction *)arg2,
			                              (struct kernel_sigaction *)arg3, arg4);
			break;
 		case __NR_sigreturn:
			user_sigreturn();
			break;
 		case __NR_rt_sigreturn:
			user_rt_sigreturn();
			break;

		case __NR_vfork:
			ret = user_clone(SIGCHLD, 0, NULL, NULL, NULL);
//			ret = user_clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, NULL, NULL);
			break;
		case __NR_fork:
			ret = user_clone(SIGCHLD, 0, NULL, NULL, NULL);
			break;
		case __NR_clone:
			ret = user_clone(arg1, arg2, (void *)arg3, (void *)arg4, (void*)arg5);
			break;
		case __NR_exit:
			user_exit(arg1);
			break;

		case __NR_execve:
			ret = user_execve((char *)arg1, (char **)arg2, (char **)arg3);
			break;
		case __NR_exit_group:
			if (dump_on_exit)
			{
				long regs[] = { call, arg2, arg3, arg1, get_thread_ctx()->user_esp, arg6, arg4, arg5 };
				do_taint_dump(regs);
			}
			sys_exit_group(arg1);
		default:
			die("unimplemented syscall");
			break;
	}
	unblock_signals();
	return ret;
}