[ Pobierz całość w formacie PDF ]
.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {return -ENOEXEC;}current->personality = PER_LINUX;fd_offset = N_TXTOFF(ex);#ifdef __i386__if (N_MAGIC(ex) == ZMAGIC && fd_offset != BLOCK_SIZE) {printk(KERN_NOTICE "N_TXTOFF != BLOCK_SIZE.See a.out.h.\n");return -ENOEXEC;}if (N_MAGIC(ex) == ZMAGIC && ex.a_text &&(fd_offset < bprm->inode->i_sb->s_blocksize)) {printk(KERN_NOTICE "N_TXTOFF < BLOCK_SIZE.Please convert binary.\n");return -ENOEXEC;}#endif/* Check initial limits.This avoids letting people circumvent* size limits imposed on them by creating programs with large* arrays in the data or bss.*/rlim = current->rlim[RLIMIT_DATA].rlim_cur;if (rlim >= RLIM_INFINITY)rlim = ~0;if (ex.a_data + ex.a_bss > rlim)return -ENOMEM;/* OK, This is the point of no return */flush_old_exec(bprm);current->mm->end_code = ex.a_text +(current->mm->start_code = N_TXTADDR(ex));current->mm->end_data = ex.a_data +(current->mm->start_data = N_DATADDR(ex));current->mm->brk = ex.a_bss +(current->mm->start_brk = N_BSSADDR(ex));current->mm->rss = 0;current->mm->mmap = NULL;current->suid = current->euid = current->fsuid = bprm->e_uid;current->sgid = current->egid = current->fsgid = bprm->e_gid;current->flags &= ~PF_FORKNOEXEC;if (N_MAGIC(ex) == OMAGIC) {#ifdef __alpha__do_mmap(NULL, N_TXTADDR(ex) & PAGE_MASK,ex.a_text+ex.a_data + PAGE_SIZE - 1,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_PRIVATE, 0);read_exec(bprm->inode, fd_offset, (char *) N_TXTADDR(ex),ex.a_text+ex.a_data, 0);#elsedo_mmap(NULL, 0, ex.a_text+ex.a_data,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_PRIVATE, 0);read_exec(bprm->inode, 32, (char *) 0, ex.a_text+ex.a_data, 0);#endif} else {if (ex.a_text & 0xfff || ex.a_data & 0xfff)printk(KERN_NOTICE "executable not page aligned\n");fd = open_inode(bprm->inode, O_RDONLY);if (fd < 0)return fd;file = current->files->fd[fd];if (!file->f_op || !file->f_op->mmap) {sys_close(fd);do_mmap(NULL, 0, ex.a_text+ex.a_data,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_PRIVATE, 0);read_exec(bprm->inode, fd_offset,(char *) N_TXTADDR(ex), ex.a_text+ex.a_data, 0);goto beyond_if;}error = do_mmap(file, N_TXTADDR(ex), ex.a_text,PROT_READ | PROT_EXEC,MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,fd_offset);if (error != N_TXTADDR(ex)) {sys_close(fd);send_sig(SIGKILL, current, 0);return error;}error = do_mmap(file, N_DATADDR(ex), ex.a_data,PROT_READ | PROT_WRITE | PROT_EXEC,MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,fd_offset + ex.a_text);sys_close(fd);if (error != N_DATADDR(ex)) {send_sig(SIGKILL, current, 0);return error;}}beyond_if:if (current->exec_domain && current->exec_domain->use_count)(*current->exec_domain->use_count)--;if (current->binfmt && current->binfmt->use_count)(*current->binfmt->use_count)--;current->exec_domain = lookup_exec_domain(current->personality);current->binfmt = &aout_format;if (current->exec_domain && current->exec_domain->use_count)(*current->exec_domain->use_count)++;if (current->binfmt && current->binfmt->use_count)(*current->binfmt->use_count)++;set_brk(current->mm->start_brk, current->mm->brk);p = setup_arg_pages(p, bprm);p = (unsigned long) create_aout_tables((char *)p, bprm);current->mm->start_stack = p;#ifdef __alpha__regs->gp = ex.a_gpvalue;#endifstart_thread(regs, ex.a_entry, p);if (current->flags & PF_PTRACED)send_sig(SIGTRAP, current, 0);return 0;}static intload_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs){int retval;MOD_INC_USE_COUNT;retval = do_load_aout_binary(bprm, regs);MOD_DEC_USE_COUNT;return retval;}static inline intdo_load_aout_library(int fd){struct file * file;struct exec ex;struct inode * inode;unsigned int len;unsigned int bss;unsigned int start_addr;unsigned long error;file = current->files->fd[fd];inode = file->f_inode;if (!file || !file->f_op)return -EACCES;/* Seek into the file */if (file->f_op->lseek) {if ((error = file->f_op->lseek(inode, file, 0, 0)) != 0)return -ENOEXEC;} elsefile->f_pos = 0;set_fs(KERNEL_DS);error = file->f_op->read(inode, file, (char *) &ex, sizeof(ex));set_fs(USER_DS);if (error != sizeof(ex))return -ENOEXEC;/* We come in here for the regular a.out style of shared libraries */if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {return -ENOEXEC;}if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&(N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {printk("N_TXTOFF < BLOCK_SIZE.Please convert library\n");return -ENOEXEC;}if (N_FLAGS(ex)) return -ENOEXEC;/* For QMAGIC, the starting address is 0x20 into the page.We maskthis off to get the starting address for the page */start_addr = ex.a_entry & 0xfffff000;/* Now use mmap to map the library into memory.*/error = do_mmap(file, start_addr, ex.a_text + ex.a_data,PROT_READ | PROT_WRITE | PROT_EXEC,MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,N_TXTOFF(ex));if (error != start_addr)return error;len = PAGE_ALIGN(ex.a_text + ex.a_data);bss = ex.a_text + ex.a_data + ex.a_bss;if (bss > len) {error = do_mmap(NULL, start_addr + len, bss-len,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE|MAP_FIXED, 0);if (error != start_addr + len)return error;}return 0;}static intload_aout_library(int fd){int retval;MOD_INC_USE_COUNT;retval = do_load_aout_library(fd);MOD_DEC_USE_COUNT;return retval;}int init_aout_binfmt(void) {return register_binfmt(&aout_format);}#ifdef MODULEint init_module(void) {return init_aout_binfmt();}void cleanup_module( void) {unregister_binfmt(&aout_format);}#endif
[ Pobierz całość w formacie PDF ]