static int ptrace_child(void *arg) { int ret; int pid = os_getpid(), ppid = getppid(); int sc_result; if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ perror("ptrace"); os_kill_process(pid, 0); } os_stop_process(pid); /*This syscall will be intercepted by the parent. Don't call more than * once, please.*/ sc_result = os_getpid(); if (sc_result == pid) ret = 1; /*Nothing modified by the parent, we are running normally.*/ else if (sc_result == ppid) ret = 0; /*Expected in check_ptrace and check_sysemu when they succeed in modifying the stack frame*/ else ret = 2; /*Serious trouble! This could be caused by a bug in host 2.6 SKAS3/2.6 patch before release -V6, together with a bug in the UML code itself.*/ _exit(ret); }
void initial_thread_cb_tt(void (*proc)(void *), void *arg) { if(os_getpid() == tracing_pid){ (*proc)(arg); } else { current->thread.request.op = OP_CB; current->thread.request.u.cb.proc = proc; current->thread.request.u.cb.arg = arg; os_usr1_process(os_getpid()); change_sig(SIGUSR1, 1); change_sig(SIGUSR1, 0); } }
static int exec_tramp(void *sig_stack) { init_new_thread_stack(sig_stack, NULL); init_new_thread_signals(); os_stop_process(os_getpid()); return(0); }
static void kill_off_processes(void) { CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas()); #ifdef CONFIG_SMP kill_idlers(os_getpid()); #endif }
static void daemon_user_init(void *data, void *dev) { struct daemon_data *pri = data; struct timeval tv; struct { char zero; int pid; int usecs; } name; if(!strcmp(pri->sock_type, "unix")) pri->ctl_addr = new_addr(pri->ctl_sock, strlen(pri->ctl_sock) + 1); name.zero = 0; name.pid = os_getpid(); gettimeofday(&tv, NULL); name.usecs = tv.tv_usec; pri->local_addr = new_addr(&name, sizeof(name)); pri->dev = dev; pri->fd = connect_to_switch(pri); if(pri->fd < 0){ kfree(pri->local_addr); pri->local_addr = NULL; } }
void release_thread_tt(struct task_struct *task) { int pid = task->thread.mode.tt.extern_pid; if(os_getpid() != pid) os_kill_process(pid, 0); }
int is_skas_winch(int pid, int fd, void *data) { if(pid != os_getpid()) return(0); register_winch_irq(-1, fd, -1, data); return(1); }
static int userspace_tramp(void *arg) { init_new_thread_signals(0); enable_timer(); ptrace(PTRACE_TRACEME, 0, 0, 0); os_stop_process(os_getpid()); return(0); }
int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct * p, struct pt_regs *regs) { int (*tramp)(void *); int new_pid, err; unsigned long stack; if(current->thread.forking) tramp = fork_tramp; else { tramp = new_thread_proc; p->thread.request.u.thread = current->thread.request.u.thread; } err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1); if(err < 0){ printk("copy_thread : pipe failed, err = %d\n", -err); return(err); } stack = alloc_stack(0, 0); if(stack == 0){ printk(KERN_ERR "copy_thread : failed to allocate " "temporary stack\n"); return(-ENOMEM); } clone_flags &= CLONE_VM; p->thread.temp_stack = stack; new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp); if(new_pid < 0){ printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", -new_pid); return(new_pid); } if(current->thread.forking){ sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(®s->regs)); SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; } p->thread.mode.tt.extern_pid = new_pid; current->thread.request.op = OP_FORK; current->thread.request.u.fork.pid = new_pid; os_usr1_process(os_getpid()); /* Enable the signal and then disable it to ensure that it is handled * here, and nowhere else. */ change_sig(SIGUSR1, 1); change_sig(SIGUSR1, 0); err = 0; return(err); }
void forward_ipi(int fd, int pid) { int err; err = os_set_owner(fd, pid); if(err < 0) printk("forward_ipi: set_owner failed, fd = %d, me = %d, " "target = %d, err = %d\n", fd, os_getpid(), pid, -err); }
void switch_to_tt(void *prev, void *next) { struct task_struct *from, *to, *prev_sched; unsigned long flags; int err, vtalrm, alrm, prof, cpu; char c; from = prev; to = next; cpu = from->thread_info->cpu; if(cpu == 0) forward_interrupts(to->thread.mode.tt.extern_pid); #ifdef CONFIG_SMP forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid); #endif local_irq_save(flags); vtalrm = change_sig(SIGVTALRM, 0); alrm = change_sig(SIGALRM, 0); prof = change_sig(SIGPROF, 0); forward_pending_sigio(to->thread.mode.tt.extern_pid); c = 0; err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); /* If the process that we have just scheduled away from has exited, * then it needs to be killed here. The reason is that, even though * it will kill itself when it next runs, that may be too late. Its * stack will be freed, possibly before then, and if that happens, * we have a use-after-free situation. So, it gets killed here * in case it has not already killed itself. */ prev_sched = current->thread.prev_sched; if(prev_sched->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); change_sig(SIGVTALRM, vtalrm); change_sig(SIGALRM, alrm); change_sig(SIGPROF, prof); arch_switch(); flush_tlb_all(); local_irq_restore(flags); }
static int signal_tramp(void *arg) { int (*proc)(void *); if(honeypot && munmap((void *) (host_task_size - 0x10000000), 0x10000000)) panic("Unmapping stack failed"); if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) panic("ptrace PTRACE_TRACEME failed"); os_stop_process(os_getpid()); change_sig(SIGWINCH, 0); signal(SIGUSR1, SIG_IGN); change_sig(SIGCHLD, 0); signal(SIGSEGV, (__sighandler_t) sig_handler); set_cmdline("(idle thread)"); set_init_pid(os_getpid()); proc = arg; return((*proc)(NULL)); }
static void fix_range(struct mm_struct *mm, unsigned long start_addr, unsigned long end_addr, int force) { if((current->thread.mode.tt.extern_pid != -1) && (current->thread.mode.tt.extern_pid != os_getpid())) panic("fix_range fixing wrong address space, current = 0x%p", current); fix_range_common(mm, start_addr, end_addr, force, 0, do_ops); }
void suspend_new_thread(int fd) { int err; char c; os_stop_process(os_getpid()); err = os_read_file(fd, &c, sizeof(c)); if(err != sizeof(c)) panic("read failed in suspend_new_thread, err = %d", -err); }
int fork_tramp(void *stack) { local_irq_disable(); arch_init_thread(); init_new_thread_stack(stack, finish_fork_handler); os_usr1_process(os_getpid()); change_sig(SIGUSR1, 1); return(0); }
static int __init start_kernel_proc(void *unused) { int pid; block_signals(); pid = os_getpid(); cpu_tasks[0].pid = pid; cpu_tasks[0].task = current; #ifdef CONFIG_SMP <<<<<<< HEAD
int set_user_mode(void *t) { struct task_struct *task; task = t ? t : current; if(task->thread.mode.tt.tracing) return(1); task->thread.request.op = OP_TRACE_ON; os_usr1_process(os_getpid()); return(0); }
int outer_tramp(void *arg) { struct tramp *t; int sig = sigkill; t = arg; t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2, t->flags, t->tramp_data); if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); kill(os_getpid(), sig); _exit(0); }
void kill_off_processes_tt(void) { struct task_struct *p; int me; me = os_getpid(); for_each_process(p){ if(p->thread.mode.tt.extern_pid != me) os_kill_process(p->thread.mode.tt.extern_pid, 0); } if(init_task.thread.mode.tt.extern_pid != me) os_kill_process(init_task.thread.mode.tt.extern_pid, 0); }
static void ptrace_child(void) { int ret; /* Calling os_getpid because some libcs cached getpid incorrectly */ int pid = os_getpid(), ppid = getppid(); int sc_result; if (change_sig(SIGWINCH, 0) < 0 || ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { perror("ptrace"); kill(pid, SIGKILL); } kill(pid, SIGSTOP); /* * This syscall will be intercepted by the parent. Don't call more than * once, please. */ sc_result = os_getpid(); if (sc_result == pid) /* Nothing modified by the parent, we are running normally. */ ret = 1; else if (sc_result == ppid) /* * Expected in check_ptrace and check_sysemu when they succeed * in modifying the stack frame */ ret = 0; else /* Serious trouble! This could be caused by a bug in host 2.6 * SKAS3/2.6 patch before release -V6, together with a bug in * the UML code itself. */ ret = 2; exit(ret); }
static int start_kernel_proc(void *unused) { int pid; block_signals(); pid = os_getpid(); cpu_tasks[0].pid = pid; cpu_tasks[0].task = current; #ifdef CONFIG_SMP cpu_online_map = cpumask_of_cpu(0); #endif start_kernel(); return(0); }
void release_thread_tt(struct task_struct *task) { int pid = task->thread.mode.tt.extern_pid; /* * We first have to kill the other process, before * closing its switch_pipe. Else it might wake up * and receive "EOF" before we could kill it. */ if(os_getpid() != pid) os_kill_process(pid, 0); os_close_file(task->thread.mode.tt.switch_pipe[0]); os_close_file(task->thread.mode.tt.switch_pipe[1]); /* use switch_pipe as flag: thread is released */ task->thread.mode.tt.switch_pipe[0] = -1; }
void kill_off_processes_skas(void) { if(proc_mm) #warning need to loop over userspace_pids in kill_off_processes_skas os_kill_ptraced_process(userspace_pid[0], 1); else { struct task_struct *p; int pid, me; me = os_getpid(); for_each_process(p){ if(p->mm == NULL) continue; pid = p->mm->context.skas.id.u.pid; os_kill_ptraced_process(pid, 1); } } }
static int helper_child(void *arg) { struct helper_data *data = arg; char **argv = data->argv; int errval; if(helper_pause){ signal(SIGHUP, helper_hup); pause(); } if(data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); execvp(argv[0], argv); errval = errno; printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); os_write_file(data->fd, &errval, sizeof(errval)); os_kill_process(os_getpid(), 0); return(0); }
void segv_handler(int sig, union uml_pt_regs *regs) { int index, max; struct faultinfo * fi = UPT_FAULTINFO(regs); if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){ bad_segv(*fi, UPT_IP(regs)); return; } max = sizeof(segfault_record)/sizeof(segfault_record[0]); index = next_trap_index(max); nsegfaults++; segfault_record[index].address = FAULT_ADDRESS(*fi); segfault_record[index].pid = os_getpid(); segfault_record[index].is_write = FAULT_WRITE(*fi); segfault_record[index].sp = UPT_SP(regs); segfault_record[index].is_user = UPT_IS_USER(regs); segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs); }
static void kill_off_processes(void) { if (proc_mm) /* * FIXME: need to loop over userspace_pids */ os_kill_ptraced_process(userspace_pid[0], 1); else { struct task_struct *p; int pid, me; me = os_getpid(); for_each_process(p) { if (p->mm == NULL) continue; pid = p->mm->context.id.u.pid; os_kill_ptraced_process(pid, 1); } } }
static void __init check_sysemu(void) { void *stack; int pid, n, status; printk("Checking syscall emulation patch for ptrace..."); sysemu_supported = 0; pid = start_ptraced_child(&stack); if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if (n < 0) panic("check_sysemu : wait failed, errno = %d", errno); if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) panic("check_sysemu : expected SIGTRAP, " "got status = %d", status); n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if(n < 0) panic("check_sysemu : failed to modify system " "call return, errno = %d", errno); if (stop_ptraced_child(pid, stack, 0, 0) < 0) goto fail_stopped; sysemu_supported = 1; printk("OK\n"); set_using_sysemu(!force_sysemu_disabled); return; fail: stop_ptraced_child(pid, stack, 1, 0); fail_stopped: sysemu_supported = 0; printk("missing\n"); }
/*! *@brief 通过outpath、outname和提供的构造后缀名称创建文件 *@author zhaohm3 *@param[in] szPostfix 文件后缀名称 *@param[out] szFileName 文件名,用于输出 *@retval 创建$(outpath)/$(outname)_pid_$(pid).$(szPostfix)文件 *@note * *@since 2014-9-25 14:27 *@attention * */ GPrivate FILE* file_open_fpostfix(String_t szPostfix, String_t szFileName) { FILE *pFile = NULL; String_t szOutpath = agentargs_get_outpath(); String_t szOutname = agentargs_get_outname(); os_sprintf(szFileName, "%s%s%s_pid_%d.%s", (szOutpath != NULL) ? szOutpath : "", (szOutpath != NULL) ? "/" : "", (szOutname != NULL) ? szOutname : "gcmon", os_getpid(), (szPostfix != NULL) ? szPostfix : "unknown"); pFile = os_fopen(szFileName, "w+"); if (NULL == pFile) { szFileName[0] = '\0'; } return pFile; }
static int __init create_pid_file(void) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")]; int fd, n; if(umid_file_name("pid", file, sizeof(file))) return 0; fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 0644); if(fd < 0){ printf("Open of machine pid file \"%s\" failed: %s\n", file, strerror(-fd)); return 0; } sprintf(pid, "%d\n", os_getpid()); n = os_write_file(fd, pid, strlen(pid)); if(n != strlen(pid)) printf("Write of pid file failed - err = %d\n", -n); os_close_file(fd); return 0; }
static int new_thread_proc(void *stack) { /* local_irq_disable is needed to block out signals until this thread is * properly scheduled. Otherwise, the tracing thread will get mighty * upset about any signals that arrive before that. * This has the complication that it sets the saved signal mask in * the sigcontext to block signals. This gets restored when this * thread (or a descendant, since they get a copy of this sigcontext) * returns to userspace. * So, this is compensated for elsewhere. * XXX There is still a small window until local_irq_disable() actually * finishes where signals are possible - shouldn't be a problem in * practice since SIGIO hasn't been forwarded here yet, and the * local_irq_disable should finish before a SIGVTALRM has time to be * delivered. */ local_irq_disable(); init_new_thread_stack(stack, new_thread_handler); os_usr1_process(os_getpid()); change_sig(SIGUSR1, 1); return(0); }