The new version of makedumpfile 1.4.0 allows user to filter out kernel data (e.g. security keys, confidential/secret information etc.) from the vmcore. The data to be filtered out is poisoned with character 'X' (0x58 in Hex). The filtered ELF kdump now carries a new ELF note section "ERASEINFO" that contains eraseinfo data. The filtered compressed kdump now contains new members (offset_eraseinfo, size_eraseinfo) int the sub header with new header version 5. With the above change in place, there may be instances where the filtered dumpfile may not be readable OR may not be helpful in analyzing the problem using crash tool. Most of the time crash tool will be able to read/analyze the dump unless someone scrubs out the data on which crash utility is dependent on. Hence, This patch adds support into crash utility to detect the above changes and show early warning message to the user about the fact that he is dealing with filtered dumpfile. This patch adds support for "help -n" output to display the filter data strings that are appended to the dumpfile or stored in an ELF note. Signed-off-by: Mahesh Salgaonkar <mahesh@xxxxxxxxxxxxxxxxxx> --- defs.h | 1 + diskdump.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diskdump.h | 2 ++ main.c | 5 +++++ netdump.c | 22 ++++++++++++++++------ 5 files changed, 84 insertions(+), 6 deletions(-) Index: crash-5.1.7/defs.h =================================================================== --- crash-5.1.7.orig/defs.h +++ crash-5.1.7/defs.h @@ -431,6 +431,7 @@ struct program_context { #define FLAT (0x1ULL) #define ELF_NOTES (0x2ULL) #define GET_OSRELEASE (0x4ULL) +#define ERASEINFO_DATA (0x8ULL) #define FLAT_FORMAT() (pc->flags2 & FLAT) #define ELF_NOTES_VALID() (pc->flags2 & ELF_NOTES) char *cleanup; Index: crash-5.1.7/main.c =================================================================== --- crash-5.1.7.orig/main.c +++ crash-5.1.7/main.c @@ -603,6 +603,11 @@ main(int argc, char **argv) void main_loop(void) { + if (pc->flags2 & ERASEINFO_DATA) + error(WARNING, "\nFile %s may not be readable/analyzable. Some" + " of the kernel data from the dump has been scrubbed" + " out\n", pc->dumpfile); + if (!(pc->flags & GDB_INIT)) { gdb_session_init(); show_untrusted_files(); Index: crash-5.1.7/netdump.c =================================================================== --- crash-5.1.7.orig/netdump.c +++ crash-5.1.7/netdump.c @@ -1636,13 +1636,13 @@ dump_Elf32_Nhdr(Elf32_Off offset, int st char buf[BUFSIZE]; char *ptr; ulong *uptr; - int xen_core, vmcoreinfo; + int xen_core, vmcoreinfo, eraseinfo; uint64_t remaining, notesize; note = (Elf32_Nhdr *)((char *)nd->elf32 + offset); BZERO(buf, BUFSIZE); - xen_core = vmcoreinfo = FALSE; + xen_core = vmcoreinfo = eraseinfo = FALSE; ptr = (char *)note + sizeof(Elf32_Nhdr); if (ptr > (nd->elf_header + nd->header_size)) { @@ -1730,6 +1730,7 @@ dump_Elf32_Nhdr(Elf32_Off offset, int st default: xen_core = STRNEQ(buf, "XEN CORE") || STRNEQ(buf, "Xen"); vmcoreinfo = STRNEQ(buf, "VMCOREINFO"); + eraseinfo = STRNEQ(buf, "ERASEINFO"); if (xen_core) { netdump_print("(unknown Xen n_type)\n"); if (store) @@ -1739,6 +1740,10 @@ dump_Elf32_Nhdr(Elf32_Off offset, int st netdump_print("(unused)\n"); nd->vmcoreinfo = (char *)(ptr + note->n_namesz + 1); nd->size_vmcoreinfo = note->n_descsz; + } else if (eraseinfo) { + netdump_print("(unused)\n"); + if (note->n_descsz) + pc->flags2 |= ERASEINFO_DATA; } else netdump_print("(?)\n"); break; @@ -1813,7 +1818,7 @@ dump_Elf32_Nhdr(Elf32_Off offset, int st if (xen_core) uptr = (ulong *)roundup((ulong)uptr, 4); - if (vmcoreinfo) { + if (vmcoreinfo || eraseinfo) { netdump_print(" "); ptr += note->n_namesz + 1; for (i = 0; i < note->n_descsz; i++, ptr++) { @@ -1856,14 +1861,14 @@ dump_Elf64_Nhdr(Elf64_Off offset, int st ulonglong *uptr; int *iptr; ulong *up; - int xen_core, vmcoreinfo; + int xen_core, vmcoreinfo, eraseinfo; uint64_t remaining, notesize; note = (Elf64_Nhdr *)((char *)nd->elf64 + offset); BZERO(buf, BUFSIZE); ptr = (char *)note + sizeof(Elf64_Nhdr); - xen_core = vmcoreinfo = FALSE; + xen_core = vmcoreinfo = eraseinfo = FALSE; if (ptr > (nd->elf_header + nd->header_size)) { error(WARNING, @@ -1981,6 +1986,7 @@ dump_Elf64_Nhdr(Elf64_Off offset, int st default: xen_core = STRNEQ(buf, "XEN CORE") || STRNEQ(buf, "Xen"); vmcoreinfo = STRNEQ(buf, "VMCOREINFO"); + eraseinfo = STRNEQ(buf, "ERASEINFO"); if (xen_core) { netdump_print("(unknown Xen n_type)\n"); if (store) @@ -1997,6 +2003,10 @@ dump_Elf64_Nhdr(Elf64_Off offset, int st if (READ_PAGESIZE_FROM_VMCOREINFO() && store) nd->page_size = (uint) vmcoreinfo_read_integer("PAGESIZE", 0); + } else if (eraseinfo) { + netdump_print("(unused)\n"); + if (note->n_descsz) + pc->flags2 |= ERASEINFO_DATA; } else netdump_print("(?)\n"); break; @@ -2090,7 +2100,7 @@ dump_Elf64_Nhdr(Elf64_Off offset, int st lf = 0; netdump_print("%08lx ", *iptr++); } - } else if (vmcoreinfo) { + } else if (vmcoreinfo || eraseinfo) { netdump_print(" "); ptr += note->n_namesz + 1; for (i = 0; i < note->n_descsz; i++, ptr++) { Index: crash-5.1.7/diskdump.c =================================================================== --- crash-5.1.7.orig/diskdump.c +++ crash-5.1.7/diskdump.c @@ -516,6 +516,12 @@ restart: machdep->process_elf_notes(dd->notes_buf, size); } + /* Check if dump file contains erasesinfo data */ + if (KDUMP_CMPRS_VALID() && (dd->header->header_version >= 5) && + (sub_header_kdump->offset_eraseinfo) && + (sub_header_kdump->size_eraseinfo)) + pc->flags2 |= ERASEINFO_DATA; + /* For split dumpfile */ if (KDUMP_CMPRS_VALID()) { is_split = ((dd->header->header_version >= 2) && @@ -1016,6 +1022,50 @@ err: } static void +dump_eraseinfo(FILE *fp) +{ + char *buf = NULL; + unsigned long i = 0; + unsigned long size_eraseinfo = dd->sub_header_kdump->size_eraseinfo; + off_t offset = dd->sub_header_kdump->offset_eraseinfo; + const off_t failed = (off_t)-1; + + if ((buf = malloc(size_eraseinfo)) == NULL) { + error(FATAL, "compressed kdump: cannot malloc eraseinfo" + " buffer\n"); + } + + if (FLAT_FORMAT()) { + if (!read_flattened_format(dd->dfd, offset, buf, size_eraseinfo)) { + error(INFO, "compressed kdump: cannot read eraseinfo data\n"); + goto err; + } + } else { + if (lseek(dd->dfd, offset, SEEK_SET) == failed) { + error(INFO, "compressed kdump: cannot lseek dump eraseinfo\n"); + goto err; + } + if (read(dd->dfd, buf, size_eraseinfo) < size_eraseinfo) { + error(INFO, "compressed kdump: cannot read eraseinfo data\n"); + goto err; + } + } + + fprintf(fp, " "); + for (i = 0; i < size_eraseinfo; i++) { + fprintf(fp, "%c", buf[i]); + if (buf[i] == '\n') + fprintf(fp, " "); + } + if (buf[i - 1] != '\n') + fprintf(fp, "\n"); +err: + if (buf) + free(buf); + return; +} + +static void dump_nt_prstatus_offset(FILE *fp) { struct kdump_sub_header *sub_header_kdump = dd->sub_header_kdump; @@ -1260,6 +1310,16 @@ __diskdump_memory_dump(FILE *fp) } dump_nt_prstatus_offset(fp); } + if (dh->header_version >= 5) { + fprintf(fp, " offset_eraseinfo: %lx\n", + (ulong)dd->sub_header_kdump->offset_eraseinfo); + fprintf(fp, " size_eraseinfo: %lu\n", + dd->sub_header_kdump->size_eraseinfo); + if (dd->sub_header_kdump->offset_eraseinfo && + dd->sub_header_kdump->size_eraseinfo) { + dump_eraseinfo(fp); + } + } fprintf(fp, "\n"); } else fprintf(fp, "(n/a)\n\n"); Index: crash-5.1.7/diskdump.h =================================================================== --- crash-5.1.7.orig/diskdump.h +++ crash-5.1.7/diskdump.h @@ -67,6 +67,8 @@ struct kdump_sub_header { unsigned long size_vmcoreinfo; /* header_version 3 and later */ off_t offset_note; /* header_version 4 and later */ unsigned long size_note; /* header_version 4 and later */ + off_t offset_eraseinfo; /* header_version 5 and later */ + unsigned long size_eraseinfo; /* header_version 5 and later */ }; /* page flags */ -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility