diff options
Diffstat (limited to 'fs/binfmt_elf_fdpic.c')
-rw-r--r-- | fs/binfmt_elf_fdpic.c | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index ddd35d873391..80c1f952ef78 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -390,7 +390,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
390 | } | 390 | } |
391 | 391 | ||
392 | /* expand the stack mapping to use up the entire allocation granule */ | 392 | /* expand the stack mapping to use up the entire allocation granule */ |
393 | fullsize = ksize((char *) current->mm->start_brk); | 393 | fullsize = kobjsize((char *) current->mm->start_brk); |
394 | if (!IS_ERR_VALUE(do_mremap(current->mm->start_brk, stack_size, | 394 | if (!IS_ERR_VALUE(do_mremap(current->mm->start_brk, stack_size, |
395 | fullsize, 0, 0))) | 395 | fullsize, 0, 0))) |
396 | stack_size = fullsize; | 396 | stack_size = fullsize; |
@@ -433,13 +433,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
433 | entryaddr = interp_params.entry_addr ?: exec_params.entry_addr; | 433 | entryaddr = interp_params.entry_addr ?: exec_params.entry_addr; |
434 | start_thread(regs, entryaddr, current->mm->start_stack); | 434 | start_thread(regs, entryaddr, current->mm->start_stack); |
435 | 435 | ||
436 | if (unlikely(current->ptrace & PT_PTRACED)) { | ||
437 | if (current->ptrace & PT_TRACE_EXEC) | ||
438 | ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP); | ||
439 | else | ||
440 | send_sig(SIGTRAP, current, 0); | ||
441 | } | ||
442 | |||
443 | retval = 0; | 436 | retval = 0; |
444 | 437 | ||
445 | error: | 438 | error: |
@@ -477,6 +470,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, | |||
477 | char __user *u_platform, *p; | 470 | char __user *u_platform, *p; |
478 | long hwcap; | 471 | long hwcap; |
479 | int loop; | 472 | int loop; |
473 | int nr; /* reset for each csp adjustment */ | ||
480 | 474 | ||
481 | /* we're going to shovel a whole load of stuff onto the stack */ | 475 | /* we're going to shovel a whole load of stuff onto the stack */ |
482 | #ifdef CONFIG_MMU | 476 | #ifdef CONFIG_MMU |
@@ -549,10 +543,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, | |||
549 | /* force 16 byte _final_ alignment here for generality */ | 543 | /* force 16 byte _final_ alignment here for generality */ |
550 | #define DLINFO_ITEMS 13 | 544 | #define DLINFO_ITEMS 13 |
551 | 545 | ||
552 | nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0); | 546 | nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH; |
553 | #ifdef DLINFO_ARCH_ITEMS | ||
554 | nitems += DLINFO_ARCH_ITEMS; | ||
555 | #endif | ||
556 | 547 | ||
557 | csp = sp; | 548 | csp = sp; |
558 | sp -= nitems * 2 * sizeof(unsigned long); | 549 | sp -= nitems * 2 * sizeof(unsigned long); |
@@ -564,39 +555,46 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, | |||
564 | sp -= sp & 15UL; | 555 | sp -= sp & 15UL; |
565 | 556 | ||
566 | /* put the ELF interpreter info on the stack */ | 557 | /* put the ELF interpreter info on the stack */ |
567 | #define NEW_AUX_ENT(nr, id, val) \ | 558 | #define NEW_AUX_ENT(id, val) \ |
568 | do { \ | 559 | do { \ |
569 | struct { unsigned long _id, _val; } __user *ent; \ | 560 | struct { unsigned long _id, _val; } __user *ent; \ |
570 | \ | 561 | \ |
571 | ent = (void __user *) csp; \ | 562 | ent = (void __user *) csp; \ |
572 | __put_user((id), &ent[nr]._id); \ | 563 | __put_user((id), &ent[nr]._id); \ |
573 | __put_user((val), &ent[nr]._val); \ | 564 | __put_user((val), &ent[nr]._val); \ |
565 | nr++; \ | ||
574 | } while (0) | 566 | } while (0) |
575 | 567 | ||
568 | nr = 0; | ||
576 | csp -= 2 * sizeof(unsigned long); | 569 | csp -= 2 * sizeof(unsigned long); |
577 | NEW_AUX_ENT(0, AT_NULL, 0); | 570 | NEW_AUX_ENT(AT_NULL, 0); |
578 | if (k_platform) { | 571 | if (k_platform) { |
572 | nr = 0; | ||
579 | csp -= 2 * sizeof(unsigned long); | 573 | csp -= 2 * sizeof(unsigned long); |
580 | NEW_AUX_ENT(0, AT_PLATFORM, | 574 | NEW_AUX_ENT(AT_PLATFORM, |
581 | (elf_addr_t) (unsigned long) u_platform); | 575 | (elf_addr_t) (unsigned long) u_platform); |
582 | } | 576 | } |
583 | 577 | ||
578 | nr = 0; | ||
584 | csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long); | 579 | csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long); |
585 | NEW_AUX_ENT( 0, AT_HWCAP, hwcap); | 580 | NEW_AUX_ENT(AT_HWCAP, hwcap); |
586 | NEW_AUX_ENT( 1, AT_PAGESZ, PAGE_SIZE); | 581 | NEW_AUX_ENT(AT_PAGESZ, PAGE_SIZE); |
587 | NEW_AUX_ENT( 2, AT_CLKTCK, CLOCKS_PER_SEC); | 582 | NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC); |
588 | NEW_AUX_ENT( 3, AT_PHDR, exec_params->ph_addr); | 583 | NEW_AUX_ENT(AT_PHDR, exec_params->ph_addr); |
589 | NEW_AUX_ENT( 4, AT_PHENT, sizeof(struct elf_phdr)); | 584 | NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr)); |
590 | NEW_AUX_ENT( 5, AT_PHNUM, exec_params->hdr.e_phnum); | 585 | NEW_AUX_ENT(AT_PHNUM, exec_params->hdr.e_phnum); |
591 | NEW_AUX_ENT( 6, AT_BASE, interp_params->elfhdr_addr); | 586 | NEW_AUX_ENT(AT_BASE, interp_params->elfhdr_addr); |
592 | NEW_AUX_ENT( 7, AT_FLAGS, 0); | 587 | NEW_AUX_ENT(AT_FLAGS, 0); |
593 | NEW_AUX_ENT( 8, AT_ENTRY, exec_params->entry_addr); | 588 | NEW_AUX_ENT(AT_ENTRY, exec_params->entry_addr); |
594 | NEW_AUX_ENT( 9, AT_UID, (elf_addr_t) current->uid); | 589 | NEW_AUX_ENT(AT_UID, (elf_addr_t) current->uid); |
595 | NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid); | 590 | NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->euid); |
596 | NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid); | 591 | NEW_AUX_ENT(AT_GID, (elf_addr_t) current->gid); |
597 | NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid); | 592 | NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->egid); |
598 | 593 | ||
599 | #ifdef ARCH_DLINFO | 594 | #ifdef ARCH_DLINFO |
595 | nr = 0; | ||
596 | csp -= AT_VECTOR_SIZE_ARCH * 2 * sizeof(unsigned long); | ||
597 | |||
600 | /* ARCH_DLINFO must come last so platform specific code can enforce | 598 | /* ARCH_DLINFO must come last so platform specific code can enforce |
601 | * special alignment requirements on the AUXV if necessary (eg. PPC). | 599 | * special alignment requirements on the AUXV if necessary (eg. PPC). |
602 | */ | 600 | */ |
@@ -1573,7 +1571,6 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1573 | struct memelfnote *notes = NULL; | 1571 | struct memelfnote *notes = NULL; |
1574 | struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */ | 1572 | struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */ |
1575 | struct elf_prpsinfo *psinfo = NULL; /* NT_PRPSINFO */ | 1573 | struct elf_prpsinfo *psinfo = NULL; /* NT_PRPSINFO */ |
1576 | struct task_struct *g, *p; | ||
1577 | LIST_HEAD(thread_list); | 1574 | LIST_HEAD(thread_list); |
1578 | struct list_head *t; | 1575 | struct list_head *t; |
1579 | elf_fpregset_t *fpu = NULL; | 1576 | elf_fpregset_t *fpu = NULL; |
@@ -1622,20 +1619,19 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1622 | #endif | 1619 | #endif |
1623 | 1620 | ||
1624 | if (signr) { | 1621 | if (signr) { |
1622 | struct core_thread *ct; | ||
1625 | struct elf_thread_status *tmp; | 1623 | struct elf_thread_status *tmp; |
1626 | rcu_read_lock(); | 1624 | |
1627 | do_each_thread(g,p) | 1625 | for (ct = current->mm->core_state->dumper.next; |
1628 | if (current->mm == p->mm && current != p) { | 1626 | ct; ct = ct->next) { |
1629 | tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); | 1627 | tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); |
1630 | if (!tmp) { | 1628 | if (!tmp) |
1631 | rcu_read_unlock(); | 1629 | goto cleanup; |
1632 | goto cleanup; | 1630 | |
1633 | } | 1631 | tmp->thread = ct->task; |
1634 | tmp->thread = p; | 1632 | list_add(&tmp->list, &thread_list); |
1635 | list_add(&tmp->list, &thread_list); | 1633 | } |
1636 | } | 1634 | |
1637 | while_each_thread(g,p); | ||
1638 | rcu_read_unlock(); | ||
1639 | list_for_each(t, &thread_list) { | 1635 | list_for_each(t, &thread_list) { |
1640 | struct elf_thread_status *tmp; | 1636 | struct elf_thread_status *tmp; |
1641 | int sz; | 1637 | int sz; |