Messages in this thread | | | Subject | Re: general protection fault with prefetch_freepointer | From | Vlastimil Babka <> | Date | Wed, 8 Aug 2018 15:16:46 +0200 |
| |
On 08/08/2018 01:54 PM, Vlastimil Babka wrote: > Hmm I have looked at the splats in all the bugs you referenced and the > Code part always has the de-obfuscation XORs. Then in comment 36 of > [1] jian-hong says the problem disappeared, and in comment 40 posts > a config that has CONFIG_SLAB_FREELIST_HARDENED disabled. Earlier > posting of his config has it enabled and confirms the disassembly. > Very suspicious, huh.
So I'm looking at 2482ddec670f ("mm: add SLUB free list pointer obfuscation") from Kees, and one suspicious thing is:
before, prefetch_freepointer() was just:
prefetch(object + s->offset);
after, it is
if (object) prefetch(freelist_dereference(s, object + s->offset));
Where freelist_dereference() is either a simple dereference of address, when FREELIST_HARDENED is disabled, or adds those XORs when enabled. However, this had changed the prefetch intention! Previously it just prefetched the address (object + s->offset), now it *dereferences it*, optionally changes the value read with those XORs, and then prefetches the result.
This unintentionally adds a non-prefetching read from (object + s->offset), which may fault, and wasn't there before. It's safe from NULL pointers, but not from bogus pointers, and faults that get_freepointer_safe() prevents. Note that alone doesn't explain why disabling SLAB_FREELIST_HARDENED would help, as the dereference is there unconditionally. But IMHO it's a bug in the commit and minimally it likely has some performance impact.
| |