From: Denys Vlasenko <vda.linux@googlemail.com>
To: Oleg Nesterov <oleg@redhat.com>,
linux-kernel@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
Amerigo Wang <amwang@redhat.com>,
"Jonathan M. Foote" <jmfoote@cert.org>,
Roland McGrath <roland@hack.frob.com>,
Pedro Alves <palves@redhat.com>
Cc: Denys Vlasenko <vda.linux@googlemail.com>
Subject: [PATCH -mm v2] coredump: extend core dump note section to contain file names of mapped files
Date: Tue, 18 Sep 2012 16:55:29 +0200 [thread overview]
Message-ID: <1347980129-1510-1-git-send-email-vda.linux@googlemail.com> (raw)
This note has the following format:
long count -- how many files are mapped
long page_size -- units for file_ofs
array of [COUNT] elements of
long start
long end
long file_ofs
followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL...
If file name is not available, "" string is encoded.
Changes since previous version: rediffed on top of NT_SIGINFO patches.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
fs/binfmt_elf.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++--
include/linux/elf.h | 1 +
2 files changed, 82 insertions(+), 4 deletions(-)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 6872e45..843d5ea 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1380,6 +1380,72 @@ static void fill_siginfo_note(struct memelfnote *note, siginfo_t *csigdata, sigi
fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata);
}
+#define MAX_FILE_NOTE_SIZE (4*1024*1024)
+
+static void fill_files_note(struct memelfnote *note)
+{
+ struct vm_area_struct *vma;
+ struct file *file;
+ unsigned count, word_count, size, remaining;
+ long *data;
+ long *start_end_ofs;
+ char *name;
+
+ count = 0;
+ for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+ file = vma->vm_file;
+ if (!file)
+ continue;
+ count++;
+ }
+
+ size = count * 64;
+ word_count = 2 + 3 * count;
+ alloc:
+ if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */
+ goto err;
+ size = round_up(size, PAGE_SIZE);
+ data = vmalloc(size);
+ if (!data)
+ goto err;
+
+ start_end_ofs = data;
+ name = (void*)&start_end_ofs[word_count];
+ remaining = size - word_count * sizeof(long);
+
+ *start_end_ofs++ = count;
+ *start_end_ofs++ = PAGE_SIZE;
+ for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+ const char *filename;
+
+ file = vma->vm_file;
+ if (!file)
+ continue;
+ filename = d_path(&file->f_path, name, remaining);
+ if (IS_ERR(filename)) {
+ if (PTR_ERR(filename) == -ENAMETOOLONG) {
+ vfree(data);
+ size = size * 5 / 4;
+ goto alloc;
+ }
+ /* continue; - WRONG, we must have COUNT elements */
+ filename = "";
+ }
+ /* d_path() fills at the end, move it to front */
+ do
+ remaining--;
+ while ((*name++ = *filename++) != '\0');
+
+ *start_end_ofs++ = vma->vm_start;
+ *start_end_ofs++ = vma->vm_end;
+ *start_end_ofs++ = vma->vm_pgoff;
+ }
+
+ size = name - (char*)data;
+ fill_note(note, "CORE", NT_FILE, size, data);
+ err: ;
+}
+
#ifdef CORE_DUMP_USE_REGSET
#include <linux/regset.h>
@@ -1395,6 +1461,7 @@ struct elf_note_info {
struct memelfnote psinfo;
struct memelfnote signote;
struct memelfnote auxv;
+ struct memelfnote files;
siginfo_t csigdata;
size_t size;
int thread_notes;
@@ -1575,6 +1642,9 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
fill_auxv_note(&info->auxv, current->mm);
info->size += notesize(&info->auxv);
+ fill_files_note(&info->files);
+ info->size += notesize(&info->files);
+
return 1;
}
@@ -1605,6 +1675,8 @@ static int write_note_info(struct elf_note_info *info,
return 0;
if (first && !writenote(&info->auxv, file, foffset))
return 0;
+ if (first && !writenote(&info->files, file, foffset))
+ return 0;
for (i = 1; i < info->thread_notes; ++i)
if (t->notes[i].data &&
@@ -1631,6 +1703,7 @@ static void free_note_info(struct elf_note_info *info)
kfree(t);
}
kfree(info->psinfo.data);
+ vfree(info->files.data);
}
#else
@@ -1707,7 +1780,7 @@ static int elf_note_info_init(struct elf_note_info *info)
INIT_LIST_HEAD(&info->thread_list);
/* Allocate space for ELF notes */
- info->notes = kmalloc(7 * sizeof(struct memelfnote), GFP_KERNEL);
+ info->notes = kmalloc(8 * sizeof(struct memelfnote), GFP_KERNEL);
if (!info->notes)
return 0;
info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL);
@@ -1777,10 +1850,11 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
fill_note(info->notes + 1, "CORE", NT_PRPSINFO,
sizeof(*info->psinfo), info->psinfo);
- info->numnote = 2;
+ fill_siginfo_note(info->notes + 2, &info->csigdata, siginfo);
+ fill_auxv_note(info->notes + 3, current->mm);
+ fill_files_note(info->notes + 4);
- fill_siginfo_note(&info->notes[info->numnote++], &info->csigdata, siginfo);
- fill_auxv_note(&info->notes[info->numnote++], current->mm);
+ info->numnote = 5;
/* Try to dump the FPU. */
info->prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs,
@@ -1842,6 +1916,9 @@ static void free_note_info(struct elf_note_info *info)
kfree(list_entry(tmp, struct elf_thread_status, list));
}
+ /* Free data allocated by fill_files_note(): */
+ vfree(info->notes[4].data);
+
kfree(info->prstatus);
kfree(info->psinfo);
kfree(info->notes);
diff --git a/include/linux/elf.h b/include/linux/elf.h
index dc62da7..59ef406 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -377,6 +377,7 @@ typedef struct elf64_shdr {
* in the future to accomodate more fields, don't assume it is fixed!
*/
#define NT_SIGINFO 0x53494749
+#define NT_FILE 0x46494c45
#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 */
--
1.7.7.6
next reply other threads:[~2012-09-18 14:55 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-18 14:55 Denys Vlasenko [this message]
2012-09-18 15:36 ` [PATCH -mm v2] coredump: extend core dump note section to contain file names of mapped files Oleg Nesterov
2012-09-18 16:47 ` Jonathan M. Foote
2012-09-18 16:58 ` Roland McGrath
2012-09-18 17:27 ` Oleg Nesterov
2012-09-18 17:36 ` Oleg Nesterov
2012-09-18 17:47 ` Oleg Nesterov
2012-09-19 11:50 ` Oleg Nesterov
2012-09-19 16:16 ` Denys Vlasenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1347980129-1510-1-git-send-email-vda.linux@googlemail.com \
--to=vda.linux@googlemail.com \
--cc=akpm@linux-foundation.org \
--cc=amwang@redhat.com \
--cc=jmfoote@cert.org \
--cc=linux-kernel@vger.kernel.org \
--cc=oleg@redhat.com \
--cc=palves@redhat.com \
--cc=roland@hack.frob.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.