Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
lcrash
lcrash-sanity-check
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File lcrash-sanity-check of Package lcrash
From: Bernhard Walle <bwalle@suse.de> Subject: [PATCH] Check for the validity of mapfile early This patch is to prevent using of wrong mapfiles for debugging. It just reads the value of linux_banner very early during vtop initialisation. We know that linux_banner must start with "Linux version" and it's unlikely to change in future. Mostly, if wrong mapfiles are used, they're completely wrong. So we read garbage here, can detect it and the user gets a clear output message instead of just hangs and crashes. If the check is passed, it's not 100 % that the mapfile is valid. Also, there might be a risk that the memory region around linux_banner is corrupted and the rest is ok. The probability is very low, and for this case the user can just continue debugging -- but he has been warned! Signed-off-by: Bernhard Walle <bwalle@suse.de> --- lib/libklib/include/kl_mem.h | 5 ++ lib/libklib/kl_kern.c | 85 +++++++++++++++++++++++++++++++++++++++++++ lib/libklib/kl_kern_i386.c | 16 ++++++++ lib/libklib/kl_kern_ia64.c | 5 ++ lib/libklib/kl_kern_x86_64.c | 16 +++++++- 5 files changed, 126 insertions(+), 1 deletion(-) --- a/lib/libklib/include/kl_mem.h +++ b/lib/libklib/include/kl_mem.h @@ -98,4 +98,9 @@ kaddr_t kl_next_valid_physaddr(kaddr_t); kaddr_t kl_fix_vaddr(kaddr_t, size_t); int kl_init_virtop(void); +/* + * other stuff + */ +int kl_linux_banner_valid(kaddr_t (*simple_vtop)(kaddr_t)); + #endif /* __KL_MEM_H */ --- a/lib/libklib/kl_kern.c +++ b/lib/libklib/kl_kern.c @@ -49,6 +49,91 @@ kl_valid_physmem(kaddr_t addr, int size) return(1); } +static uint8_t +kl_read_uint8_simple(kaddr_t (*simple_vtop)(kaddr_t), kaddr_t vaddr) +{ + if (simple_vtop) { + kaddr_t paddr = simple_vtop(vaddr); + return KLP->dump->func.read_uint8(paddr); + } else { + return KLP->dump->func.vread_uint8(vaddr); + } +} + +static kaddr_t +kl_read_ptr_simple(kaddr_t (*simple_vtop)(kaddr_t), kaddr_t vaddr) +{ + if (simple_vtop) { + kaddr_t paddr = simple_vtop(vaddr); + return KLP->dump->func.read_ptr(paddr); + } else { + return KLP->dump->func.vread_ptr(vaddr); + } +} + +/* + * Name: kl_linux_banner_valid() + * Func: This function checks if the global symbol "linux_banner" contains valid + * data, i.e. starts with "Linux version". This is to simply check if the + * given mapfile fits to the memory dump corefile. Wrong mapfiles can + * lead to vaious strange error messages afterwards, and this should be + * a clear indicator to avoid strange error messages and give a clear + * message. + * The function returns FALSE if the value is invalid, and TRUE if it's valid. + */ +int +kl_linux_banner_valid(kaddr_t (*simple_vtop)(kaddr_t)) +{ + const char reference[] = "Linux version"; + const char *refptr; + syment_t *sp; + kaddr_t addr; + kaddr_t location; + int check_valid; + + sp = kl_lkup_symname("linux_banner"); + if (!sp) { + fprintf(KL_ERRORFP, "Lookup of linux_banner has failed\n"); + return(0); + } + addr = sp->s_addr; + + + /* + * try char linux_banner[] first (new kernels) + */ + + check_valid = 1; + location = addr; + refptr = reference; + while (*refptr) { + uint8_t val = kl_read_uint8_simple(simple_vtop, location++); + if (*refptr++ != (char)val) { + check_valid = 0; + break; + } + } + + /* + * and now try char *linux_banner (old kernels) + */ + if (!check_valid) { + location = kl_read_ptr_simple(simple_vtop, addr); + refptr = reference; + check_valid = 1; + + while (*refptr) { + uint8_t val = kl_read_uint8_simple(simple_vtop, location++); + if (*refptr++ != (char)val) { + check_valid = 0; + break; + } + } + } + + return check_valid; +} + /* * Name: kl_valid_physaddr() * Func: Returns 1 if a physical address represents valid physical --- a/lib/libklib/kl_kern_i386.c +++ b/lib/libklib/kl_kern_i386.c @@ -90,6 +90,17 @@ kl_fix_vaddr_i386(kaddr_t vaddr, size_t } /* + * Name: simple_vtop + * Func: Simple virtual to physical address translation if the virtual address + * is in kernel text + */ +static kaddr_t +simple_vtop(kaddr_t vaddr) +{ + return vaddr - KL_PAGE_OFFSET_I386; +} + +/* * Name: kl_init_virtop_i386() * Func: initialize virtual to physical address translation * This function must at least initialize high_memory and init_mm. @@ -105,6 +116,11 @@ kl_init_virtop_i386(void) return ret; } + if (!kl_linux_banner_valid(simple_vtop)) { + fprintf(KL_ERRORFP, "\nlinux_banner contains invalid data - " + "most likely your mapfile is invalid."); + } + /* Get the cr4 settings. This will tell us if the system is PAE enabled * */ --- a/lib/libklib/kl_kern_ia64.c +++ b/lib/libklib/kl_kern_ia64.c @@ -911,6 +911,11 @@ kl_init_virtop_ia64(void) } else { VMALLOC_END = 0xafffffffffffffff; } + + if (!kl_linux_banner_valid(simple_vtop)) { + fprintf(KL_ERRORFP, "\nlinux_banner contains invalid data - " + "most likely your mapfile is invalid."); + } check_arch_ia64(); --- a/lib/libklib/kl_kern_x86_64.c +++ b/lib/libklib/kl_kern_x86_64.c @@ -94,6 +94,17 @@ kl_fix_vaddr_x86_64(kaddr_t vaddr, size_ } /* + * Name: simple_vtop + * Func: Simple virtual to physical address translation if the virtual address + * is in kernel text + */ +static kaddr_t +simple_vtop(kaddr_t vaddr) +{ + return vaddr - KL_START_KERNEL_map_X86_64; +} + +/* * Name: kl_init_virtop_x86_64() * Func: initialize virtual to physical address translation * This function must at least initialize high_memory and init_mm. @@ -122,7 +133,10 @@ kl_init_virtop_x86_64(void) KL_HIGH_MEMORY = (kaddr_t) -1; } - + if (!kl_linux_banner_valid(simple_vtop)) { + fprintf(KL_ERRORFP, "\nlinux_banner contains invalid data - " + "most likely your mapfile is invalid."); + } /* Get the address of init_mm and convert it to a physical address * so that we can make direct calls to kl_readmem(). We make a call
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor