int main(int argc, char **argv) { void *base; char path[16]; pid_t pid; int fd; pid = getpid(); sprintf(path, "/proc/%d/maps", pid); if ( !(fd = open(path, O_RDONLY))) { fprintf(stderr, "Unable to open %s\n", path); return 1; } base = mmap((void *)0x60000000, VMASIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); printf("\nBase address : 0x%x\n\n", base); read_maps(fd, path, MAPS_NO_CHECK); printf("\nRemapping at 0x70000000...\n\n"); base = real_mremap(base, 0, 0, MREMAP_MAYMOVE | MREMAP_FIXED, (void *)0x70000000); read_maps(fd, path, MAPS_CHECK); printf("\nReport : \n"); (mremap_check) ? printf("This kernel appears to be VULNERABLE\n\n") : printf("This kernel appears to be NOT VULNERABLE\n\n"); close(fd); return 0; }
static void test_read_maps(void) { FILE *fp = fopen("maps.txt", "r"); struct proc_map *result = read_maps(fp, "libc-2.11.1.so"); fclose(fp); assert(result != NULL); assert(0 == result->base); assert(0x00b16000 == result->lo); assert(0x00c69000 == result->hi); struct proc_map *next = result->next; assert(next != NULL); assert(0x00153000 == next->base); assert(0x00c69000 == next->lo); assert(0x00c6a000 == next->hi); next = next->next; assert(next != NULL); assert(0x00153000 == next->base); assert(0x00c6a000 == next->lo); assert(0x00c6c000 == next->hi); next = next->next; assert(next != NULL); assert(0x00155000 == next->base); assert(0x00c6c000 == next->lo); assert(0x00c6d000 == next->hi); unsigned int fake = 0x00b16000 + 0x000f7e30; unsigned int realaddr = get_real_address(result, fake); assert(realaddr == 0x000f7e30); free_maps(result); }
ino_t get_addr_inode(void *p) { char name[256]; int ret; struct stat sb; ret = read_maps((unsigned long)p, name); if (ret < 0) return ret; if (ret == 0) { ERROR("Couldn't find address %p in /proc/self/maps\n", p); return -1; } /* Don't care about non-filenames */ if (name[0] != '/') return 0; /* Truncate the filename portion */ ret = stat(name, &sb); if (ret < 0) { /* Don't care about unlinked files */ if (errno == ENOENT) return 0; ERROR("stat failed: %s\n", strerror(errno)); return -1; } return sb.st_ino; }
/* We define this function standalone, rather than in terms of * hugetlbfs_test_path() so that we can use it without -lhugetlbfs for * testing PRELOAD */ int test_addr_huge(void *p) { char name[256]; char *dirend; int ret; struct statfs64 sb; ret = read_maps((unsigned long)p, name); if (ret < 0) return ret; if (ret == 0) { verbose_printf("Couldn't find address %p in /proc/self/maps\n", p); return -1; } /* looks like a filename? */ if (name[0] != '/') return 0; /* Truncate the filename portion */ dirend = strrchr(name, '/'); if (dirend && dirend > name) { *dirend = '\0'; } ret = statfs64(name, &sb); if (ret) return -1; return (sb.f_type == HUGETLBFS_MAGIC); }
static int arraylong_read (struct inode * inode, struct file * file, char * buf, int count) { unsigned int pid = inode->i_ino >> 16; unsigned int type = inode->i_ino & 0x0000ffff; if (count < 0) return -EINVAL; switch (type) { case PROC_PID_MAPS: return read_maps(pid, file, buf, count); } return -EINVAL; }
void Resources::read_all(const std::string& fdir, ZipReader *fzip, bool base_resource) throw (Exception) { read_tilesets(fdir + "tilesets", fzip, base_resource); read_objects(fdir + "objects", fzip, base_resource); read_charactersets(fdir + "charactersets", fzip, base_resource); read_npcs(fdir + "npcs", fzip, base_resource); read_animations(fdir + "animations", fzip, base_resource); read_maps(fdir + "maps", fzip, base_resource); read_backgrounds(fdir + "backgrounds", fzip, base_resource); read_fonts(fdir + "fonts", fzip, base_resource); read_icons(fdir + "icons", fzip, base_resource); read_sounds(fdir + "sounds", fzip, base_resource); read_musics(fdir + "music", fzip, base_resource); read_game_settings(fdir + "game", fzip, base_resource); }
void read_db() { #ifdef DEBUG_VALUE //char cur_dir[256]; //GetCurrentDirectory(256, cur_dir); //printf("in read_db(): %s\n", cur_dir); #endif GLint charsRead = read_chars(); GLint mapsRead = read_maps(); GLint itemsRead = read_items(); if (charsRead || mapsRead || itemsRead) { exit_glut("Error reading database!"); } }
/* Note that 'init' is a special process: it doesn't get signals it doesn't * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, unsigned long orig_i0, int restart_syscall) { unsigned long signr; siginfo_t info; struct k_sigaction *ka; if (!oldset) oldset = ¤t->blocked; #ifdef CONFIG_SPARC32_COMPAT if (current->thread.flags & SPARC_FLAG_32BIT) { extern asmlinkage int do_signal32(sigset_t *, struct pt_regs *, unsigned long, int); return do_signal32(oldset, regs, orig_i0, restart_syscall); } #endif for (;;) { spin_lock_irq(¤t->sigmask_lock); signr = dequeue_signal(¤t->blocked, &info); spin_unlock_irq(¤t->sigmask_lock); if (!signr) break; if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { /* Do the syscall restart before we let the debugger * look at the child registers. */ if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; restart_syscall = 0; } current->exit_code = signr; current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule(); if (!(signr = current->exit_code)) continue; current->exit_code = 0; if (signr == SIGSTOP) continue; /* Update the siginfo structure. Is this good? */ if (signr != info.si_signo) { info.si_signo = signr; info.si_errno = 0; info.si_code = SI_USER; info.si_pid = current->p_pptr->pid; info.si_uid = current->p_pptr->uid; } /* If the (new) signal is now blocked, requeue it. */ if (sigismember(¤t->blocked, signr)) { send_sig_info(signr, &info, current); continue; } } ka = ¤t->sig->action[signr-1]; if (ka->sa.sa_handler == SIG_IGN) { if (signr != SIGCHLD) continue; /* sys_wait4() grabs the master kernel lock, so * we need not do so, that sucker should be * threaded and would not be that difficult to * do anyways. */ while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) ; continue; } if (ka->sa.sa_handler == SIG_DFL) { unsigned long exit_code = signr; if (current->pid == 1) continue; switch (signr) { case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: continue; case SIGTSTP: case SIGTTIN: case SIGTTOU: if (is_orphaned_pgrp(current->pgrp)) continue; case SIGSTOP: if (current->ptrace & PT_PTRACED) continue; current->state = TASK_STOPPED; current->exit_code = signr; if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) notify_parent(current, SIGCHLD); schedule(); continue; case SIGQUIT: case SIGILL: case SIGTRAP: case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: if (do_coredump(signr, regs)) exit_code |= 0x80; #ifdef DEBUG_SIGNALS /* Very useful to debug the dynamic linker */ printk ("Sig %d going...\n", (int)signr); show_regs (regs); #ifdef DEBUG_SIGNALS_TRACE { struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); unsigned long ins[8]; while (rw && !(((unsigned long) rw) & 0x3)) { copy_from_user(ins, &rw->ins[0], sizeof(ins)); printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]); rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS); } } #endif #ifdef DEBUG_SIGNALS_MAPS printk("Maps:\n"); read_maps(); #endif #endif /* fall through */ default: sig_exit(signr, exit_code, &info); /* NOT REACHED */ } } if (restart_syscall) syscall_restart(orig_i0, regs, &ka->sa); handle_signal(signr, ka, &info, oldset, regs); return 1; } if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } return 0; }
/* * Run a command passed as an argument, * stop when execle + dynamic loading is done * record mapping to further study ASLR */ int run_aslr_tests(int argc, char *argv, char **envp) { int status,s; pid_t child; siginfo_t si; int nmaps = 0; memset(&si, 0, sizeof(siginfo_t)); /* * We run the given command, wait for the * mapping to be done, and read the map */ if ((child = fork()) < 0) { perror("fork:"); exit(-1); } else if (!child) { // child FILE *f=fopen("/dev/zero","r"); // just in case it starts with a read... stdin=f; ptrace(PTRACE_TRACEME, 0, 0, 0); // drop privileges (if any) // setgid(gid); // setuid(uid); execle((char*)argv, (char*)argv, NULL,envp); perror("execle:"); exit(-1); } while (1) { // Wait for an event while (waitpid(child,&status,0) < 0) { if (errno == ECHILD) { printf(" [!!] Child exited\n"); exit(0); } else if (errno == EINTR) { continue; } else { perror("wait:"); exit(-1); } } s=get_syscall(child); //printf("syscall: %d\n",s); if(still_loading(s) || s == -1){ ptrace(PTRACE_SYSCALL, child, 0, 0); // } else if (s == -1){ // usleep(200); // ptrace(PTRACE_SYSCALL, child, 0, 0); // goto done_tracing; }else{ break; } } // read mapping nmaps = read_maps(child); if (debug_flag) printf("Number of maps read for aslr test: %d\n", nmaps); //kill child kill_pid(child); waitpid(child,&status,0); return 0; }
filter_action memory_filter::filter_syscall_exit(pid_data& pdata, process_state& st) { /* Handle the result of a safe memory installation. */ pid_t pid = pdata.pid; enum SYSCALL sys = st.get_syscall(); if(pdata.installing_safe_mem) { if(sys != sys_mmap) { log_error(pid, "installing safe mem but didn't get mmap exit"); return FILTER_KILL_PID; } if(!install_safe_memory_result(pdata, st)) { log_error(pid, "safe memory installation failed"); return FILTER_KILL_PID; } log_info(pid, 2, "safe memory installed"); } if(sys == sys_execve && !st.is_error_result()) { heap_base = heap_end = 0; //max_memory = 0; mappings.clear(); } if(mappings.size() == 0) { mappings = read_maps(st.get_pid(), page_size); if(mappings.size() == 0) { log_error(pid, "could not read memory mappings"); return FILTER_KILL_PID; } } switch(sys) { case sys_brk: { if(!st.is_error_result()) { unsigned long new_heap_end = st.get_result() / page_size; if(!heap_base) { log_info(pid, 4, "got heap base"); heap_base = new_heap_end; } else if(new_heap_end < heap_end) { mappings.rem(new_heap_end, heap_end); } else { mappings.add(heap_end, new_heap_end); } heap_end = new_heap_end; } } break; case sys_mmap: { if(!st.is_error_result()) { unsigned long map_base = st.get_result() / page_size; unsigned long map_len = st.get_param(1) / page_size; mappings.add(map_base, map_base + map_len); } } break; case sys_munmap: { if(!st.is_error_result()) { unsigned long map_base = st.get_param(0) / page_size; unsigned long map_len = st.get_param(1) / page_size; mappings.rem(map_base, map_base + map_len); } } break; default: break; } max_memory = std::max(max_memory, mappings.size()); if(!get_passive() && get_mem() && max_memory * page_size > get_mem() * 1024UL) { log_violation(pid, "memory limit exceeded"); return FILTER_KILL_PID; } return FILTER_NO_ACTION; }