Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 500be43b authored by Daniel Micay's avatar Daniel Micay Committed by Bernhard Thoben
Browse files

add slub free list XOR encryption

Based on the grsecurity feature, but with a per-cache random value.

(cherry picked from commit 80ee3d9d0eff88de44c657a1a503e04e076ffc1b)
parent b60f365c
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -259,20 +259,28 @@ static inline int check_valid_pointer(struct kmem_cache *s,

static inline void *get_freepointer(struct kmem_cache *s, void *object)
{
	return *(void **)(object + s->offset);
	unsigned long freepointer_addr = (unsigned long)object + s->offset;
	return (void *)(*(unsigned long *)freepointer_addr ^ s->random ^ freepointer_addr);
}

static void prefetch_freepointer(const struct kmem_cache *s, void *object)
{
	prefetch(object + s->offset);
	unsigned long freepointer_addr = (unsigned long)object + s->offset;
	if (object) {
		void **freepointer_ptr = (void **)(*(unsigned long *)freepointer_addr ^ s->random ^ freepointer_addr);
		prefetch(freepointer_ptr);
	}
}

static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
{
	unsigned long __maybe_unused freepointer_addr;
	void *p;

#ifdef CONFIG_DEBUG_PAGEALLOC
	probe_kernel_read(&p, (void **)(object + s->offset), sizeof(p));
	freepointer_addr = (unsigned long)object + s->offset;
	probe_kernel_read(&p, (void **)freepointer_addr, sizeof(p));
	return (void *)((unsigned long)p ^ s->random ^ freepointer_addr);
#else
	p = get_freepointer(s, object);
#endif
@@ -281,7 +289,8 @@ static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)

static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
{
	*(void **)(object + s->offset) = fp;
	unsigned long freepointer_addr = (unsigned long)object + s->offset;
	*(void **)freepointer_addr = (void *)((unsigned long)fp ^ s->random ^ freepointer_addr);
}

#ifdef CONFIG_64BIT