aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d0434406eaeb..6eb48e1446ec 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -84,7 +84,7 @@ static struct linux_binfmt elf_format = {
84 .min_coredump = ELF_EXEC_PAGESIZE 84 .min_coredump = ELF_EXEC_PAGESIZE
85}; 85};
86 86
87#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) 87#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
88 88
89static int set_brk(unsigned long start, unsigned long end) 89static int set_brk(unsigned long start, unsigned long end)
90{ 90{
@@ -394,7 +394,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
394 * <= p_memsize so it's only necessary to check p_memsz. 394 * <= p_memsize so it's only necessary to check p_memsz.
395 */ 395 */
396 k = load_addr + eppnt->p_vaddr; 396 k = load_addr + eppnt->p_vaddr;
397 if (k > TASK_SIZE || 397 if (BAD_ADDR(k) ||
398 eppnt->p_filesz > eppnt->p_memsz || 398 eppnt->p_filesz > eppnt->p_memsz ||
399 eppnt->p_memsz > TASK_SIZE || 399 eppnt->p_memsz > TASK_SIZE ||
400 TASK_SIZE - eppnt->p_memsz < k) { 400 TASK_SIZE - eppnt->p_memsz < k) {
@@ -515,7 +515,8 @@ static unsigned long randomize_stack_top(unsigned long stack_top)
515{ 515{
516 unsigned int random_variable = 0; 516 unsigned int random_variable = 0;
517 517
518 if (current->flags & PF_RANDOMIZE) { 518 if ((current->flags & PF_RANDOMIZE) &&
519 !(current->personality & ADDR_NO_RANDOMIZE)) {
519 random_variable = get_random_int() & STACK_RND_MASK; 520 random_variable = get_random_int() & STACK_RND_MASK;
520 random_variable <<= PAGE_SHIFT; 521 random_variable <<= PAGE_SHIFT;
521 } 522 }
@@ -887,7 +888,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
887 * allowed task size. Note that p_filesz must always be 888 * allowed task size. Note that p_filesz must always be
888 * <= p_memsz so it is only necessary to check p_memsz. 889 * <= p_memsz so it is only necessary to check p_memsz.
889 */ 890 */
890 if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || 891 if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
891 elf_ppnt->p_memsz > TASK_SIZE || 892 elf_ppnt->p_memsz > TASK_SIZE ||
892 TASK_SIZE - elf_ppnt->p_memsz < k) { 893 TASK_SIZE - elf_ppnt->p_memsz < k) {
893 /* set_brk can never work. Avoid overflows. */ 894 /* set_brk can never work. Avoid overflows. */
@@ -941,10 +942,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
941 interpreter, 942 interpreter,
942 &interp_load_addr); 943 &interp_load_addr);
943 if (BAD_ADDR(elf_entry)) { 944 if (BAD_ADDR(elf_entry)) {
944 printk(KERN_ERR "Unable to load interpreter %.128s\n",
945 elf_interpreter);
946 force_sig(SIGSEGV, current); 945 force_sig(SIGSEGV, current);
947 retval = -ENOEXEC; /* Nobody gets to see this, but.. */ 946 retval = IS_ERR((void *)elf_entry) ?
947 (int)elf_entry : -EINVAL;
948 goto out_free_dentry; 948 goto out_free_dentry;
949 } 949 }
950 reloc_func_desc = interp_load_addr; 950 reloc_func_desc = interp_load_addr;
@@ -955,8 +955,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
955 } else { 955 } else {
956 elf_entry = loc->elf_ex.e_entry; 956 elf_entry = loc->elf_ex.e_entry;
957 if (BAD_ADDR(elf_entry)) { 957 if (BAD_ADDR(elf_entry)) {
958 send_sig(SIGSEGV, current, 0); 958 force_sig(SIGSEGV, current);
959 retval = -ENOEXEC; /* Nobody gets to see this, but.. */ 959 retval = -EINVAL;
960 goto out_free_dentry; 960 goto out_free_dentry;
961 } 961 }
962 } 962 }
@@ -1038,10 +1038,8 @@ out_free_interp:
1038out_free_file: 1038out_free_file:
1039 sys_close(elf_exec_fileno); 1039 sys_close(elf_exec_fileno);
1040out_free_fh: 1040out_free_fh:
1041 if (files) { 1041 if (files)
1042 put_files_struct(current->files); 1042 reset_files_struct(current, files);
1043 current->files = files;
1044 }
1045out_free_ph: 1043out_free_ph:
1046 kfree(elf_phdata); 1044 kfree(elf_phdata);
1047 goto out; 1045 goto out;
@@ -1186,8 +1184,6 @@ static int maydump(struct vm_area_struct *vma)
1186 return 1; 1184 return 1;
1187} 1185}
1188 1186
1189#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
1190
1191/* An ELF note in memory */ 1187/* An ELF note in memory */
1192struct memelfnote 1188struct memelfnote
1193{ 1189{
@@ -1265,7 +1261,7 @@ static void fill_elf_header(struct elfhdr *elf, int segs)
1265 return; 1261 return;
1266} 1262}
1267 1263
1268static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, off_t offset) 1264static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, loff_t offset)
1269{ 1265{
1270 phdr->p_type = PT_NOTE; 1266 phdr->p_type = PT_NOTE;
1271 phdr->p_offset = offset; 1267 phdr->p_offset = offset;
@@ -1431,7 +1427,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1431 int i; 1427 int i;
1432 struct vm_area_struct *vma; 1428 struct vm_area_struct *vma;
1433 struct elfhdr *elf = NULL; 1429 struct elfhdr *elf = NULL;
1434 off_t offset = 0, dataoff; 1430 loff_t offset = 0, dataoff;
1435 unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; 1431 unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
1436 int numnote; 1432 int numnote;
1437 struct memelfnote *notes = NULL; 1433 struct memelfnote *notes = NULL;
@@ -1483,20 +1479,19 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1483 1479
1484 if (signr) { 1480 if (signr) {
1485 struct elf_thread_status *tmp; 1481 struct elf_thread_status *tmp;
1486 read_lock(&tasklist_lock); 1482 rcu_read_lock();
1487 do_each_thread(g,p) 1483 do_each_thread(g,p)
1488 if (current->mm == p->mm && current != p) { 1484 if (current->mm == p->mm && current != p) {
1489 tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); 1485 tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
1490 if (!tmp) { 1486 if (!tmp) {
1491 read_unlock(&tasklist_lock); 1487 rcu_read_unlock();
1492 goto cleanup; 1488 goto cleanup;
1493 } 1489 }
1494 INIT_LIST_HEAD(&tmp->list);
1495 tmp->thread = p; 1490 tmp->thread = p;
1496 list_add(&tmp->list, &thread_list); 1491 list_add(&tmp->list, &thread_list);
1497 } 1492 }
1498 while_each_thread(g,p); 1493 while_each_thread(g,p);
1499 read_unlock(&tasklist_lock); 1494 rcu_read_unlock();
1500 list_for_each(t, &thread_list) { 1495 list_for_each(t, &thread_list) {
1501 struct elf_thread_status *tmp; 1496 struct elf_thread_status *tmp;
1502 int sz; 1497 int sz;
@@ -1664,11 +1659,11 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1664 ELF_CORE_WRITE_EXTRA_DATA; 1659 ELF_CORE_WRITE_EXTRA_DATA;
1665#endif 1660#endif
1666 1661
1667 if ((off_t)file->f_pos != offset) { 1662 if (file->f_pos != offset) {
1668 /* Sanity check */ 1663 /* Sanity check */
1669 printk(KERN_WARNING 1664 printk(KERN_WARNING
1670 "elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", 1665 "elf_core_dump: file->f_pos (%Ld) != offset (%Ld)\n",
1671 (off_t)file->f_pos, offset); 1666 file->f_pos, offset);
1672 } 1667 }
1673 1668
1674end_coredump: 1669end_coredump: