aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
commita9de18eb761f7c1c860964b2e5addc1a35c7e861 (patch)
tree886e75fdfd09690cd262ca69cb7f5d1d42b48602 /fs/binfmt_elf.c
parentb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (diff)
parent6a94cb73064c952255336cc57731904174b2c58f (diff)
Merge branch 'linus' into stackprotector
Conflicts: arch/x86/include/asm/pda.h kernel/fork.c
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c59
1 files changed, 33 insertions, 26 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 655ed8d30a86..c41fa2af7677 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -157,7 +157,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
157 int items; 157 int items;
158 elf_addr_t *elf_info; 158 elf_addr_t *elf_info;
159 int ei_index = 0; 159 int ei_index = 0;
160 struct task_struct *tsk = current; 160 const struct cred *cred = current_cred();
161 struct vm_area_struct *vma; 161 struct vm_area_struct *vma;
162 162
163 /* 163 /*
@@ -223,10 +223,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
223 NEW_AUX_ENT(AT_BASE, interp_load_addr); 223 NEW_AUX_ENT(AT_BASE, interp_load_addr);
224 NEW_AUX_ENT(AT_FLAGS, 0); 224 NEW_AUX_ENT(AT_FLAGS, 0);
225 NEW_AUX_ENT(AT_ENTRY, exec->e_entry); 225 NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
226 NEW_AUX_ENT(AT_UID, tsk->uid); 226 NEW_AUX_ENT(AT_UID, cred->uid);
227 NEW_AUX_ENT(AT_EUID, tsk->euid); 227 NEW_AUX_ENT(AT_EUID, cred->euid);
228 NEW_AUX_ENT(AT_GID, tsk->gid); 228 NEW_AUX_ENT(AT_GID, cred->gid);
229 NEW_AUX_ENT(AT_EGID, tsk->egid); 229 NEW_AUX_ENT(AT_EGID, cred->egid);
230 NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); 230 NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
231 NEW_AUX_ENT(AT_EXECFN, bprm->exec); 231 NEW_AUX_ENT(AT_EXECFN, bprm->exec);
232 if (k_platform) { 232 if (k_platform) {
@@ -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
@@ -949,14 +949,14 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
949 set_binfmt(&elf_format); 949 set_binfmt(&elf_format);
950 950
951#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES 951#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
952 retval = arch_setup_additional_pages(bprm, executable_stack); 952 retval = arch_setup_additional_pages(bprm, !!elf_interpreter);
953 if (retval < 0) { 953 if (retval < 0) {
954 send_sig(SIGKILL, current, 0); 954 send_sig(SIGKILL, current, 0);
955 goto out; 955 goto out;
956 } 956 }
957#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ 957#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
958 958
959 compute_creds(bprm); 959 install_exec_creds(bprm);
960 current->flags &= ~PF_FORKNOEXEC; 960 current->flags &= ~PF_FORKNOEXEC;
961 retval = create_elf_tables(bprm, &loc->elf_ex, 961 retval = create_elf_tables(bprm, &loc->elf_ex,
962 load_addr, interp_load_addr); 962 load_addr, interp_load_addr);
@@ -1156,16 +1156,24 @@ static int dump_seek(struct file *file, loff_t off)
1156static unsigned long vma_dump_size(struct vm_area_struct *vma, 1156static 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);
@@ -1358,6 +1361,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
1358static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, 1361static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1359 struct mm_struct *mm) 1362 struct mm_struct *mm)
1360{ 1363{
1364 const struct cred *cred;
1361 unsigned int i, len; 1365 unsigned int i, len;
1362 1366
1363 /* first copy the parameters from user space */ 1367 /* first copy the parameters from user space */
@@ -1385,8 +1389,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1385 psinfo->pr_zomb = psinfo->pr_sname == 'Z'; 1389 psinfo->pr_zomb = psinfo->pr_sname == 'Z';
1386 psinfo->pr_nice = task_nice(p); 1390 psinfo->pr_nice = task_nice(p);
1387 psinfo->pr_flag = p->flags; 1391 psinfo->pr_flag = p->flags;
1388 SET_UID(psinfo->pr_uid, p->uid); 1392 rcu_read_lock();
1389 SET_GID(psinfo->pr_gid, p->gid); 1393 cred = __task_cred(p);
1394 SET_UID(psinfo->pr_uid, cred->uid);
1395 SET_GID(psinfo->pr_gid, cred->gid);
1396 rcu_read_unlock();
1390 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname)); 1397 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
1391 1398
1392 return 0; 1399 return 0;