diff options
-rw-r--r-- | fs/binfmt_elf.c | 27 | ||||
-rw-r--r-- | fs/compat_binfmt_elf.c | 6 | ||||
-rw-r--r-- | include/linux/elf.h | 5 |
3 files changed, 36 insertions, 2 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 4450e82a05aa..865f9be6a2d3 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -37,6 +37,10 @@ | |||
37 | #include <asm/page.h> | 37 | #include <asm/page.h> |
38 | #include <asm/exec.h> | 38 | #include <asm/exec.h> |
39 | 39 | ||
40 | #ifndef user_siginfo_t | ||
41 | #define user_siginfo_t siginfo_t | ||
42 | #endif | ||
43 | |||
40 | static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); | 44 | static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); |
41 | static int load_elf_library(struct file *); | 45 | static int load_elf_library(struct file *); |
42 | static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, | 46 | static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, |
@@ -1372,6 +1376,16 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) | |||
1372 | fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv); | 1376 | fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv); |
1373 | } | 1377 | } |
1374 | 1378 | ||
1379 | static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata, | ||
1380 | siginfo_t *siginfo) | ||
1381 | { | ||
1382 | mm_segment_t old_fs = get_fs(); | ||
1383 | set_fs(KERNEL_DS); | ||
1384 | copy_siginfo_to_user((user_siginfo_t __user *) csigdata, siginfo); | ||
1385 | set_fs(old_fs); | ||
1386 | fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata); | ||
1387 | } | ||
1388 | |||
1375 | #ifdef CORE_DUMP_USE_REGSET | 1389 | #ifdef CORE_DUMP_USE_REGSET |
1376 | #include <linux/regset.h> | 1390 | #include <linux/regset.h> |
1377 | 1391 | ||
@@ -1385,7 +1399,9 @@ struct elf_thread_core_info { | |||
1385 | struct elf_note_info { | 1399 | struct elf_note_info { |
1386 | struct elf_thread_core_info *thread; | 1400 | struct elf_thread_core_info *thread; |
1387 | struct memelfnote psinfo; | 1401 | struct memelfnote psinfo; |
1402 | struct memelfnote signote; | ||
1388 | struct memelfnote auxv; | 1403 | struct memelfnote auxv; |
1404 | user_siginfo_t csigdata; | ||
1389 | size_t size; | 1405 | size_t size; |
1390 | int thread_notes; | 1406 | int thread_notes; |
1391 | }; | 1407 | }; |
@@ -1559,6 +1575,9 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, | |||
1559 | fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm); | 1575 | fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm); |
1560 | info->size += notesize(&info->psinfo); | 1576 | info->size += notesize(&info->psinfo); |
1561 | 1577 | ||
1578 | fill_siginfo_note(&info->signote, &info->csigdata, siginfo); | ||
1579 | info->size += notesize(&info->signote); | ||
1580 | |||
1562 | fill_auxv_note(&info->auxv, current->mm); | 1581 | fill_auxv_note(&info->auxv, current->mm); |
1563 | info->size += notesize(&info->auxv); | 1582 | info->size += notesize(&info->auxv); |
1564 | 1583 | ||
@@ -1588,6 +1607,8 @@ static int write_note_info(struct elf_note_info *info, | |||
1588 | 1607 | ||
1589 | if (first && !writenote(&info->psinfo, file, foffset)) | 1608 | if (first && !writenote(&info->psinfo, file, foffset)) |
1590 | return 0; | 1609 | return 0; |
1610 | if (first && !writenote(&info->signote, file, foffset)) | ||
1611 | return 0; | ||
1591 | if (first && !writenote(&info->auxv, file, foffset)) | 1612 | if (first && !writenote(&info->auxv, file, foffset)) |
1592 | return 0; | 1613 | return 0; |
1593 | 1614 | ||
@@ -1681,6 +1702,7 @@ struct elf_note_info { | |||
1681 | #ifdef ELF_CORE_COPY_XFPREGS | 1702 | #ifdef ELF_CORE_COPY_XFPREGS |
1682 | elf_fpxregset_t *xfpu; | 1703 | elf_fpxregset_t *xfpu; |
1683 | #endif | 1704 | #endif |
1705 | user_siginfo_t csigdata; | ||
1684 | int thread_status_size; | 1706 | int thread_status_size; |
1685 | int numnote; | 1707 | int numnote; |
1686 | }; | 1708 | }; |
@@ -1690,8 +1712,8 @@ static int elf_note_info_init(struct elf_note_info *info) | |||
1690 | memset(info, 0, sizeof(*info)); | 1712 | memset(info, 0, sizeof(*info)); |
1691 | INIT_LIST_HEAD(&info->thread_list); | 1713 | INIT_LIST_HEAD(&info->thread_list); |
1692 | 1714 | ||
1693 | /* Allocate space for six ELF notes */ | 1715 | /* Allocate space for ELF notes */ |
1694 | info->notes = kmalloc(6 * sizeof(struct memelfnote), GFP_KERNEL); | 1716 | info->notes = kmalloc(7 * sizeof(struct memelfnote), GFP_KERNEL); |
1695 | if (!info->notes) | 1717 | if (!info->notes) |
1696 | return 0; | 1718 | return 0; |
1697 | info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); | 1719 | info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); |
@@ -1763,6 +1785,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, | |||
1763 | 1785 | ||
1764 | info->numnote = 2; | 1786 | info->numnote = 2; |
1765 | 1787 | ||
1788 | fill_siginfo_note(&info->notes[info->numnote++], &info->csigdata, siginfo); | ||
1766 | fill_auxv_note(&info->notes[info->numnote++], current->mm); | 1789 | fill_auxv_note(&info->notes[info->numnote++], current->mm); |
1767 | 1790 | ||
1768 | /* Try to dump the FPU. */ | 1791 | /* Try to dump the FPU. */ |
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c index 112e45a17e99..0fbcf6347437 100644 --- a/fs/compat_binfmt_elf.c +++ b/fs/compat_binfmt_elf.c | |||
@@ -38,6 +38,12 @@ | |||
38 | #define elf_addr_t Elf32_Addr | 38 | #define elf_addr_t Elf32_Addr |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Some data types as stored in coredump. | ||
42 | */ | ||
43 | #define user_siginfo_t compat_siginfo_t | ||
44 | #define copy_siginfo_to_user copy_siginfo_to_user32 | ||
45 | |||
46 | /* | ||
41 | * The machine-dependent core note format types are defined in elfcore-compat.h, | 47 | * The machine-dependent core note format types are defined in elfcore-compat.h, |
42 | * which requires asm/elf.h to define compat_elf_gregset_t et al. | 48 | * which requires asm/elf.h to define compat_elf_gregset_t et al. |
43 | */ | 49 | */ |
diff --git a/include/linux/elf.h b/include/linux/elf.h index 0a05051a8924..dc62da7447ca 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h | |||
@@ -372,6 +372,11 @@ typedef struct elf64_shdr { | |||
372 | #define NT_PRPSINFO 3 | 372 | #define NT_PRPSINFO 3 |
373 | #define NT_TASKSTRUCT 4 | 373 | #define NT_TASKSTRUCT 4 |
374 | #define NT_AUXV 6 | 374 | #define NT_AUXV 6 |
375 | /* | ||
376 | * Note to userspace developers: size of NT_SIGINFO note may increase | ||
377 | * in the future to accomodate more fields, don't assume it is fixed! | ||
378 | */ | ||
379 | #define NT_SIGINFO 0x53494749 | ||
375 | #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ | 380 | #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ |
376 | #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ | 381 | #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ |
377 | #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ | 382 | #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ |