Skip to contentSkip to conversation

kasan: fixes for 5.11-rc

PATCH Applied Andrey Konovalov 3 participants 7 messages Jan 15, 2021 – Jan 18, 2021

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v3 cover kasan: fixes for 5.11-rc

Changes v2->v3:
- Fix up kernel pointer tag in do_tag_check_fault() instead of report_tag_fault().

Andrey Konovalov (2):
kasan, mm: fix conflicts with init_on_alloc/free kasan, arm64: fix pointer tags in KASAN reports

 arch/arm64/mm/fault.c | 7 ++++---
 mm/slub.c             | 7 ++++---
 2 files changed, 8 insertions(+), 6 deletions(-)
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog
#1 lore raw

PATCH v3 1/2 kasan, mm: fix conflicts with init_on_alloc/free

A few places where SLUB accesses object's data or metadata were missed in a previous patch. This leads to false positives with hardware tag-based KASAN when bulk allocations are used with init_on_alloc/free.

Fix the false-positives by resetting pointer tags during these accesses.

(The kasan_reset_tag call is removed from slab_alloc_node, as it's added
into maybe_wipe_obj_freeptr.)

---
 mm/slub.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
mm/slub.c +4 -3
index dc5b42e700b8..75fb097d990d 100644
@@ -2791,7 +2791,8 @@ static __always_inline void maybe_wipe_obj_freeptr(struct kmem_cache *s,
 						   void *obj)
 {
 	if (unlikely(slab_want_init_on_free(s)) && obj)
-		memset((void *)((char *)obj + s->offset), 0, sizeof(void *));
+		memset((void *)((char *)kasan_reset_tag(obj) + s->offset),
+			0, sizeof(void *));
 }
 
 /*
@@ -2883,7 +2884,7 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
 		stat(s, ALLOC_FASTPATH);
 	}
 
-	maybe_wipe_obj_freeptr(s, kasan_reset_tag(object));
+	maybe_wipe_obj_freeptr(s, object);
 
 	if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
 		memset(kasan_reset_tag(object), 0, s->object_size);
@@ -3329,7 +3330,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
 		int j;
 
 		for (j = 0; j < i; j++)
-			memset(p[j], 0, s->object_size);
+			memset(kasan_reset_tag(p[j]), 0, s->object_size);
 	}
 
 	/* memcg and kmem_cache debug support */
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog
#2 lore raw

PATCH v3 2/2 kasan, arm64: fix pointer tags in KASAN reports

In reply to Andrey Konovalov

As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address that is passed to report_tag_fault has pointer tags in the format of 0x0X, while KASAN uses 0xFX format (note the difference in the top 4 bits).

Fix up the pointer tag for kernel pointers in do_tag_check_fault by setting them to the same value as bit 55. Explicitly use __untagged_addr() instead of untagged_addr(), as the latter doesn't affect TTBR1 addresses.

Fixes dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
---
 arch/arm64/mm/fault.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
arch/arm64/mm/fault.c +4 -3
index 3c40da479899..35d75c60e2b8 100644
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,
 			      struct pt_regs *regs)
 {
 	/*
-	 * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN for tag
-	 * check faults. Mask them out now so that userspace doesn't see them.
+	 * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN
+	 * for tag check faults. Set them to corresponding bits in the untagged
+	 * address.
 	 */
-	far &= (1UL << 60) - 1;
+	far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
 	do_bad_area(far, esr, regs);
 	return 0;
 }
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog
maintainer Reviewed-by on v3 2/2
#3 lore raw

Re: [PATCH v3 2/2] kasan, arm64: fix pointer tags in KASAN reports

Quoted 9 lines · Andrey Konovalov

As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address that is passed to report_tag_fault has pointer tags in the format of 0x0X, while KASAN uses 0xFX format (note the difference in the top 4 bits).

Fix up the pointer tag for kernel pointers in do_tag_check_fault by setting them to the same value as bit 55. Explicitly use __untagged_addr() instead of untagged_addr(), as the latter doesn't affect TTBR1 addresses.

Unless there are other comments, I'll queue this for -rc5 through the arm64 tree (I already finalised the arm64 for-next/fixes branch for this week).

Signature · 1 line
Catalin
#4 lore raw

Re: [PATCH v3 2/2] kasan, arm64: fix pointer tags in KASAN reports

Quoted 10 lines · Catalin Marinas
Quoted 8 lines · Andrey Konovalov

As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address that is passed to report_tag_fault has pointer tags in the format of 0x0X, while KASAN uses 0xFX format (note the difference in the top 4 bits).

Fix up the pointer tag for kernel pointers in do_tag_check_fault by setting them to the same value as bit 55. Explicitly use __untagged_addr() instead of untagged_addr(), as the latter doesn't affect TTBR1 addresses.

Quoted 7 lines
Quoted 1 line

Unless there are other comments, I'll queue this for -rc5 through the arm64 tree (I already finalised the arm64 for-next/fixes branch for this week).

Sounds good, thank you!

Reviewed-by on v3 2/2
#5 lore raw

Re: [PATCH v3 2/2] kasan, arm64: fix pointer tags in KASAN reports

In reply to Andrey Konovalov
Quoted 4 lines · Andrey Konovalov

As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address that is passed to report_tag_fault has pointer tags in the format of 0x0X, while KASAN uses 0xFX format (note the difference in the top 4 bits).

Quoted 8 lines

Fix up the pointer tag for kernel pointers in do_tag_check_fault by setting them to the same value as bit 55. Explicitly use __untagged_addr() instead of untagged_addr(), as the latter doesn't affect TTBR1 addresses.

Fixes dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Quoted 24 lines
---
 arch/arm64/mm/fault.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
arch/arm64/mm/fault.c +4 -3
index 3c40da479899..35d75c60e2b8 100644
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,
 			      struct pt_regs *regs)
 {
 	/*
-	 * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN for tag
-	 * check faults. Mask them out now so that userspace doesn't see them.
+	 * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN
+	 * for tag check faults. Set them to corresponding bits in the untagged
+	 * address.
 	 */
-	far &= (1UL << 60) - 1;
+	far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
 	do_bad_area(far, esr, regs);
 	return 0;
 }
Signature · 2 lines
Regards,
Vincenzo
maintainer Applied
#6 lore raw
In reply to Andrey Konovalov
Quoted 9 lines · Andrey Konovalov

Changes v2->v3:
- Fix up kernel pointer tag in do_tag_check_fault() instead of report_tag_fault().

Andrey Konovalov (2):
kasan, mm: fix conflicts with init_on_alloc/free kasan, arm64: fix pointer tags in KASAN reports

[...]

Applied to arm64 (for-next/fixes), thanks!

[2/2] kasan, arm64: fix pointer tags in KASAN reports

      https://git.kernel.org/arm64/c/3ed86b9a7140
Signature · 1 line
Catalin