[Crash-utility] [PATCH 2/2] Fix "kmem -s|-S" not working properly when CONFIG_SLAB_FREELIST_HARDENED is enabled

Lianbo Jiang lijiang at redhat.com
Mon Aug 14 01:54:24 UTC 2023


Currently, crash-utility still depends on detecting the kernel version,
or the asm instruction 'bswap' on X86 64/X86 architectures to decide how
to deal with the freelist ptr obfuscation, when kernel option
CONFIG_SLAB_FREELIST_HARDENED is enabled.

As you known, the bit diffusion for freelist ptr obfuscation has
experienced the changes several times on the kernel side, For most
distributions, usually they might backport these kernel patches from
upstream, especially for the old kernel, the 'kmem -s|-S' will fail with
an error "invalid freepointer", which can be observed on ppc64le and
S390x architectures, etc. That is really not friendly.

Given that, let's fix the above issues this time, and it won't rely
on the linux version number or asm instruction 'bswap' to decide how to
dereference the freelist ptr.

Reported-by: Lucas Oakley <soakley at redhat.com>
Signed-off-by: Lianbo Jiang <lijiang at redhat.com>
---
 memory.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/memory.c b/memory.c
index 626c6039c6d9..562914ee9230 100644
--- a/memory.c
+++ b/memory.c
@@ -19654,9 +19654,12 @@ 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))
-			ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr)
-						       : bswap_32(ptr_addr);
+		ulong addr = (sizeof(long) == 8) ? bswap_64(ptr_addr) : bswap_32(ptr_addr);
+		addr = ptr ^ si->random ^ addr;
+
+		if (!addr || accessible(addr))
+			return addr;
+
 		return (ptr ^ si->random ^ ptr_addr);
 	} else
 		return ptr;
-- 
2.37.1



More information about the Crash-utility mailing list