linux-hardening.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] LoongArch: Add kernel address sanitizer support
@ 2023-05-12  1:57 Qing Zhang
  2023-05-12  1:57 ` [PATCH v3 1/4] kasan: Add __HAVE_ARCH_SHADOW_MAP to support arch specific mapping Qing Zhang
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Qing Zhang @ 2023-05-12  1:57 UTC (permalink / raw)
  To: Andrey Ryabinin, Jonathan Corbet, Huacai Chen, Andrew Morton
  Cc: Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
	Vincenzo Frascino, WANG Xuerui, Jiaxun Yang, kasan-dev,
	linux-doc, linux-mm, loongarch, linux-kernel, linux-hardening

1/8 of kernel addresses reserved for shadow memory. But for LoongArch,
There are a lot of holes between different segments and valid address
space (256T available) is insufficient to map all these segments to kasan
shadow memory with the common formula provided by kasan core, saying
(addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET

So LoongArch has a arch-specific mapping formula, different segments are
mapped individually, and only limited space lengths of these specific
segments are mapped to shadow.

At early boot stage the whole shadow region populated with just one
physical page (kasan_early_shadow_page). Later, this page is reused as
readonly zero shadow for some memory that kasan currently don't track.
After mapping the physical memory, pages for shadow memory are allocated
and mapped.

Functions like memset()/memcpy()/memmove() do a lot of memory accesses.
If bad pointer passed to one of these function it is important to be
caught. Compiler's instrumentation cannot do this since these functions
are written in assembly.

KASan replaces memory functions with manually instrumented variants.
Original functions declared as weak symbols so strong definitions in
mm/kasan/kasan.c could replace them. Original functions have aliases
with '__' prefix in names, so we could call non-instrumented variant
if needed.

Changes v2 -> v3:
- Rebased on 6.4-rc1
- Add Makefile ``KASAN_SANITIZE`` annotation for tlb related files
  to adapt to multiple cores.

Changes v1 -> v2:
Suggested by Andrey:
- Make two separate patches for changes to public files.
- Removes unnecessary judgments in check_region_inline.
- Add pud/pmd_init __weak define.
- Add Empty function kasan_(early)_init when CONFIG_KASAN turned off.
Suggested by Huacai:
- Split the simplified relocation patch.
Suggested by Youling:
- Add ARCH_HAS_FORTIFY_SOURCE in Kconfig and split into separate patches.
- update `Documentation/translations/zh_CN/dev-tools/kasan.rst`.
- Use macros to avoid using magic values directly.
- Modify patch sequence.
- Remove redundant tab.
- Modify submission information.

Qing Zhang (4):
  kasan: Add __HAVE_ARCH_SHADOW_MAP to support arch specific mapping
  kasan: Add (pmd|pud)_init for LoongArch zero_(pud|p4d)_populate
    process
  LoongArch: Simplify the processing of jumping new kernel for KASLR
  LoongArch: Add kernel address sanitizer support

 Documentation/dev-tools/kasan.rst             |   4 +-
 .../features/debug/KASAN/arch-support.txt     |   2 +-
 .../translations/zh_CN/dev-tools/kasan.rst    |   2 +-
 arch/loongarch/Kconfig                        |   7 +
 arch/loongarch/include/asm/kasan.h            | 120 +++++++++
 arch/loongarch/include/asm/pgtable.h          |   7 +
 arch/loongarch/include/asm/setup.h            |   2 +-
 arch/loongarch/include/asm/string.h           |  20 ++
 arch/loongarch/kernel/Makefile                |   6 +
 arch/loongarch/kernel/head.S                  |  13 +-
 arch/loongarch/kernel/relocate.c              |   8 +-
 arch/loongarch/kernel/setup.c                 |   4 +
 arch/loongarch/lib/memcpy.S                   |   4 +-
 arch/loongarch/lib/memmove.S                  |  16 +-
 arch/loongarch/lib/memset.S                   |   4 +-
 arch/loongarch/mm/Makefile                    |   2 +
 arch/loongarch/mm/kasan_init.c                | 255 ++++++++++++++++++
 arch/loongarch/vdso/Makefile                  |   4 +
 include/linux/kasan.h                         |   2 +
 mm/kasan/init.c                               |  18 +-
 mm/kasan/kasan.h                              |   6 +
 21 files changed, 478 insertions(+), 28 deletions(-)
 create mode 100644 arch/loongarch/include/asm/kasan.h
 create mode 100644 arch/loongarch/mm/kasan_init.c

-- 
2.36.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/4] kasan: Add __HAVE_ARCH_SHADOW_MAP to support arch specific mapping
  2023-05-12  1:57 [PATCH v3 0/4] LoongArch: Add kernel address sanitizer support Qing Zhang
@ 2023-05-12  1:57 ` Qing Zhang
  2023-05-12  1:57 ` [PATCH v3 2/4] kasan: Add (pmd|pud)_init for LoongArch zero_(pud|p4d)_populate process Qing Zhang
  2023-05-12  1:57 ` [PATCH v3 3/4] LoongArch: Simplify the processing of jumping new kernel for KASLR Qing Zhang
  2 siblings, 0 replies; 4+ messages in thread
From: Qing Zhang @ 2023-05-12  1:57 UTC (permalink / raw)
  To: Andrey Ryabinin, Jonathan Corbet, Huacai Chen, Andrew Morton
  Cc: Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
	Vincenzo Frascino, WANG Xuerui, Jiaxun Yang, kasan-dev,
	linux-doc, linux-mm, loongarch, linux-kernel, linux-hardening

MIPS, LoongArch and some other architectures have many holes between
different segments and the valid address space (256T available) is
insufficient to map all these segments to kasan shadow memory with the
common formula provided by kasan core. So we need architecture specific
mapping formulas to ensure different segments are mapped individually,
and only limited space lengths of those specific segments are mapped to
shadow.

Therefore, when the incoming address is converted to a shadow, we need
to add a condition to determine whether it is valid.

Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
 include/linux/kasan.h | 2 ++
 mm/kasan/kasan.h      | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index f7ef70661ce2..3b91b941873d 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -54,11 +54,13 @@ extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
 int kasan_populate_early_shadow(const void *shadow_start,
 				const void *shadow_end);
 
+#ifndef __HAVE_ARCH_SHADOW_MAP
 static inline void *kasan_mem_to_shadow(const void *addr)
 {
 	return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
 		+ KASAN_SHADOW_OFFSET;
 }
+#endif
 
 int kasan_add_zero_shadow(void *start, unsigned long size);
 void kasan_remove_zero_shadow(void *start, unsigned long size);
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index a61eeee3095a..033335c13b25 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -291,16 +291,22 @@ struct kasan_stack_ring {
 
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 
+#ifndef __HAVE_ARCH_SHADOW_MAP
 static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
 {
 	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
 		<< KASAN_SHADOW_SCALE_SHIFT);
 }
