diff options
Diffstat (limited to 'fs/binfmt_elf_fdpic.c')
| -rw-r--r-- | fs/binfmt_elf_fdpic.c | 78 |
1 files changed, 37 insertions, 41 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index d051a32e6270..80c1f952ef78 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
| @@ -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; |
