mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
FROMGIT: kasan: untag addresses for KFENCE
[ This change combines two fixes for "kfence, kasan: make KFENCE compatible with KASAN" cherry-picked from the mm tree. ] KFENCE annotations operate on untagged addresses. Untag addresses in KASAN runtime where they might be tagged. Signed-off-by: Marco Elver <elver@google.com> Co-developed-by: Andrey Konovalov <andreyknvl@google.com> Signed-off-by: Andrey Konovalov <andreyknvl@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> (cherry picked from commit 9c9dcae3169799a0882da9318ea8c335c3fe09da https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git akpm) (cherry picked from commit dec4728fab910da0c86cf9a97e980f4244ebae9f https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git akpm) Bug: 172318110 Signed-off-by: Andrey Konovalov <andreyknvl@google.com> Change-Id: I5c57ebfce7f8a3754efe7b1215e4eac364fb922a
This commit is contained in:
parent
13aefe4bf8
commit
f03825db4d
|
|
@ -416,7 +416,7 @@ static void *____kasan_kmalloc(struct kmem_cache *cache, const void *object,
|
|||
if (unlikely(object == NULL))
|
||||
return NULL;
|
||||
|
||||
if (is_kfence_address(object))
|
||||
if (is_kfence_address(kasan_reset_tag(object)))
|
||||
return (void *)object;
|
||||
|
||||
redzone_start = round_up((unsigned long)(object + size),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#define __MM_KASAN_KASAN_H
|
||||
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/kfence.h>
|
||||
#include <linux/stackdepot.h>
|
||||
|
||||
#ifdef CONFIG_KASAN_HW_TAGS
|
||||
|
|
@ -319,14 +320,28 @@ static inline u8 kasan_random_tag(void) { return 0; }
|
|||
|
||||
static inline void kasan_poison(const void *address, size_t size, u8 value)
|
||||
{
|
||||
hw_set_mem_tag_range(kasan_reset_tag(address),
|
||||
address = kasan_reset_tag(address);
|
||||
|
||||
/* Skip KFENCE memory if called explicitly outside of sl*b. */
|
||||
if (is_kfence_address(address))
|
||||
return;
|
||||
|
||||
hw_set_mem_tag_range((void *)address,
|
||||
round_up(size, KASAN_GRANULE_SIZE), value);
|
||||
}
|
||||
|
||||
static inline void kasan_unpoison(const void *address, size_t size)
|
||||
{
|
||||
hw_set_mem_tag_range(kasan_reset_tag(address),
|
||||
round_up(size, KASAN_GRANULE_SIZE), get_tag(address));
|
||||
u8 tag = get_tag(address);
|
||||
|
||||
address = kasan_reset_tag(address);
|
||||
|
||||
/* Skip KFENCE memory if called explicitly outside of sl*b. */
|
||||
if (is_kfence_address(address))
|
||||
return;
|
||||
|
||||
hw_set_mem_tag_range((void *)address,
|
||||
round_up(size, KASAN_GRANULE_SIZE), tag);
|
||||
}
|
||||
|
||||
static inline bool kasan_byte_accessible(const void *addr)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kfence.h>
|
||||
#include <linux/kmemleak.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/mm.h>
|
||||
|
|
@ -84,6 +85,10 @@ void kasan_poison(const void *address, size_t size, u8 value)
|
|||
address = kasan_reset_tag(address);
|
||||
size = round_up(size, KASAN_GRANULE_SIZE);
|
||||
|
||||
/* Skip KFENCE memory if called explicitly outside of sl*b. */
|
||||
if (is_kfence_address(address))
|
||||
return;
|
||||
|
||||
shadow_start = kasan_mem_to_shadow(address);
|
||||
shadow_end = kasan_mem_to_shadow(address + size);
|
||||
|
||||
|
|
@ -102,6 +107,14 @@ void kasan_unpoison(const void *address, size_t size)
|
|||
*/
|
||||
address = kasan_reset_tag(address);
|
||||
|
||||
/*
|
||||
* Skip KFENCE memory if called explicitly outside of sl*b. Also note
|
||||
* that calls to ksize(), where size is not a multiple of machine-word
|
||||
* size, would otherwise poison the invalid portion of the word.
|
||||
*/
|
||||
if (is_kfence_address(address))
|
||||
return;
|
||||
|
||||
kasan_poison(address, size, tag);
|
||||
|
||||
if (size & KASAN_GRANULE_MASK) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user