On Sat, May 29, 2021 at 4:43 AM Kazuhito Hagio <kazuhito.hagio(a)gmail.com>
wrote:
> -----Original Message-----
> > Linux 5.7 and later kernels that contain kernel commit <1ad53d9fa3f6>
> > ("slub: improve bit diffusion for freelist ptr obfuscation") changed
> > the calculation formula in the freelist_ptr(), which added a swab()
> > call to mix bits a little more. When kernel is built with the
> > "CONFIG_SLAB_FREELIST_HARDENED=y",the "kmem -s" option
fails with the
> > following errors, if there is no such patch.
> >
> > crash> kmem -s
> > CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
> > 82166d00 144 0 0 0 4k
fuse_request
> > 82166e00 792 0 0 0 16k
fuse_inode
> > 87201e00 528 0 0 0 8k xfs_dqtrx
> > 87201f00 496 0 0 0 8k xfs_dquot
> > kmem: xfs_buf: slab: 37202e6e900 invalid freepointer: b844bab900001d70
> > kmem: xfs_buf: slab: 3720250fd80 invalid freepointer: b8603f9400001370
> > ...
>
> Good catch! And the patch diff looks good to me.
Sorry, I completely misread the code.. Please ignore the comments below.
I will check again next week.
No worry. Thanks for the review.
Thanks,
Kazu
>
> But the freelist_ptr() function, which is patched, is called only when
> the error message is NOT printed. So it seems like the patch does not
> stop the message, right?
No, the patch fixes the above errors. Upstream kernel has changed the
calculation
formula in the
freelist_ptr() as below(marked it with "^^^^"), which added the
"swab()"
operation, crash also needs
to follow up this change, otherwise crash will get the error of "invalid
freepointer".
diff --git a/mm/slub.c b/mm/slub.c
index fc911c222b11..bc949e3428c9 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -259,7 +259,7 @@ static inline void *freelist_ptr(const struct
kmem_cache *s, void *ptr,
* freepointer to be restored incorrectly.
*/
return (void *)((unsigned long)ptr ^ s->random ^
- (unsigned long)kasan_reset_tag((void *)ptr_addr));
+ *swab*((unsigned long)kasan_reset_tag((void
*)ptr_addr)));
* ^^^^^*
Before:
crash> kmem -s
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
c0000000311a4200 152 0 0 0 64k fuse_request
c0000000311a8700 800 0 0 0 64k fuse_inode
c000000035df7600 528 0 0 0 64k xfs_dqtrx
c000000035df6600 496 0 0 0 64k xfs_dquot
kmem: xfs_buf: slab: c00c0000000b6500 invalid freepointer: 3808942d00004eb0
kmem: xfs_buf: slab: c00c00000116ba00 invalid freepointer: b83fe85a040027b0
...
After:
crash> kmem -s
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
c0000000311a4200 152 0 0 0 64k fuse_request
c0000000311a8700 800 0 0 0 64k fuse_inode
c000000035df7600 528 0 0 0 64k xfs_dqtrx
c000000035df6600 496 0 0 0 64k xfs_dquot
c000000035dff500 360 7865 9010 53 64k xfs_buf
...
Thanks.
Lianbo