Hi Georges, Thanks for the update. On 2023/02/07 23:02, Aureau, Georges (Kernel Tools ERT) wrote: > Hello Kazu, > > Thanks tons for your valuable comments, below is round #2. > > With respect to the RHEL8 crash patch, it consisted of simply removing the 'if (THIS_KERNEL_VERSION >= LINUX(5,7,0))' from freelist_ptr(), suited for RHEL8.6/RHEL8.7, but obviously not for upstream. Right, when RHEL8.6 enabled the CONFIG_SLAB_FREELIST_HARDENED, it already had 1ad53d9fa3f6, so it's enough for RHEL8 crash to only check VALID_MEMBER(kmem_cache_random). > > Cheers, > Georges > -- > diff --git a/defs.h b/defs.h > index 33a823b..56d6cf4 100644 > --- a/defs.h > +++ b/defs.h > @@ -2638,6 +2638,7 @@ struct vm_table { /* kernel VM-related data */ > #define SLAB_OVERLOAD_PAGE (0x8000000) > #define SLAB_CPU_CACHE (0x10000000) > #define SLAB_ROOT_CACHES (0x20000000) > +#define FREELIST_PTR_BSWAP (0x40000000) With the following code showing it, Acked-by: Kazuhito Hagio <k-hagio-ab@xxxxxxx> --- a/memory.c +++ b/memory.c @@ -13932,6 +13932,8 @@ dump_vm_table(int verbose) fprintf(fp, "%sSLAB_CPU_CACHE", others++ ? "|" : "");\ if (vt->flags & SLAB_ROOT_CACHES) fprintf(fp, "%sSLAB_ROOT_CACHES", others++ ? "|" : "");\ + if (vt->flags & FREELIST_PTR_BSWAP) + fprintf(fp, "%sFREELIST_PTR_BSWAP", others++ ? "|" : "");\ if (vt->flags & USE_VMAP_AREA) fprintf(fp, "%sUSE_VMAP_AREA", others++ ? "|" : "");\ if (vt->flags & CONFIG_NUMA) Could I have your Signed-off-by: tag? Or it's helpful for us if you would send a formal patch with the above diff. Thanks, Kazu > > #define IS_FLATMEM() (vt->flags & FLATMEM) > #define IS_DISCONTIGMEM() (vt->flags & DISCONTIGMEM) > diff --git a/memory.c b/memory.c > index 5141fbe..b235b7c 100644 > --- a/memory.c > +++ b/memory.c > @@ -320,6 +320,7 @@ static void dump_per_cpu_offsets(void); > static void dump_page_flags(ulonglong); > static ulong kmem_cache_nodelists(ulong); > static void dump_hstates(void); > +static void freelist_ptr_init(void); > static ulong freelist_ptr(struct meminfo *, ulong, ulong); > static ulong handle_each_vm_area(struct handle_each_vm_area_args *); > > @@ -370,7 +371,6 @@ mem_init(void) > DISPLAY_DEFAULT = (sizeof(long) == 8) ? DISPLAY_64 : DISPLAY_32; > } > > - > /* > * Stash a few popular offsets and some basic kernel virtual memory > * items used by routines in this file. > @@ -789,6 +789,8 @@ vm_init(void) > MEMBER_OFFSET_INIT(kmem_cache_name, "kmem_cache", "name"); > MEMBER_OFFSET_INIT(kmem_cache_flags, "kmem_cache", "flags"); > MEMBER_OFFSET_INIT(kmem_cache_random, "kmem_cache", "random"); > + if (VALID_MEMBER(kmem_cache_random)) > + freelist_ptr_init(); > MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist"); > MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "page"); > if (INVALID_MEMBER(kmem_cache_cpu_page)) > @@ -19519,13 +19521,65 @@ count_free_objects(struct meminfo *si, ulong freelist) > return c; > } > > +/* > + * With CONFIG_SLAB_FREELIST_HARDENED, freelist_ptr's are crypted with xor's, > + * and for recent release with an additionnal bswap. Some releases prio to 5.7.0 > + * may be using the additionnal bswap. The only easy and reliable way to tell is > + * to inspect assembly code (eg. "__slab_free") for a bswap instruction. > + */ > +static int > +freelist_ptr_bswap_x86(void) > +{ > + struct syment *sp, *spn; > + char buf1[BUFSIZE]; > + char buf2[BUFSIZE]; > + char *arglist[MAXARGS]; > + ulong vaddr; > + int found; > + > + if (!(sp = symbol_search("__slab_free")) || > + !(spn = next_symbol(NULL, sp))) > + return FALSE; > + > + sprintf(buf1, "x/%ldi 0x%lx", spn->value - sp->value, sp->value); > + > + found = FALSE; > + vaddr = 0; > + open_tmpfile(); > + gdb_pass_through(buf1, pc->tmpfile, GNU_RETURN_ON_ERROR); > + rewind(pc->tmpfile); > + while (fgets(buf2, BUFSIZE, pc->tmpfile)) { > + if (parse_line(buf2, arglist) < 3) > + continue; > + > + if ((vaddr = htol(strip_ending_char(arglist[0], ':'), > + RETURN_ON_ERROR|QUIET, NULL)) >= spn->value) > + continue; > + > + if (STREQ(arglist[2], "bswap")) { > + found = TRUE; > + break; > + } > + } > + close_tmpfile(); > + return found; > +} > + > +static void > +freelist_ptr_init(void) > +{ > + if (THIS_KERNEL_VERSION >= LINUX(5,7,0) || > + ((machine_type("X86_64") || machine_type("X86")) && freelist_ptr_bswap_x86())) > + vt->flags |= FREELIST_PTR_BSWAP; > +} > + > static ulong > freelist_ptr(struct meminfo *si, ulong ptr, ulong ptr_addr) > { > if (VALID_MEMBER(kmem_cache_random)) { > /* CONFIG_SLAB_FREELIST_HARDENED */ > > - if (THIS_KERNEL_VERSION >= LINUX(5,7,0)) > + if (vt->flags & FREELIST_PTR_BSWAP) > ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr) > : bswap_32(ptr_addr); > return (ptr ^ si->random ^ ptr_addr); -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki