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 4450e82..865f9be 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -37,6 +37,10 @@ #include <asm/page.h> #include <asm/exec.h> +#ifndef user_siginfo_t +#define user_siginfo_t siginfo_t +#endif + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); 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) fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv); } +static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata, + siginfo_t *siginfo) +{ + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + copy_siginfo_to_user((user_siginfo_t __user *) csigdata, siginfo); + set_fs(old_fs); + fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata); +} + #ifdef CORE_DUMP_USE_REGSET #include <linux/regset.h> @@ -1385,7 +1399,9 @@ struct elf_thread_core_info { struct elf_note_info { struct elf_thread_core_info *thread; struct memelfnote psinfo; + struct memelfnote signote; struct memelfnote auxv; + user_siginfo_t csigdata; size_t size; int thread_notes; }; @@ -1559,6 +1575,9 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm); info->size += notesize(&info->psinfo); + fill_siginfo_note(&info->signote, &info->csigdata, siginfo); + info->size += notesize(&info->signote); + fill_auxv_note(&info->auxv, current->mm); info->size += notesize(&info->auxv); @@ -1588,6 +1607,8 @@ static int write_note_info(struct elf_note_info *info, if (first && !writenote(&info->psinfo, file, foffset)) return 0; + if (first && !writenote(&info->signote, file, foffset)) + return 0; if (first && !writenote(&info->auxv, file, foffset)) return 0; @@ -1681,6 +1702,7 @@ struct elf_note_info { #ifdef ELF_CORE_COPY_XFPREGS elf_fpxregset_t *xfpu; #endif + user_siginfo_t csigdata; int thread_status_size; int numnote; }; @@ -1690,8 +1712,8 @@ static int elf_note_info_init(struct elf_note_info *info) memset(info, 0, sizeof(*info)); INIT_LIST_HEAD(&info->thread_list); - /* Allocate space for six ELF notes */ - info->notes = kmalloc(6 * sizeof(struct memelfnote), GFP_KERNEL); + /* Allocate space for ELF notes */ + info->notes = kmalloc(7 * sizeof(struct memelfnote), GFP_KERNEL); if (!info->notes) return 0; info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); @@ -1763,6 +1785,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, info->numnote = 2; + fill_siginfo_note(&info->notes[info->numnote++], &info->csigdata, siginfo); fill_auxv_note(&info->notes[info->numnote++], current->mm); /* Try to dump the FPU. */ diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c index 112e45a..0fbcf63 100644 --- a/fs/compat_binfmt_elf.c +++ b/fs/compat_binfmt_elf.c @@ -38,6 +38,12 @@ #define elf_addr_t Elf32_Addr /* + * Some data types as stored in coredump. + */ +#define user_siginfo_t compat_siginfo_t +#define copy_siginfo_to_user copy_siginfo_to_user32 + +/* * The machine-dependent core note format types are defined in elfcore-compat.h, * which requires asm/elf.h to define compat_elf_gregset_t et al. */ diff --git a/include/linux/elf.h b/include/linux/elf.h index 0a05051..dc62da7 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -372,6 +372,11 @@ typedef struct elf64_shdr { #define NT_PRPSINFO 3 #define NT_TASKSTRUCT 4 #define NT_AUXV 6 +/* + * Note to userspace developers: size of NT_SIGINFO note may increase + * in the future to accomodate more fields, don't assume it is fixed! + */ +#define NT_SIGINFO 0x53494749 #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ |