power: supply: Allow charger manager can be built as a module
[linux-2.6-microblaze.git] / fs / binfmt_elf.c
index 9afb5ed..f4713ea 100644 (file)
@@ -97,7 +97,7 @@ static struct linux_binfmt elf_format = {
        .min_coredump   = ELF_EXEC_PAGESIZE,
 };
 
-#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
+#define BAD_ADDR(x) (unlikely((unsigned long)(x) >= TASK_SIZE))
 
 static int set_brk(unsigned long start, unsigned long end, int prot)
 {
@@ -1595,6 +1595,10 @@ static int fill_files_note(struct memelfnote *note)
        if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */
                return -EINVAL;
        size = round_up(size, PAGE_SIZE);
+       /*
+        * "size" can be 0 here legitimately.
+        * Let it ENOMEM and omit NT_FILE section which will be empty anyway.
+        */
        data = kvmalloc(size, GFP_KERNEL);
        if (ZERO_OR_NULL_PTR(data))
                return -ENOMEM;
@@ -2186,7 +2190,7 @@ static int elf_core_dump(struct coredump_params *cprm)
        int segs, i;
        size_t vma_data_size = 0;
        struct vm_area_struct *vma, *gate_vma;
-       struct elfhdr *elf = NULL;
+       struct elfhdr elf;
        loff_t offset = 0, dataoff;
        struct elf_note_info info = { };
        struct elf_phdr *phdr4note = NULL;
@@ -2207,10 +2211,6 @@ static int elf_core_dump(struct coredump_params *cprm)
         * exists while dumping the mm->vm_next areas to the core file.
         */
   
-       /* alloc memory for large data structures: too large to be on stack */
-       elf = kmalloc(sizeof(*elf), GFP_KERNEL);
-       if (!elf)
-               goto out;
        /*
         * The number of segs are recored into ELF header as 16bit value.
         * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
@@ -2234,7 +2234,7 @@ static int elf_core_dump(struct coredump_params *cprm)
         * Collect all the non-memory information about the process for the
         * notes.  This also sets up the file header.
         */
-       if (!fill_note_info(elf, e_phnum, &info, cprm->siginfo, cprm->regs))
+       if (!fill_note_info(&elf, e_phnum, &info, cprm->siginfo, cprm->regs))
                goto cleanup;
 
        has_dumped = 1;
@@ -2242,7 +2242,7 @@ static int elf_core_dump(struct coredump_params *cprm)
        fs = get_fs();
        set_fs(KERNEL_DS);
 
-       offset += sizeof(*elf);                         /* Elf header */
+       offset += sizeof(elf);                          /* Elf header */
        offset += segs * sizeof(struct elf_phdr);       /* Program headers */
 
        /* Write notes phdr entry */
@@ -2261,11 +2261,13 @@ static int elf_core_dump(struct coredump_params *cprm)
 
        dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
 
-       if (segs - 1 > ULONG_MAX / sizeof(*vma_filesz))
-               goto end_coredump;
+       /*
+        * Zero vma process will get ZERO_SIZE_PTR here.
+        * Let coredump continue for register state at least.
+        */
        vma_filesz = kvmalloc(array_size(sizeof(*vma_filesz), (segs - 1)),
                              GFP_KERNEL);
-       if (ZERO_OR_NULL_PTR(vma_filesz))
+       if (!vma_filesz)
                goto end_coredump;
 
        for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;
@@ -2285,12 +2287,12 @@ static int elf_core_dump(struct coredump_params *cprm)
                shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
                if (!shdr4extnum)
                        goto end_coredump;
-               fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
+               fill_extnum_info(&elf, shdr4extnum, e_shoff, segs);
        }
 
        offset = dataoff;
 
-       if (!dump_emit(cprm, elf, sizeof(*elf)))
+       if (!dump_emit(cprm, &elf, sizeof(elf)))
                goto end_coredump;
 
        if (!dump_emit(cprm, phdr4note, sizeof(*phdr4note)))
@@ -2374,8 +2376,6 @@ cleanup:
        kfree(shdr4extnum);
        kvfree(vma_filesz);
        kfree(phdr4note);
-       kfree(elf);
-out:
        return has_dumped;
 }