[PATCH 3/3] elf: distinguish ELF note types by ELF note name space
HATAYAMA Daisuke
d.hatayama at jp.fujitsu.com
Sun Mar 3 23:18:40 EST 2013
In ELF, the same integers for two note type represent different
meanings if the names they belong to are different. However,
get_pt_note_info() doesn't distinguish note types by name space, due
to which, for example, any new note type in "VMCOREINFO" name space is
wrongly interpretted as NT_PRSTATUS or the unique note type in
"VMCOREINFO" name space. This patch checks first ELF note names
explicitly and then ELF note types.
Signed-off-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com>
---
elf_info.c | 76 +++++++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 54 insertions(+), 22 deletions(-)
diff --git a/elf_info.c b/elf_info.c
index f9c554d..9bd8cd0 100644
--- a/elf_info.c
+++ b/elf_info.c
@@ -254,6 +254,23 @@ note_type(void *note)
}
static int
+note_namesz(void *note)
+{
+ int size;
+ Elf64_Nhdr *note64;
+ Elf32_Nhdr *note32;
+
+ if (is_elf64_memory()) {
+ note64 = (Elf64_Nhdr *)note;
+ size = note64->n_namesz;
+ } else {
+ note32 = (Elf32_Nhdr *)note;
+ size = note32->n_namesz;
+ }
+ return size;
+}
+
+static int
note_descsz(void *note)
{
int size;
@@ -290,7 +307,7 @@ offset_note_desc(void *note)
static int
get_pt_note_info(void)
{
- int n_type, size_desc;
+ int n_type, size_name, size_desc;
off_t offset, offset_desc;
char buf[VMCOREINFO_XEN_NOTE_NAME_BYTES];
char note[MAX_SIZE_NHDR];
@@ -308,40 +325,51 @@ get_pt_note_info(void)
name_memory, strerror(errno));
return FALSE;
}
+
+ n_type = note_type(note);
+ size_name = note_namesz(note);
+ size_desc = note_descsz(note);
+ offset_desc = offset + offset_note_desc(note);
+
+ if (!size_name || size_name >= sizeof(buf))
+ goto next_note;
+
if (read(fd_memory, &buf, sizeof(buf)) != sizeof(buf)) {
ERRMSG("Can't read the dump memory(%s). %s\n",
name_memory, strerror(errno));
return FALSE;
}
- n_type = note_type(note);
- if (n_type == NT_PRSTATUS) {
- nr_cpus++;
- offset += offset_next_note(note);
- continue;
- }
- offset_desc = offset + offset_note_desc(note);
- size_desc = note_descsz(note);
+ if (!strncmp(KEXEC_CORE_NOTE_NAME, buf,
+ KEXEC_CORE_NOTE_NAME_BYTES)) {
+ if (n_type == NT_PRSTATUS) {
+ nr_cpus++;
+ }
- if (!strncmp(VMCOREINFO_NOTE_NAME, buf,
- VMCOREINFO_NOTE_NAME_BYTES)) {
- set_vmcoreinfo(offset_desc, size_desc);
+ } else if (!strncmp(VMCOREINFO_NOTE_NAME, buf,
+ VMCOREINFO_NOTE_NAME_BYTES)) {
+ if (n_type == 0) {
+ set_vmcoreinfo(offset_desc, size_desc);
+ }
/*
* Check whether /proc/vmcore contains vmcoreinfo,
* and get both the offset and the size.
*/
} else if (!strncmp(VMCOREINFO_XEN_NOTE_NAME, buf,
- VMCOREINFO_XEN_NOTE_NAME_BYTES)) {
- offset_vmcoreinfo_xen = offset_desc;
- size_vmcoreinfo_xen = size_desc;
+ VMCOREINFO_XEN_NOTE_NAME_BYTES)) {
+ if (n_type == 0) {
+ offset_vmcoreinfo_xen = offset_desc;
+ size_vmcoreinfo_xen = size_desc;
+ }
/*
* Check whether /proc/vmcore contains xen's note.
*/
- } else if (n_type == XEN_ELFNOTE_CRASH_INFO) {
- flags_memory |= MEMORY_XEN;
- offset_xen_crash_info = offset_desc;
- size_xen_crash_info = size_desc;
-
+ } else if (!strncmp("Xen", buf, 4)) {
+ if (n_type == XEN_ELFNOTE_CRASH_INFO) {
+ flags_memory |= MEMORY_XEN;
+ offset_xen_crash_info = offset_desc;
+ size_xen_crash_info = size_desc;
+ }
/*
* Check whether a source dumpfile contains eraseinfo.
* /proc/vmcore does not contain eraseinfo, because eraseinfo
@@ -349,9 +377,13 @@ get_pt_note_info(void)
* create /proc/vmcore.
*/
} else if (!strncmp(ERASEINFO_NOTE_NAME, buf,
- ERASEINFO_NOTE_NAME_BYTES)) {
- set_eraseinfo(offset_desc, size_desc);
+ ERASEINFO_NOTE_NAME_BYTES)) {
+ if (n_type == 0) {
+ set_eraseinfo(offset_desc, size_desc);
+ }
}
+
+ next_note:
offset += offset_next_note(note);
}
if (is_xen_memory())
More information about the kexec
mailing list