X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fbinfmt_elf.c;h=479ee5fde69ed6cb1fc64301b682e92ab68e3e57;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=86a271554614537481f706012deb3ac08d576553;hpb=567f20a20be06ad546b5962340c4be268462055b;p=linux-2.6.git diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 86a271554..479ee5fde 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include @@ -47,9 +45,10 @@ #include #include +#include -static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); -static int load_elf_library(struct file *); +static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs); +static int load_elf_library(struct file*); static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long); extern int dump_fpu (struct pt_regs *, elf_fpregset_t *); @@ -62,15 +61,15 @@ extern int dump_fpu (struct pt_regs *, elf_fpregset_t *); * don't even try. */ #if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) -static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file); +static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file); #else #define elf_core_dump NULL #endif #if ELF_EXEC_PAGESIZE > PAGE_SIZE -#define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE +# define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE #else -#define ELF_MIN_ALIGN PAGE_SIZE +# define ELF_MIN_ALIGN PAGE_SIZE #endif #ifndef ELF_CORE_EFLAGS @@ -89,7 +88,7 @@ static struct linux_binfmt elf_format = { .min_coredump = ELF_EXEC_PAGESIZE }; -#define BAD_ADDR(x) ((unsigned long)(x) >= PAGE_MASK) +#define BAD_ADDR(x) ((unsigned long)(x) >= PAGE_MASK) static int set_brk(unsigned long start, unsigned long end) { @@ -107,11 +106,13 @@ static int set_brk(unsigned long start, unsigned long end) return 0; } + /* We need to explicitly zero any fractional pages after the data section (i.e. bss). This would contain the junk from the file that should not - be in memory - */ + be in memory */ + + static int padzero(unsigned long elf_bss) { unsigned long nbyte; @@ -130,9 +131,7 @@ static int padzero(unsigned long elf_bss) #define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) + (items)) #define STACK_ROUND(sp, items) \ ((15 + (unsigned long) ((sp) + (items))) &~ 15UL) -#define STACK_ALLOC(sp, len) ({ \ - elf_addr_t __user *old_sp = (elf_addr_t __user *)sp; sp += len; \ - old_sp; }) +#define STACK_ALLOC(sp, len) ({ elf_addr_t __user *old_sp = (elf_addr_t __user *)sp; sp += len; old_sp; }) #else #define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) - (items)) #define STACK_ROUND(sp, items) \ @@ -141,7 +140,7 @@ static int padzero(unsigned long elf_bss) #endif static int -create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, +create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, int interp_aout, unsigned long load_addr, unsigned long interp_load_addr) { @@ -164,6 +163,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, * for userspace to get any other way, in others (i386) it is * merely difficult. */ + u_platform = NULL; if (k_platform) { size_t len = strlen(k_platform) + 1; @@ -173,7 +173,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, * evictions by the processes running on the same package. One * thing we can do is to shuffle the initial stack for them. */ - + p = arch_align_stack(p); u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); @@ -182,12 +182,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, } /* Create the ELF interpreter info */ - elf_info = (elf_addr_t *)current->mm->saved_auxv; + elf_info = (elf_addr_t *) current->mm->saved_auxv; #define NEW_AUX_ENT(id, val) \ - do { \ - elf_info[ei_index++] = id; \ - elf_info[ei_index++] = val; \ - } while (0) + do { elf_info[ei_index++] = id; elf_info[ei_index++] = val; } while (0) #ifdef ARCH_DLINFO /* @@ -200,22 +197,21 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, NEW_AUX_ENT(AT_PAGESZ, ELF_EXEC_PAGESIZE); NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC); NEW_AUX_ENT(AT_PHDR, load_addr + exec->e_phoff); - NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr)); + NEW_AUX_ENT(AT_PHENT, sizeof (struct elf_phdr)); NEW_AUX_ENT(AT_PHNUM, exec->e_phnum); NEW_AUX_ENT(AT_BASE, interp_load_addr); NEW_AUX_ENT(AT_FLAGS, 0); NEW_AUX_ENT(AT_ENTRY, exec->e_entry); - NEW_AUX_ENT(AT_UID, tsk->uid); - NEW_AUX_ENT(AT_EUID, tsk->euid); - NEW_AUX_ENT(AT_GID, tsk->gid); - NEW_AUX_ENT(AT_EGID, tsk->egid); - NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); + NEW_AUX_ENT(AT_UID, (elf_addr_t) tsk->uid); + NEW_AUX_ENT(AT_EUID, (elf_addr_t) tsk->euid); + NEW_AUX_ENT(AT_GID, (elf_addr_t) tsk->gid); + NEW_AUX_ENT(AT_EGID, (elf_addr_t) tsk->egid); + NEW_AUX_ENT(AT_SECURE, (elf_addr_t) security_bprm_secureexec(bprm)); if (k_platform) { - NEW_AUX_ENT(AT_PLATFORM, - (elf_addr_t)(unsigned long)u_platform); + NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(unsigned long)u_platform); } if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { - NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); + NEW_AUX_ENT(AT_EXECFD, (elf_addr_t) bprm->interp_data); } #undef NEW_AUX_ENT /* AT_NULL is zero; clear the rest too */ @@ -238,7 +234,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, /* Point sp at the lowest address on the stack */ #ifdef CONFIG_STACK_GROWSUP sp = (elf_addr_t __user *)bprm->p - items - ei_index; - bprm->exec = (unsigned long)sp; /* XXX: PARISC HACK */ + bprm->exec = (unsigned long) sp; /* XXX: PARISC HACK */ #else sp = (elf_addr_t __user *)bprm->p; #endif @@ -291,8 +287,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, #ifndef elf_map static unsigned long elf_map(struct file *filep, unsigned long addr, - struct elf_phdr *eppnt, int prot, int type, - unsigned long total_size) + struct elf_phdr *eppnt, int prot, int type, + unsigned long total_size) { unsigned long map_addr; unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr); @@ -307,14 +303,15 @@ static unsigned long elf_map(struct file *filep, unsigned long addr, return addr; down_write(¤t->mm->mmap_sem); + /* - * total_size is the size of the ELF (interpreter) image. - * The _first_ mmap needs to know the full size, otherwise - * randomization might put this image into an overlapping - * position with the ELF binary image. (since size < total_size) - * So we first map the 'big' image - and unmap the remainder at - * the end. (which unmap is needed for ELF images with holes.) - */ + * total_size is the size of the ELF (interpreter) image. + * The _first_ mmap needs to know the full size, otherwise + * randomization might put this image into an overlapping + * position with the ELF binary image. (since size < total_size) + * So we first map the 'big' image - and unmap the remainder at + * the end. (which unmap is needed for ELF images with holes.) + */ if (total_size) { total_size = ELF_PAGEALIGN(total_size); map_addr = do_mmap(filep, addr, total_size, prot, type, off); @@ -324,7 +321,8 @@ static unsigned long elf_map(struct file *filep, unsigned long addr, map_addr = do_mmap(filep, addr, size, prot, type, off); up_write(¤t->mm->mmap_sem); - return(map_addr); + + return map_addr; } #endif /* !elf_map */ @@ -353,9 +351,10 @@ static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) is only provided so that we can read a.out libraries that have an ELF header */ -static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, - struct file *interpreter, unsigned long *interp_map_addr, - unsigned long no_base) +static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, + struct file * interpreter, + unsigned long *interp_map_addr, + unsigned long no_base) { struct elf_phdr *elf_phdata; struct elf_phdr *eppnt; @@ -386,15 +385,15 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, goto out; /* Now read in all of the header information */ + size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum; if (size > ELF_MIN_ALIGN) goto out; - elf_phdata = kmalloc(size, GFP_KERNEL); + elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL); if (!elf_phdata) goto out; - retval = kernel_read(interpreter, interp_elf_ex->e_phoff, - (char *)elf_phdata,size); + retval = kernel_read(interpreter,interp_elf_ex->e_phoff,(char *)elf_phdata,size); error = -EIO; if (retval != size) { if (retval < 0) @@ -407,70 +406,63 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, goto out_close; eppnt = elf_phdata; - for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { - if (eppnt->p_type == PT_LOAD) { - int elf_type = MAP_PRIVATE | MAP_DENYWRITE; - int elf_prot = 0; - unsigned long vaddr = 0; - unsigned long k, map_addr; - - if (eppnt->p_flags & PF_R) - elf_prot = PROT_READ; - if (eppnt->p_flags & PF_W) - elf_prot |= PROT_WRITE; - if (eppnt->p_flags & PF_X) - elf_prot |= PROT_EXEC; - vaddr = eppnt->p_vaddr; - if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) - elf_type |= MAP_FIXED; - else if (no_base && interp_elf_ex->e_type == ET_DYN) - load_addr = -vaddr; - - map_addr = elf_map(interpreter, load_addr + vaddr, - eppnt, elf_prot, elf_type, total_size); - total_size = 0; - if (!*interp_map_addr) - *interp_map_addr = map_addr; - error = map_addr; - if (BAD_ADDR(map_addr)) - goto out_close; - - if (!load_addr_set && - interp_elf_ex->e_type == ET_DYN) { - load_addr = map_addr - ELF_PAGESTART(vaddr); - load_addr_set = 1; - } - - /* - * Check to see if the section's size will overflow the - * allowed task size. Note that p_filesz must always be - * <= p_memsize so it's only necessary to check p_memsz. - */ - k = load_addr + eppnt->p_vaddr; - if (BAD_ADDR(k) || - eppnt->p_filesz > eppnt->p_memsz || - eppnt->p_memsz > TASK_SIZE || - TASK_SIZE - eppnt->p_memsz < k) { - error = -ENOMEM; - goto out_close; - } - - /* - * Find the end of the file mapping for this phdr, and - * keep track of the largest address we see for this. - */ - k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; - if (k > elf_bss) - elf_bss = k; - - /* - * Do the same thing for the memory mapping - between - * elf_bss and last_bss is the bss section. - */ - k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; - if (k > last_bss) - last_bss = k; - } + for (i=0; ie_phnum; i++, eppnt++) { + if (eppnt->p_type == PT_LOAD) { + int elf_type = MAP_PRIVATE | MAP_DENYWRITE; + int elf_prot = 0; + unsigned long vaddr = 0; + unsigned long k, map_addr; + + if (eppnt->p_flags & PF_R) elf_prot = PROT_READ; + if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; + if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; + vaddr = eppnt->p_vaddr; + if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) + elf_type |= MAP_FIXED; + else if (no_base && interp_elf_ex->e_type == ET_DYN) + load_addr = -vaddr; + + map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type, total_size); + total_size = 0; + if (!*interp_map_addr) + *interp_map_addr = map_addr; + error = map_addr; + if (BAD_ADDR(map_addr)) + goto out_close; + + if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { + load_addr = map_addr - ELF_PAGESTART(vaddr); + load_addr_set = 1; + } + + /* + * Check to see if the section's size will overflow the + * allowed task size. Note that p_filesz must always be + * <= p_memsize so it is only necessary to check p_memsz. + */ + k = load_addr + eppnt->p_vaddr; + if (BAD_ADDR(k) || eppnt->p_filesz > eppnt->p_memsz || + eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) { + error = -ENOMEM; + goto out_close; + } + + /* + * Find the end of the file mapping for this phdr, and keep + * track of the largest address we see for this. + */ + k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; + if (k > elf_bss) + elf_bss = k; + + /* + * Do the same thing for the memory mapping - between + * elf_bss and last_bss is the bss section. + */ + k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; + if (k > last_bss) + last_bss = k; + } } /* @@ -484,8 +476,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, goto out_close; } - /* What we have mapped so far */ - elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); + elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); /* What we have mapped so far */ /* Map the last of the bss segment */ if (last_bss > elf_bss) { @@ -504,8 +495,8 @@ out: return error; } -static unsigned long load_aout_interp(struct exec *interp_ex, - struct file *interpreter) +static unsigned long load_aout_interp(struct exec * interp_ex, + struct file * interpreter) { unsigned long text_data, elf_entry = ~0UL; char __user * addr; @@ -524,7 +515,7 @@ static unsigned long load_aout_interp(struct exec *interp_ex, case ZMAGIC: case QMAGIC: offset = N_TXTOFF(*interp_ex); - addr = (char __user *)N_TXTADDR(*interp_ex); + addr = (char __user *) N_TXTADDR(*interp_ex); break; default: goto out; @@ -540,6 +531,7 @@ static unsigned long load_aout_interp(struct exec *interp_ex, flush_icache_range((unsigned long)addr, (unsigned long)addr + text_data); + down_write(¤t->mm->mmap_sem); do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1), interp_ex->a_bss); @@ -578,7 +570,7 @@ static unsigned long randomize_stack_top(unsigned long stack_top) #endif } -static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) { struct file *interpreter = NULL; /* to shut gcc up */ unsigned long load_addr = 0, load_bias = 0; @@ -587,7 +579,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) unsigned int interpreter_type = INTERPRETER_NONE; unsigned char ibcs2_interpreter = 0; unsigned long error; - struct elf_phdr *elf_ppnt, *elf_phdata; + struct elf_phdr * elf_ppnt, *elf_phdata; unsigned long elf_bss, elf_brk; int elf_exec_fileno; int retval, i; @@ -612,7 +604,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) } /* Get the exec-header */ - loc->elf_ex = *((struct elfhdr *)bprm->buf); + loc->elf_ex = *((struct elfhdr *) bprm->buf); retval = -ENOEXEC; /* First of all, some simple consistency checks */ @@ -627,6 +619,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto out; /* Now read in all of the header information */ + if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr)) goto out; if (loc->elf_ex.e_phnum < 1 || @@ -634,19 +627,18 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto out; size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr); retval = -ENOMEM; - elf_phdata = kmalloc(size, GFP_KERNEL); + elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL); if (!elf_phdata) goto out; - retval = kernel_read(bprm->file, loc->elf_ex.e_phoff, - (char *)elf_phdata, size); + retval = kernel_read(bprm->file, loc->elf_ex.e_phoff, (char *) elf_phdata, size); if (retval != size) { if (retval >= 0) retval = -EIO; goto out_free_ph; } - files = current->files; /* Refcounted so ok */ + files = current->files; /* Refcounted so ok */ retval = unshare_files(); if (retval < 0) goto out_free_ph; @@ -657,6 +649,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* exec will make our files private anyway, but for the a.out loader stuff we need to do it earlier */ + retval = get_unused_fd(); if (retval < 0) goto out_free_fh; @@ -678,6 +671,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) * shared libraries - for now assume that this * is an a.out format binary */ + retval = -ENOEXEC; if (elf_ppnt->p_filesz > PATH_MAX || elf_ppnt->p_filesz < 2) @@ -685,13 +679,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) retval = -ENOMEM; elf_interpreter = kmalloc(elf_ppnt->p_filesz, - GFP_KERNEL); + GFP_KERNEL); if (!elf_interpreter) goto out_free_file; retval = kernel_read(bprm->file, elf_ppnt->p_offset, - elf_interpreter, - elf_ppnt->p_filesz); + elf_interpreter, + elf_ppnt->p_filesz); if (retval != elf_ppnt->p_filesz) { if (retval >= 0) retval = -EIO; @@ -735,8 +729,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) retval = PTR_ERR(interpreter); if (IS_ERR(interpreter)) goto out_free_interp; - retval = kernel_read(interpreter, 0, bprm->buf, - BINPRM_BUF_SIZE); + retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE); if (retval != BINPRM_BUF_SIZE) { if (retval >= 0) retval = -EIO; @@ -744,8 +737,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) } /* Get the exec headers */ - loc->interp_ex = *((struct exec *)bprm->buf); - loc->interp_elf_ex = *((struct elfhdr *)bprm->buf); + loc->interp_ex = *((struct exec *) bprm->buf); + loc->interp_elf_ex = *((struct elfhdr *) bprm->buf); break; } elf_ppnt++; @@ -804,6 +797,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* OK, we are done with that, now set up the arg stuff, and then start this sucker up */ + if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) { char *passed_p = passed_fileno; sprintf(passed_fileno, "%d", elf_exec_fileno); @@ -832,6 +826,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* Discard our unneeded old files struct */ if (files) { + steal_locks(files); put_files_struct(files); files = NULL; } @@ -851,7 +846,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) elf_read_implies_exec(loc->elf_ex, executable_stack)) current->personality |= READ_IMPLIES_EXEC; - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) current->flags |= PF_RANDOMIZE; arch_pick_mmap_layout(current->mm); @@ -868,11 +863,12 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) current->mm->start_stack = bprm->p; + /* Now we do a little grungy work by mmaping the ELF image into the correct location in memory. */ - for(i = 0, elf_ppnt = elf_phdata; - i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { + + for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { int elf_prot = 0, elf_flags; unsigned long k, vaddr; @@ -900,21 +896,18 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) load_bias, nbyte)) { /* * This bss-zeroing can fail if the ELF - * file specifies odd protections. So + * file specifies odd protections. So * we don't check the return value */ } } } - if (elf_ppnt->p_flags & PF_R) - elf_prot |= PROT_READ; - if (elf_ppnt->p_flags & PF_W) - elf_prot |= PROT_WRITE; - if (elf_ppnt->p_flags & PF_X) - elf_prot |= PROT_EXEC; + if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ; + if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; + if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; - elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE; + elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE; vaddr = elf_ppnt->p_vaddr; if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) @@ -926,8 +919,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); #endif - error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, - elf_prot, elf_flags, 0); + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags, 0); if (BAD_ADDR(error)) { send_sig(SIGKILL, current, 0); goto out_free_dentry; @@ -944,10 +936,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) } } k = elf_ppnt->p_vaddr; - if (k < start_code) - start_code = k; - if (start_data < k) - start_data = k; + if (k < start_code) start_code = k; + if (start_data < k) start_data = k; /* * Check to see if the section's size will overflow the @@ -957,7 +947,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz || elf_ppnt->p_memsz > TASK_SIZE || TASK_SIZE - elf_ppnt->p_memsz < k) { - /* set_brk can never work. Avoid overflows. */ + /* set_brk can never work. Avoid overflows. */ send_sig(SIGKILL, current, 0); goto out_free_dentry; } @@ -1052,9 +1042,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; - create_elf_tables(bprm, &loc->elf_ex, - (interpreter_type == INTERPRETER_AOUT), - load_addr, interp_load_addr); + create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT), + load_addr, interp_load_addr); /* N.B. passed_fileno might not be initialized? */ if (interpreter_type == INTERPRETER_AOUT) current->mm->arg_start += strlen(passed_fileno) + 1; @@ -1072,7 +1061,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* Why this, you ask??? Well SVr4 maps page 0 as read-only, and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we - emulate the SVr4 behavior. Sigh. */ + emulate the SVr4 behavior. Sigh. */ down_write(¤t->mm->mmap_sem); error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); @@ -1127,6 +1116,7 @@ out_free_ph: /* This is really simpleminded and specialized - we are loading an a.out library that is given an ELF header. */ + static int load_elf_library(struct file *file) { struct elf_phdr *elf_phdata; @@ -1136,7 +1126,7 @@ static int load_elf_library(struct file *file) struct elfhdr elf_ex; error = -ENOEXEC; - retval = kernel_read(file, 0, (char *)&elf_ex, sizeof(elf_ex)); + retval = kernel_read(file, 0, (char *) &elf_ex, sizeof(elf_ex)); if (retval != sizeof(elf_ex)) goto out; @@ -1145,7 +1135,7 @@ static int load_elf_library(struct file *file) /* First of all, some simple consistency checks */ if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || - !elf_check_arch(&elf_ex) || !file->f_op || !file->f_op->mmap) + !elf_check_arch(&elf_ex) || !file->f_op || !file->f_op->mmap) goto out; /* Now read in all of the header information */ @@ -1193,8 +1183,7 @@ static int load_elf_library(struct file *file) goto out_free_ph; } - len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + - ELF_MIN_ALIGN - 1); + len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); bss = eppnt->p_memsz + eppnt->p_vaddr; if (bss > len) { down_write(¤t->mm->mmap_sem); @@ -1256,7 +1245,7 @@ static int maydump(struct vm_area_struct *vma) if (vma->vm_flags & VM_DONTEXPAND) /* Kludge for vDSO. */ return 1; - /* Dump shared memory only if mapped from an anonymous file. */ + /* Dump shared memory only if mapped from an anonymous file. */ if (vma->vm_flags & VM_SHARED) return vma->vm_file->f_dentry->d_inode->i_nlink == 0; @@ -1267,6 +1256,8 @@ static int maydump(struct vm_area_struct *vma) return 1; } +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) + /* An ELF note in memory */ struct memelfnote { @@ -1368,11 +1359,11 @@ static void fill_note(struct memelfnote *note, const char *name, int type, } /* - * fill up all the fields in prstatus from the given task struct, except - * registers which need to be filled up separately. + * fill up all the fields in prstatus from the given task struct, except registers + * which need to be filled up separately. */ static void fill_prstatus(struct elf_prstatus *prstatus, - struct task_struct *p, long signr) + struct task_struct *p, long signr) { prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; prstatus->pr_sigpend = p->pending.signal.sig[0]; @@ -1457,8 +1448,8 @@ struct elf_thread_status /* * In order to add the specific thread information for the elf file format, - * we need to keep a linked list of every threads pr_status and then create - * a single section for them in the final core file. + * we need to keep a linked list of every threads pr_status and then + * create a single section for them in the final core file. */ static int elf_dump_thread_status(long signr, struct elf_thread_status *t) { @@ -1469,23 +1460,19 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t) fill_prstatus(&t->prstatus, p, signr); elf_core_copy_task_regs(p, &t->prstatus.pr_reg); - fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus), - &(t->prstatus)); + fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus), &(t->prstatus)); t->num_notes++; sz += notesize(&t->notes[0]); - if ((t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL, - &t->fpu))) { - fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu), - &(t->fpu)); + if ((t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL, &t->fpu))) { + fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu), &(t->fpu)); t->num_notes++; sz += notesize(&t->notes[1]); } #ifdef ELF_CORE_COPY_XFPREGS if (elf_core_copy_task_xfpregs(p, &t->xfpu)) { - fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu), - &t->xfpu); + fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu), &t->xfpu); t->num_notes++; sz += notesize(&t->notes[2]); } @@ -1500,7 +1487,7 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t) * and then they are actually written out. If we run out of core limit * we just truncate. */ -static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) +static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) { #define NUM_NOTES 6 int has_dumped = 0; @@ -1529,12 +1516,12 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) /* * We no longer stop all VM operations. * - * This is because those proceses that could possibly change map_count - * or the mmap / vma pages are now blocked in do_exit on current - * finishing this core dump. + * This is because those proceses that could possibly change map_count or + * the mmap / vma pages are now blocked in do_exit on current finishing + * this core dump. * * Only ptrace can touch these memory addresses, but it doesn't change - * the map_count or the pages allocated. So no possibility of crashing + * the map_count or the pages allocated. So no possibility of crashing * exists while dumping the mm->vm_next areas to the core file. */ @@ -1596,7 +1583,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) #endif /* Set up header */ - fill_elf_header(elf, segs + 1); /* including notes section */ + fill_elf_header(elf, segs+1); /* including notes section */ has_dumped = 1; current->flags |= PF_DUMPCORE; @@ -1606,24 +1593,24 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) * with info from their /proc. */ - fill_note(notes + 0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus); + fill_note(notes +0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus); + fill_psinfo(psinfo, current->group_leader, current->mm); - fill_note(notes + 1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo); + fill_note(notes +1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo); numnote = 2; - auxv = (elf_addr_t *)current->mm->saved_auxv; + auxv = (elf_addr_t *) current->mm->saved_auxv; i = 0; do i += 2; while (auxv[i - 2] != AT_NULL); fill_note(¬es[numnote++], "CORE", NT_AUXV, - i * sizeof(elf_addr_t), auxv); + i * sizeof (elf_addr_t), auxv); /* Try to dump the FPU. */ - if ((prstatus->pr_fpvalid = - elf_core_copy_task_fpregs(current, regs, fpu))) + if ((prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs, fpu))) fill_note(notes + numnote++, "CORE", NT_PRFPREG, sizeof(*fpu), fpu); #ifdef ELF_CORE_COPY_XFPREGS @@ -1672,10 +1659,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) phdr.p_memsz = sz; offset += phdr.p_filesz; phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; - if (vma->vm_flags & VM_WRITE) - phdr.p_flags |= PF_W; - if (vma->vm_flags & VM_EXEC) - phdr.p_flags |= PF_X; + if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W; + if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X; phdr.p_align = ELF_EXEC_PAGESIZE; DUMP_WRITE(&phdr, sizeof(phdr)); @@ -1692,9 +1677,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) /* write out the thread status notes section */ list_for_each(t, &thread_list) { - struct elf_thread_status *tmp = - list_entry(t, struct elf_thread_status, list); - + struct elf_thread_status *tmp = list_entry(t, struct elf_thread_status, list); for (i = 0; i < tmp->num_notes; i++) if (!writenote(&tmp->notes[i], file)) goto end_coredump; @@ -1711,19 +1694,18 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { - struct page *page; + struct page* page; struct vm_area_struct *vma; if (get_user_pages(current, current->mm, addr, 1, 0, 1, &page, &vma) <= 0) { - DUMP_SEEK(file->f_pos + PAGE_SIZE); + DUMP_SEEK (file->f_pos + PAGE_SIZE); } else { if (page == ZERO_PAGE(addr)) { - DUMP_SEEK(file->f_pos + PAGE_SIZE); + DUMP_SEEK (file->f_pos + PAGE_SIZE); } else { void *kaddr; - flush_cache_page(vma, addr, - page_to_pfn(page)); + flush_cache_page(vma, addr, page_to_pfn(page)); kaddr = kmap(page); if ((size += PAGE_SIZE) > limit || !dump_write(file, kaddr, @@ -1745,8 +1727,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) if ((off_t)file->f_pos != offset) { /* Sanity check */ - printk(KERN_WARNING - "elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", + printk(KERN_WARNING "elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", (off_t)file->f_pos, offset); }