[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