+#endif
 
 static __always_inline bool addr_has_metadata(const void *addr)
 {
+#ifdef __HAVE_ARCH_SHADOW_MAP
+	return (kasan_mem_to_shadow((void *)addr) != NULL);
+#else
 	return (kasan_reset_tag(addr) >=
 		kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
+#endif
 }
 
 /**
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/4] kasan: Add (pmd|pud)_init for LoongArch zero_(pud|p4d)_populate process
  2023-05-12  1:57 [PATCH v3 0/4] LoongArch: Add kernel address sanitizer support Qing Zhang
  2023-05-12  1:57 ` [PATCH v3 1/4] kasan: Add __HAVE_ARCH_SHADOW_MAP to support arch specific mapping Qing Zhang
@ 2023-05-12  1:57 ` Qing Zhang
  2023-05-12  1:57 ` [PATCH v3 3/4] LoongArch: Simplify the processing of jumping new kernel for KASLR Qing Zhang
  2 siblings, 0 replies; 4+ messages in thread
From: Qing Zhang @ 2023-05-12  1:57 UTC (permalink / raw)
  To: Andrey Ryabinin, Jonathan Corbet, Huacai Chen, Andrew Morton
  Cc: Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
	Vincenzo Frascino, WANG Xuerui, Jiaxun Yang, kasan-dev,
	linux-doc, linux-mm, loongarch, linux-kernel, linux-hardening

LoongArch populates pmd/pud with invalid_pmd_table/invalid_pud_table in
pagetable_init, So pmd_init/pud_init(p) is required, define them as __weak
in mm/kasan/init.c, like mm/sparse-vmemmap.c.

Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
 mm/kasan/init.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/mm/kasan/init.c b/mm/kasan/init.c
index cc64ed6858c6..a7fa223b96e4 100644
--- a/mm/kasan/init.c
+++ b/mm/kasan/init.c
@@ -139,6 +139,10 @@ static int __ref zero_pmd_populate(pud_t *pud, unsigned long addr,
 	return 0;
 }
 
+void __weak __meminit pmd_init(void *addr)
+{
+}
+
 static int __ref zero_pud_populate(p4d_t *p4d, unsigned long addr,
 				unsigned long end)
 {
@@ -166,8 +170,9 @@ static int __ref zero_pud_populate(p4d_t *p4d, unsigned long addr,
 				if (!p)
 					return -ENOMEM;
 			} else {
-				pud_populate(&init_mm, pud,
-					early_alloc(PAGE_SIZE, NUMA_NO_NODE));
+				p = early_alloc(PAGE_SIZE, NUMA_NO_NODE);
+				pmd_init(p);
+				pud_populate(&init_mm, pud, p);
 			}
 		}
 		zero_pmd_populate(pud, addr, next);
@@ -176,6 +181,10 @@ static int __ref zero_pud_populate(p4d_t *p4d, unsigned long addr,
 	return 0;
 }
 
+void __weak __meminit pud_init(void *addr)
+{
+}
+
 static int __ref zero_p4d_populate(pgd_t *pgd, unsigned long addr,
 				unsigned long end)
 {
@@ -207,8 +216,9 @@ static int __ref zero_p4d_populate(pgd_t *pgd, unsigned long addr,
 				if (!p)
 					return -ENOMEM;
 			} else {
-				p4d_populate(&init_mm, p4d,
-					early_alloc(PAGE_SIZE, NUMA_NO_NODE));
+				p = early_alloc(PAGE_SIZE, NUMA_NO_NODE);
+				pud_init(p);
+				p4d_populate(&init_mm, p4d, p);
 			}
 		}
 		zero_pud_populate(p4d, addr, next);
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 3/4] LoongArch: Simplify the processing of jumping new kernel for KASLR
  2023-05-12  1:57 [PATCH v3 0/4] LoongArch: Add kernel address sanitizer support Qing Zhang
  2023-05-12  1:57 ` [PATCH v3 1/4] kasan: Add __HAVE_ARCH_SHADOW_MAP to support arch specific mapping Qing Zhang
  2023-05-12  1:57 ` [PATCH v3 2/4] kasan: Add (pmd|pud)_init for LoongArch zero_(pud|p4d)_populate process Qing Zhang
@ 2023-05-12  1:57 ` Qing Zhang
  2 siblings, 0 replies; 4+ messages in thread
From: Qing Zhang @ 2023-05-12  1:57 UTC (permalink / raw)
  To: Andrey Ryabinin, Jonathan Corbet, Huacai Chen, Andrew Morton
  Cc: Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
	Vincenzo Frascino, WANG Xuerui, Jiaxun Yang, kasan-dev,
	linux-doc, linux-mm, loongarch, linux-kernel, linux-hardening

Modified relocate_kernel() doesn't return new kernel's entry point but
the random_offset. In this way we share the start_kernel() processing
with the normal kernel, which avoids calling 'jr a0' directly and allows
some other operations (e.g, kasan_early_init) before start_kernel() when
KASLR (CONFIG_RANDOMIZE_BASE) is turned on.

Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
 arch/loongarch/include/asm/setup.h |  2 +-
 arch/loongarch/kernel/head.S       | 11 ++++++-----
 arch/loongarch/kernel/relocate.c   |  8 ++------
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/arch/loongarch/include/asm/setup.h b/arch/loongarch/include/asm/setup.h
index be05c0e706a2..2dca0d1dd90a 100644
--- a/arch/loongarch/include/asm/setup.h
+++ b/arch/loongarch/include/asm/setup.h
@@ -33,7 +33,7 @@ extern long __la_abs_end;
 extern long __rela_dyn_begin;
 extern long __rela_dyn_end;
 
-extern void * __init relocate_kernel(void);
+extern unsigned long __init relocate_kernel(void);
 
 #endif
 
diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index aa64b179744f..aace7a300cd3 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -95,13 +95,14 @@ SYM_CODE_START(kernel_entry)			# kernel entry point
 	PTR_LI		sp, (_THREAD_SIZE - PT_SIZE)
 	PTR_ADD		sp, sp, tp
 	set_saved_sp	sp, t0, t1
-#endif
 
-	/* relocate_kernel() returns the new kernel entry point */
-	jr		a0
-	ASM_BUG()
+	/* Jump to the new kernel: new_pc = current_pc + random_offset */
+	pcaddi		t0, 0
+	add.d		t0, t0, a0
+	jirl		zero, t0, 0xc
+#endif /* CONFIG_RANDOMIZE_BASE */
 
-#endif
+#endif /* CONFIG_RELOCATABLE */
 
 	bl		start_kernel
 	ASM_BUG()
diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
index 01f94d1e3edf..6c3eff9af9fb 100644
--- a/arch/loongarch/kernel/relocate.c
+++ b/arch/loongarch/kernel/relocate.c
@@ -157,12 +157,11 @@ static inline void __init update_reloc_offset(unsigned long *addr, long random_o
 	*new_addr = (unsigned long)reloc_offset;
 }
 
-void * __init relocate_kernel(void)
+unsigned long __init relocate_kernel(void)
 {
 	unsigned long kernel_length;
 	unsigned long random_offset = 0;
 	void *location_new = _text; /* Default to original kernel start */
-	void *kernel_entry = start_kernel; /* Default to original kernel entry point */
 	char *cmdline = early_ioremap(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */
 
 	strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
@@ -190,9 +189,6 @@ void * __init relocate_kernel(void)
 
 		reloc_offset += random_offset;
 
-		/* Return the new kernel's entry point */
-		kernel_entry = RELOCATED_KASLR(start_kernel);
-
 		/* The current thread is now within the relocated kernel */
 		__current_thread_info = RELOCATED_KASLR(__current_thread_info);
 
@@ -204,7 +200,7 @@ void * __init relocate_kernel(void)
 
 	relocate_absolute(random_offset);
 
-	return kernel_entry;
+	return random_offset;
 }
 
 /*
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-05-12  1:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-12  1:57 [PATCH v3 0/4] LoongArch: Add kernel address sanitizer support Qing Zhang
2023-05-12  1:57 ` [PATCH v3 1/4] kasan: Add __HAVE_ARCH_SHADOW_MAP to support arch specific mapping Qing Zhang
2023-05-12  1:57 ` [PATCH v3 2/4] kasan: Add (pmd|pud)_init for LoongArch zero_(pud|p4d)_populate process Qing Zhang
2023-05-12  1:57 ` [PATCH v3 3/4] LoongArch: Simplify the processing of jumping new kernel for KASLR Qing Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).