diff options
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r-- | fs/binfmt_elf.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 655ed8d30a86..8fcfa398d350 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -683,7 +683,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
683 | * switch really is going to happen - do this in | 683 | * switch really is going to happen - do this in |
684 | * flush_thread(). - akpm | 684 | * flush_thread(). - akpm |
685 | */ | 685 | */ |
686 | SET_PERSONALITY(loc->elf_ex, 0); | 686 | SET_PERSONALITY(loc->elf_ex); |
687 | 687 | ||
688 | interpreter = open_exec(elf_interpreter); | 688 | interpreter = open_exec(elf_interpreter); |
689 | retval = PTR_ERR(interpreter); | 689 | retval = PTR_ERR(interpreter); |
@@ -734,7 +734,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
734 | goto out_free_dentry; | 734 | goto out_free_dentry; |
735 | } else { | 735 | } else { |
736 | /* Executables without an interpreter also need a personality */ | 736 | /* Executables without an interpreter also need a personality */ |
737 | SET_PERSONALITY(loc->elf_ex, 0); | 737 | SET_PERSONALITY(loc->elf_ex); |
738 | } | 738 | } |
739 | 739 | ||
740 | /* Flush all traces of the currently running executable */ | 740 | /* Flush all traces of the currently running executable */ |
@@ -748,7 +748,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
748 | 748 | ||
749 | /* Do this immediately, since STACK_TOP as used in setup_arg_pages | 749 | /* Do this immediately, since STACK_TOP as used in setup_arg_pages |
750 | may depend on the personality. */ | 750 | may depend on the personality. */ |
751 | SET_PERSONALITY(loc->elf_ex, 0); | 751 | SET_PERSONALITY(loc->elf_ex); |
752 | if (elf_read_implies_exec(loc->elf_ex, executable_stack)) | 752 | if (elf_read_implies_exec(loc->elf_ex, executable_stack)) |
753 | current->personality |= READ_IMPLIES_EXEC; | 753 | current->personality |= READ_IMPLIES_EXEC; |
754 | 754 | ||
@@ -1156,16 +1156,24 @@ static int dump_seek(struct file *file, loff_t off) | |||
1156 | static unsigned long vma_dump_size(struct vm_area_struct *vma, | 1156 | static unsigned long vma_dump_size(struct vm_area_struct *vma, |
1157 | unsigned long mm_flags) | 1157 | unsigned long mm_flags) |
1158 | { | 1158 | { |
1159 | #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type)) | ||
1160 | |||
1159 | /* The vma can be set up to tell us the answer directly. */ | 1161 | /* The vma can be set up to tell us the answer directly. */ |
1160 | if (vma->vm_flags & VM_ALWAYSDUMP) | 1162 | if (vma->vm_flags & VM_ALWAYSDUMP) |
1161 | goto whole; | 1163 | goto whole; |
1162 | 1164 | ||
1165 | /* Hugetlb memory check */ | ||
1166 | if (vma->vm_flags & VM_HUGETLB) { | ||
1167 | if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED)) | ||
1168 | goto whole; | ||
1169 | if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE)) | ||
1170 | goto whole; | ||
1171 | } | ||
1172 | |||
1163 | /* Do not dump I/O mapped devices or special mappings */ | 1173 | /* Do not dump I/O mapped devices or special mappings */ |
1164 | if (vma->vm_flags & (VM_IO | VM_RESERVED)) | 1174 | if (vma->vm_flags & (VM_IO | VM_RESERVED)) |
1165 | return 0; | 1175 | return 0; |
1166 | 1176 | ||
1167 | #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type)) | ||
1168 | |||
1169 | /* By default, dump shared memory if mapped from an anonymous file. */ | 1177 | /* By default, dump shared memory if mapped from an anonymous file. */ |
1170 | if (vma->vm_flags & VM_SHARED) { | 1178 | if (vma->vm_flags & VM_SHARED) { |
1171 | if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0 ? | 1179 | if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0 ? |
@@ -1333,20 +1341,15 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1333 | prstatus->pr_pgrp = task_pgrp_vnr(p); | 1341 | prstatus->pr_pgrp = task_pgrp_vnr(p); |
1334 | prstatus->pr_sid = task_session_vnr(p); | 1342 | prstatus->pr_sid = task_session_vnr(p); |
1335 | if (thread_group_leader(p)) { | 1343 | if (thread_group_leader(p)) { |
1344 | struct task_cputime cputime; | ||
1345 | |||
1336 | /* | 1346 | /* |
1337 | * This is the record for the group leader. Add in the | 1347 | * This is the record for the group leader. It shows the |
1338 | * cumulative times of previous dead threads. This total | 1348 | * group-wide total, not its individual thread total. |
1339 | * won't include the time of each live thread whose state | ||
1340 | * is included in the core dump. The final total reported | ||
1341 | * to our parent process when it calls wait4 will include | ||
1342 | * those sums as well as the little bit more time it takes | ||
1343 | * this and each other thread to finish dying after the | ||
1344 | * core dump synchronization phase. | ||
1345 | */ | 1349 | */ |
1346 | cputime_to_timeval(cputime_add(p->utime, p->signal->utime), | 1350 | thread_group_cputime(p, &cputime); |
1347 | &prstatus->pr_utime); | 1351 | cputime_to_timeval(cputime.utime, &prstatus->pr_utime); |
1348 | cputime_to_timeval(cputime_add(p->stime, p->signal->stime), | 1352 | cputime_to_timeval(cputime.stime, &prstatus->pr_stime); |
1349 | &prstatus->pr_stime); | ||
1350 | } else { | 1353 | } else { |
1351 | cputime_to_timeval(p->utime, &prstatus->pr_utime); | 1354 | cputime_to_timeval(p->utime, &prstatus->pr_utime); |
1352 | cputime_to_timeval(p->stime, &prstatus->pr_stime); | 1355 | cputime_to_timeval(p->stime, &prstatus->pr_stime); |