diff options
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r-- | fs/binfmt_elf.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 79b05a1a4365..7cb28720f90e 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -47,10 +47,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); | |||
47 | static int load_elf_library(struct file *); | 47 | static int load_elf_library(struct file *); |
48 | static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); | 48 | static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); |
49 | 49 | ||
50 | #ifndef elf_addr_t | ||
51 | #define elf_addr_t unsigned long | ||
52 | #endif | ||
53 | |||
54 | /* | 50 | /* |
55 | * If we don't support core dumping, then supply a NULL so we | 51 | * If we don't support core dumping, then supply a NULL so we |
56 | * don't even try. | 52 | * don't even try. |
@@ -243,8 +239,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
243 | if (interp_aout) { | 239 | if (interp_aout) { |
244 | argv = sp + 2; | 240 | argv = sp + 2; |
245 | envp = argv + argc + 1; | 241 | envp = argv + argc + 1; |
246 | __put_user((elf_addr_t)(unsigned long)argv, sp++); | 242 | if (__put_user((elf_addr_t)(unsigned long)argv, sp++) || |
247 | __put_user((elf_addr_t)(unsigned long)envp, sp++); | 243 | __put_user((elf_addr_t)(unsigned long)envp, sp++)) |
244 | return -EFAULT; | ||
248 | } else { | 245 | } else { |
249 | argv = sp; | 246 | argv = sp; |
250 | envp = argv + argc + 1; | 247 | envp = argv + argc + 1; |
@@ -254,7 +251,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
254 | p = current->mm->arg_end = current->mm->arg_start; | 251 | p = current->mm->arg_end = current->mm->arg_start; |
255 | while (argc-- > 0) { | 252 | while (argc-- > 0) { |
256 | size_t len; | 253 | size_t len; |
257 | __put_user((elf_addr_t)p, argv++); | 254 | if (__put_user((elf_addr_t)p, argv++)) |
255 | return -EFAULT; | ||
258 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); | 256 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); |
259 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) | 257 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) |
260 | return 0; | 258 | return 0; |
@@ -265,7 +263,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
265 | current->mm->arg_end = current->mm->env_start = p; | 263 | current->mm->arg_end = current->mm->env_start = p; |
266 | while (envc-- > 0) { | 264 | while (envc-- > 0) { |
267 | size_t len; | 265 | size_t len; |
268 | __put_user((elf_addr_t)p, envp++); | 266 | if (__put_user((elf_addr_t)p, envp++)) |
267 | return -EFAULT; | ||
269 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); | 268 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); |
270 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) | 269 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) |
271 | return 0; | 270 | return 0; |
@@ -545,7 +544,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
545 | unsigned long reloc_func_desc = 0; | 544 | unsigned long reloc_func_desc = 0; |
546 | char passed_fileno[6]; | 545 | char passed_fileno[6]; |
547 | struct files_struct *files; | 546 | struct files_struct *files; |
548 | int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT; | 547 | int executable_stack = EXSTACK_DEFAULT; |
549 | unsigned long def_flags = 0; | 548 | unsigned long def_flags = 0; |
550 | struct { | 549 | struct { |
551 | struct elfhdr elf_ex; | 550 | struct elfhdr elf_ex; |
@@ -708,7 +707,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
708 | executable_stack = EXSTACK_DISABLE_X; | 707 | executable_stack = EXSTACK_DISABLE_X; |
709 | break; | 708 | break; |
710 | } | 709 | } |
711 | have_pt_gnu_stack = (i < loc->elf_ex.e_phnum); | ||
712 | 710 | ||
713 | /* Some simple consistency checks for the interpreter */ | 711 | /* Some simple consistency checks for the interpreter */ |
714 | if (elf_interpreter) { | 712 | if (elf_interpreter) { |
@@ -1186,7 +1184,7 @@ static int maydump(struct vm_area_struct *vma) | |||
1186 | 1184 | ||
1187 | /* Dump shared memory only if mapped from an anonymous file. */ | 1185 | /* Dump shared memory only if mapped from an anonymous file. */ |
1188 | if (vma->vm_flags & VM_SHARED) | 1186 | if (vma->vm_flags & VM_SHARED) |
1189 | return vma->vm_file->f_dentry->d_inode->i_nlink == 0; | 1187 | return vma->vm_file->f_path.dentry->d_inode->i_nlink == 0; |
1190 | 1188 | ||
1191 | /* If it hasn't been written to, don't write it out */ | 1189 | /* If it hasn't been written to, don't write it out */ |
1192 | if (!vma->anon_vma) | 1190 | if (!vma->anon_vma) |
@@ -1313,7 +1311,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1313 | prstatus->pr_pid = p->pid; | 1311 | prstatus->pr_pid = p->pid; |
1314 | prstatus->pr_ppid = p->parent->pid; | 1312 | prstatus->pr_ppid = p->parent->pid; |
1315 | prstatus->pr_pgrp = process_group(p); | 1313 | prstatus->pr_pgrp = process_group(p); |
1316 | prstatus->pr_sid = p->signal->session; | 1314 | prstatus->pr_sid = process_session(p); |
1317 | if (thread_group_leader(p)) { | 1315 | if (thread_group_leader(p)) { |
1318 | /* | 1316 | /* |
1319 | * This is the record for the group leader. Add in the | 1317 | * This is the record for the group leader. Add in the |
@@ -1359,7 +1357,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1359 | psinfo->pr_pid = p->pid; | 1357 | psinfo->pr_pid = p->pid; |
1360 | psinfo->pr_ppid = p->parent->pid; | 1358 | psinfo->pr_ppid = p->parent->pid; |
1361 | psinfo->pr_pgrp = process_group(p); | 1359 | psinfo->pr_pgrp = process_group(p); |
1362 | psinfo->pr_sid = p->signal->session; | 1360 | psinfo->pr_sid = process_session(p); |
1363 | 1361 | ||
1364 | i = p->state ? ffz(~p->state) + 1 : 0; | 1362 | i = p->state ? ffz(~p->state) + 1 : 0; |
1365 | psinfo->pr_state = i; | 1363 | psinfo->pr_state = i; |
@@ -1582,6 +1580,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1582 | 1580 | ||
1583 | sz += thread_status_size; | 1581 | sz += thread_status_size; |
1584 | 1582 | ||
1583 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | ||
1584 | sz += ELF_CORE_EXTRA_NOTES_SIZE; | ||
1585 | #endif | ||
1586 | |||
1585 | fill_elf_note_phdr(&phdr, sz, offset); | 1587 | fill_elf_note_phdr(&phdr, sz, offset); |
1586 | offset += sz; | 1588 | offset += sz; |
1587 | DUMP_WRITE(&phdr, sizeof(phdr)); | 1589 | DUMP_WRITE(&phdr, sizeof(phdr)); |
@@ -1622,6 +1624,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1622 | if (!writenote(notes + i, file, &foffset)) | 1624 | if (!writenote(notes + i, file, &foffset)) |
1623 | goto end_coredump; | 1625 | goto end_coredump; |
1624 | 1626 | ||
1627 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | ||
1628 | ELF_CORE_WRITE_EXTRA_NOTES; | ||
1629 | #endif | ||
1630 | |||
1625 | /* write out the thread status notes section */ | 1631 | /* write out the thread status notes section */ |
1626 | list_for_each(t, &thread_list) { | 1632 | list_for_each(t, &thread_list) { |
1627 | struct elf_thread_status *tmp = | 1633 | struct elf_thread_status *tmp = |