static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, struct pt_regs *from, unsigned long sp) { return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), sizeof(*fp), sp), copy_sc_to_user_skas(to, fp, from, sp)); }
static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, struct pt_regs *from) { return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), sizeof(*fp)), copy_sc_to_user_skas(to, fp, from))); }
static void kill_off_processes(void) { CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas()); #ifdef CONFIG_SMP kill_idlers(os_getpid()); #endif }
void do_boot_timer_handler(struct sigcontext * sc) { struct pt_regs regs; CHOOSE_MODE((void) (UPT_SC(®s.regs) = sc), (void) (regs.regs.skas.is_user = 0)); do_timer(®s); }
static int copy_sc_from_user(struct pt_regs *to, void *from, struct arch_frame_data *arch) { int ret; ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch), copy_sc_from_user_skas(&to->regs, from)); return(ret); }
static int copy_sc_from_user(struct pt_regs *to, void __user *from) { int ret; ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, sizeof(struct _fpstate)), copy_sc_from_user_skas(to, from)); return ret; }
static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, struct arch_frame_data *arch) { return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), arch), copy_sc_to_user_skas(userspace_pid[0], to, fp, &from->regs, current->thread.cr2, current->thread.err))); }
void timer_handler(int sig, union uml_pt_regs *regs) { local_irq_disable(); irq_enter(); update_process_times(CHOOSE_MODE( (UPT_SC(regs) && user_context(UPT_SP(regs))), (regs)->skas.is_user)); irq_exit(); local_irq_enable(); if(current_thread->cpu == 0) timer_irq(regs); }
static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error) { siginfo_t info; struct k_sigaction *ka; int err, sig; if (!oldset) oldset = ¤t->blocked; sig = get_signal_to_deliver(&info, regs, NULL); if(sig == 0) return(0); /* Whee! Actually deliver the signal. */ ka = ¤t->sig->action[sig -1 ]; err = handle_signal(regs, sig, ka, &info, oldset, error); if(!err) return(1); /* Did we come from a system call? */ if(PT_REGS_SYSCALL_NR(regs) >= 0){ /* Restart the system call - no handlers present */ if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND || PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS || PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){ PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); PT_REGS_RESTART_SYSCALL(regs); } else if(PT_REGS_SYSCALL_RET(regs) == -ERESTART_RESTARTBLOCK){ PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall; PT_REGS_RESTART_SYSCALL(regs); } } /* This closes a way to execute a system call on the host. If * you set a breakpoint on a system call instruction and singlestep * from it, the tracing thread used to PTRACE_SINGLESTEP the process * rather than PTRACE_SYSCALL it, allowing the system call to execute * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ if((current->ptrace & PT_DTRACE) && is_syscall(PT_REGS_IP(¤t->thread.regs))) (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0); return(0); }
static int show_cpuinfo(struct seq_file *m, void *v) { int index = 0; #ifdef CONFIG_SMP index = (struct cpuinfo_um *) v - cpu_data; if (!cpu_online(index)) return 0; #endif seq_printf(m, "processor\t: %d\n", index); seq_printf(m, "vendor_id\t: User Mode Linux\n"); seq_printf(m, "model name\t: UML\n"); seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas")); seq_printf(m, "host\t\t: %s\n", host_info); seq_printf(m, "bogomips\t: %lu.%02lu\n\n", loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ)) % 100); return(0); }
void set_cmdline(char *cmd) { #ifdef CONFIG_MODE_TT char *umid, *ptr; if(CHOOSE_MODE(honeypot, 0)) return; umid = get_umid(1); if(umid != NULL){ snprintf(argv1_begin, (argv1_end - argv1_begin) * sizeof(*ptr), "(%s) ", umid); ptr = &argv1_begin[strlen(argv1_begin)]; } else ptr = argv1_begin; snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd); memset(argv1_begin + strlen(argv1_begin), '\0', argv1_end - argv1_begin - strlen(argv1_begin)); #endif }
int not_dead_yet(char *dir) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")], *end; int dead, fd, p, n; sprintf(file, "%s/pid", dir); dead = 0; fd = os_open_file(file, of_read(OPENFLAGS()), 0); if(fd < 0){ if(fd != -ENOENT){ printk("not_dead_yet : couldn't open pid file '%s', " "err = %d\n", file, -fd); return(1); } dead = 1; } if(fd > 0){ n = os_read_file(fd, pid, sizeof(pid)); if(n < 0){ printk("not_dead_yet : couldn't read pid file '%s', " "err = %d\n", file, -n); return(1); } p = strtoul(pid, &end, 0); if(end == pid){ printk("not_dead_yet : couldn't parse pid file '%s', " "errno = %d\n", file, errno); dead = 1; } if(((kill(p, 0) < 0) && (errno == ESRCH)) || (p == CHOOSE_MODE(tracing_pid, os_getpid()))) dead = 1; } if(!dead) return(1); return(actually_do_remove(dir)); }
int linux_main(int argc, char **argv) { unsigned long avail, diff; unsigned long virtmem_size, max_physmem; unsigned int i, add; for (i = 1; i < argc; i++){ if((i == 1) && (argv[i][0] == ' ')) continue; add = 1; uml_checksetup(argv[i], &add); if(add) add_arg(saved_command_line, argv[i]); } if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE); mode_tt = force_tt ? 1 : !can_do_skas(); #ifndef CONFIG_MODE_TT if (mode_tt) { /*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So, * can_do_skas() returned 0, and the message is correct. */ printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n"); exit(1); } #endif uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, &host_task_size, &task_size); /* Need to check this early because mmapping happens before the * kernel is running. */ check_tmpexec(); brk_start = (unsigned long) sbrk(0); CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); /* Increase physical memory size for exec-shield users so they actually get what they asked for. This should add zero for non-exec shield users */ diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); if(diff > 1024 * 1024){ printf("Adding %ld bytes to physical memory to account for " "exec-shield gap\n", diff); physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); } uml_physmem = uml_start; /* Reserve up to 4M after the current brk */ uml_reserved = ROUND_4M(brk_start) + (1 << 22); setup_machinename(system_utsname.machine); #ifdef CONFIG_MODE_TT argv1_begin = argv[1]; argv1_end = &argv[1][strlen(argv[1])]; #endif highmem = 0; iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; /* Zones have to begin on a 1 << MAX_ORDER page boundary, * so this makes sure that's true for highmem */ max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); if(physmem_size + iomem_size > max_physmem){ highmem = physmem_size + iomem_size - max_physmem; physmem_size -= highmem; #ifndef CONFIG_HIGHMEM highmem = 0; printf("CONFIG_HIGHMEM not enabled - physical memory shrunk " "to %ld bytes\n", physmem_size); #endif } high_physmem = uml_physmem + physmem_size; end_iomem = high_physmem + iomem_size; high_memory = (void *) end_iomem; start_vm = VMALLOC_START; setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); if(init_maps(physmem_size, iomem_size, highmem)){ printf("Failed to allocate mem_map for %ld bytes of physical " "memory and %ld bytes of highmem\n", physmem_size, highmem); exit(1); } virtmem_size = physmem_size; avail = get_kmem_end() - start_vm; if(physmem_size > avail) virtmem_size = avail; end_vm = start_vm + virtmem_size; if(virtmem_size < physmem_size) printf("Kernel virtual memory size shrunk to %ld bytes\n", virtmem_size); uml_postsetup(); task_protections((unsigned long) &init_thread_info); os_flush_stdout(); return(CHOOSE_MODE(start_uml_tt(), start_uml_skas())); }
void usr2_handler(int sig, union uml_pt_regs *regs) { CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0); }
void flush_tlb_kernel_vm(void) { CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas()); }
void force_flush_all(void) { CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas()); }
void flush_thread(void) { CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); }
void machine_power_off(void) { do_uml_exitcalls(); kill_off_processes(); CHOOSE_MODE(halt_tt(), halt_skas()); }
void machine_restart(char * __unused) { do_uml_exitcalls(); kill_off_processes(); CHOOSE_MODE(reboot_tt(), reboot_skas()); }
void flush_thread(void) { arch_flush_thread(¤t->thread.arch); CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); }
int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) { struct dog_data data; int in_fds[2], out_fds[2], pid, n, err; char pid_buf[sizeof("nnnnn\0")], c; char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL }; char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, NULL }; char **args = NULL; err = os_pipe(in_fds, 1, 0); if(err < 0){ printk("harddog_open - os_pipe failed, err = %d\n", -err); goto out; } err = os_pipe(out_fds, 1, 0); if(err < 0){ printk("harddog_open - os_pipe failed, err = %d\n", -err); goto out_close_in; } data.stdin = out_fds[0]; data.stdout = in_fds[1]; data.close_me[0] = out_fds[1]; data.close_me[1] = in_fds[0]; if(sock != NULL){ mconsole_args[2] = sock; args = mconsole_args; } else { /* XXX The os_getpid() is not SMP correct */ sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid())); args = pid_args; } pid = run_helper(pre_exec, &data, args, NULL); os_close_file(out_fds[0]); os_close_file(in_fds[1]); if(pid < 0){ err = -pid; printk("harddog_open - run_helper failed, errno = %d\n", -err); goto out_close_out; } n = os_read_file(in_fds[0], &c, sizeof(c)); if(n == 0){ printk("harddog_open - EOF on watchdog pipe\n"); helper_wait(pid); err = -EIO; goto out_close_out; } else if(n < 0){ printk("harddog_open - read of watchdog pipe failed, " "err = %d\n", -n); helper_wait(pid); err = n; goto out_close_out; } *in_fd_ret = in_fds[0]; *out_fd_ret = out_fds[1]; return 0; out_close_in: os_close_file(in_fds[0]); os_close_file(in_fds[1]); out_close_out: os_close_file(out_fds[0]); os_close_file(out_fds[1]); out: return err; }