2020-02-17 08:33:21

by Zong Li

[permalink] [raw]
Subject: [PATCH 0/8] Support strict kernel memory permissions for security

The main purpose of this patch series is changing the kernel mapping permission
, make sure that code is not writeable, data is not executable, and read-only
data is neither writable nor executable.

This patch series also supports the relevant implementations such as
ARCH_HAS_SET_MEMORY, ARCH_HAS_SET_DIRECT_MAP,
ARCH_SUPPORTS_DEBUG_PAGEALLOC and DEBUG_WX.

Zong Li (8):
riscv: add ARCH_HAS_SET_MEMORY support
riscv: add ARCH_HAS_SET_DIRECT_MAP support
riscv: add ARCH_SUPPORTS_DEBUG_PAGEALLOC support
riscv: move exception table immediately after RO_DATA
riscv: add alignment for text, rodata and data sections
riscv: add STRICT_KERNEL_RWX support
riscv: add DEBUG_WX support
riscv: add two hook functions of ftrace

arch/riscv/Kconfig | 6 +
arch/riscv/Kconfig.debug | 30 +++++
arch/riscv/include/asm/ptdump.h | 6 +
arch/riscv/include/asm/set_memory.h | 41 ++++++
arch/riscv/kernel/ftrace.c | 18 +++
arch/riscv/kernel/vmlinux.lds.S | 12 +-
arch/riscv/mm/Makefile | 1 +
arch/riscv/mm/init.c | 47 +++++++
arch/riscv/mm/pageattr.c | 187 ++++++++++++++++++++++++++++
9 files changed, 344 insertions(+), 4 deletions(-)
create mode 100644 arch/riscv/include/asm/set_memory.h
create mode 100644 arch/riscv/mm/pageattr.c

--
2.25.0


2020-02-17 08:33:27

by Zong Li

[permalink] [raw]
Subject: [PATCH 5/8] riscv: add alignment for text, rodata and data sections

The kernel mapping will tried to optimize its mapping by using bigger
size. In rv64, it tries to use PMD_SIZE, and tryies to use PGDIR_SIZE in
rv32. To ensure that the start address of these sections could fit the
mapping entry size, make them align to the biggest alignment.

Define a macro SECTION_ALIGN because the HPAGE_SIZE or PMD_SIZE, etc.,
are invisible in linker script.

This patch is prepared for STRICT_KERNEL_RWX support.

Signed-off-by: Zong Li <[email protected]>
---
arch/riscv/include/asm/set_memory.h | 13 +++++++++++++
arch/riscv/kernel/vmlinux.lds.S | 4 +++-
2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
index a9783a878dca..a91f192063c2 100644
--- a/arch/riscv/include/asm/set_memory.h
+++ b/arch/riscv/include/asm/set_memory.h
@@ -6,6 +6,7 @@
#ifndef _ASM_RISCV_SET_MEMORY_H
#define _ASM_RISCV_SET_MEMORY_H

+#ifndef __ASSEMBLY__
/*
* Functions to change memory attributes.
*/
@@ -17,4 +18,16 @@ int set_memory_nx(unsigned long addr, int numpages);
int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);

+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_ARCH_HAS_STRICT_KERNEL_RWX
+#ifdef CONFIG_64BIT
+#define SECTION_ALIGN (1 << 21)
+#else
+#define SECTION_ALIGN (1 << 22)
+#endif
+#else /* !CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */
+#define SECTION_ALIGN L1_CACHE_BYTES
+#endif /* CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */
+
#endif /* _ASM_RISCV_SET_MEMORY_H */
diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
index 4ba8a5397e8b..0b145b9c1778 100644
--- a/arch/riscv/kernel/vmlinux.lds.S
+++ b/arch/riscv/kernel/vmlinux.lds.S
@@ -37,6 +37,7 @@ SECTIONS
PERCPU_SECTION(L1_CACHE_BYTES)
__init_end = .;

+ . = ALIGN(SECTION_ALIGN);
.text : {
_text = .;
_stext = .;
@@ -53,13 +54,14 @@ SECTIONS
}

/* Start of data section */
- RO_DATA(L1_CACHE_BYTES)
+ RO_DATA(SECTION_ALIGN)
.srodata : {
*(.srodata*)
}

EXCEPTION_TABLE(0x10)

+ . = ALIGN(SECTION_ALIGN);
_sdata = .;

RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
--
2.25.0

2020-02-17 08:35:00

by Zong Li

[permalink] [raw]
Subject: [PATCH 3/8] riscv: add ARCH_SUPPORTS_DEBUG_PAGEALLOC support

ARCH_SUPPORTS_DEBUG_PAGEALLOC provides a hook to map and unmap
pages for debugging purposes. Implement the __kernel_map_pages
functions to fill the poison pattern.

Signed-off-by: Zong Li <[email protected]>
---
arch/riscv/Kconfig | 3 +++
arch/riscv/mm/pageattr.c | 13 +++++++++++++
2 files changed, 16 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 07bf1a7c0dd2..f524d7e60648 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -132,6 +132,9 @@ config ARCH_SELECT_MEMORY_MODEL
config ARCH_WANT_GENERAL_HUGETLB
def_bool y

+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y
+
config SYS_SUPPORTS_HUGETLBFS
def_bool y

diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 7be6cd67e2ef..728759eb530a 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -172,3 +172,16 @@ int set_direct_map_default_noflush(struct page *page)

return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks);
}
+
+void __kernel_map_pages(struct page *page, int numpages, int enable)
+{
+ if (!debug_pagealloc_enabled())
+ return;
+
+ if (enable)
+ __set_memory((unsigned long)page_address(page), numpages,
+ __pgprot(_PAGE_PRESENT), __pgprot(0));
+ else
+ __set_memory((unsigned long)page_address(page), numpages,
+ __pgprot(0), __pgprot(_PAGE_PRESENT));
+}
--
2.25.0

2020-03-05 00:58:28

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH 3/8] riscv: add ARCH_SUPPORTS_DEBUG_PAGEALLOC support

On Mon, 17 Feb 2020 00:32:18 PST (-0800), [email protected] wrote:
> ARCH_SUPPORTS_DEBUG_PAGEALLOC provides a hook to map and unmap
> pages for debugging purposes. Implement the __kernel_map_pages
> functions to fill the poison pattern.
>
> Signed-off-by: Zong Li <[email protected]>
> ---
> arch/riscv/Kconfig | 3 +++
> arch/riscv/mm/pageattr.c | 13 +++++++++++++
> 2 files changed, 16 insertions(+)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 07bf1a7c0dd2..f524d7e60648 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -132,6 +132,9 @@ config ARCH_SELECT_MEMORY_MODEL
> config ARCH_WANT_GENERAL_HUGETLB
> def_bool y
>
> +config ARCH_SUPPORTS_DEBUG_PAGEALLOC
> + def_bool y
> +
> config SYS_SUPPORTS_HUGETLBFS
> def_bool y
>
> diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
> index 7be6cd67e2ef..728759eb530a 100644
> --- a/arch/riscv/mm/pageattr.c
> +++ b/arch/riscv/mm/pageattr.c
> @@ -172,3 +172,16 @@ int set_direct_map_default_noflush(struct page *page)
>
> return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks);
> }
> +
> +void __kernel_map_pages(struct page *page, int numpages, int enable)
> +{
> + if (!debug_pagealloc_enabled())
> + return;
> +
> + if (enable)
> + __set_memory((unsigned long)page_address(page), numpages,
> + __pgprot(_PAGE_PRESENT), __pgprot(0));
> + else
> + __set_memory((unsigned long)page_address(page), numpages,
> + __pgprot(0), __pgprot(_PAGE_PRESENT));
> +}

Reviewed-by: Palmer Dabbelt <[email protected]>

2020-03-05 00:59:15

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH 5/8] riscv: add alignment for text, rodata and data sections

On Mon, 17 Feb 2020 00:32:20 PST (-0800), [email protected] wrote:
> The kernel mapping will tried to optimize its mapping by using bigger
> size. In rv64, it tries to use PMD_SIZE, and tryies to use PGDIR_SIZE in
> rv32. To ensure that the start address of these sections could fit the
> mapping entry size, make them align to the biggest alignment.
>
> Define a macro SECTION_ALIGN because the HPAGE_SIZE or PMD_SIZE, etc.,
> are invisible in linker script.
>
> This patch is prepared for STRICT_KERNEL_RWX support.
>
> Signed-off-by: Zong Li <[email protected]>
> ---
> arch/riscv/include/asm/set_memory.h | 13 +++++++++++++
> arch/riscv/kernel/vmlinux.lds.S | 4 +++-
> 2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
> index a9783a878dca..a91f192063c2 100644
> --- a/arch/riscv/include/asm/set_memory.h
> +++ b/arch/riscv/include/asm/set_memory.h
> @@ -6,6 +6,7 @@
> #ifndef _ASM_RISCV_SET_MEMORY_H
> #define _ASM_RISCV_SET_MEMORY_H
>
> +#ifndef __ASSEMBLY__
> /*
> * Functions to change memory attributes.
> */
> @@ -17,4 +18,16 @@ int set_memory_nx(unsigned long addr, int numpages);
> int set_direct_map_invalid_noflush(struct page *page);
> int set_direct_map_default_noflush(struct page *page);
>
> +#endif /* __ASSEMBLY__ */
> +
> +#ifdef CONFIG_ARCH_HAS_STRICT_KERNEL_RWX
> +#ifdef CONFIG_64BIT
> +#define SECTION_ALIGN (1 << 21)
> +#else
> +#define SECTION_ALIGN (1 << 22)
> +#endif
> +#else /* !CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */
> +#define SECTION_ALIGN L1_CACHE_BYTES
> +#endif /* CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */
> +
> #endif /* _ASM_RISCV_SET_MEMORY_H */
> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
> index 4ba8a5397e8b..0b145b9c1778 100644
> --- a/arch/riscv/kernel/vmlinux.lds.S
> +++ b/arch/riscv/kernel/vmlinux.lds.S
> @@ -37,6 +37,7 @@ SECTIONS
> PERCPU_SECTION(L1_CACHE_BYTES)
> __init_end = .;
>
> + . = ALIGN(SECTION_ALIGN);
> .text : {
> _text = .;
> _stext = .;
> @@ -53,13 +54,14 @@ SECTIONS
> }
>
> /* Start of data section */
> - RO_DATA(L1_CACHE_BYTES)
> + RO_DATA(SECTION_ALIGN)
> .srodata : {
> *(.srodata*)
> }
>
> EXCEPTION_TABLE(0x10)
>
> + . = ALIGN(SECTION_ALIGN);
> _sdata = .;
>
> RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)

Reviewed-by: Palmer Dabbelt <[email protected]>

2020-03-05 15:57:34

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH 0/8] Support strict kernel memory permissions for security

On Mon, 17 Feb 2020 00:32:15 PST (-0800), [email protected] wrote:
> The main purpose of this patch series is changing the kernel mapping permission
> , make sure that code is not writeable, data is not executable, and read-only
> data is neither writable nor executable.
>
> This patch series also supports the relevant implementations such as
> ARCH_HAS_SET_MEMORY, ARCH_HAS_SET_DIRECT_MAP,
> ARCH_SUPPORTS_DEBUG_PAGEALLOC and DEBUG_WX.
>
> Zong Li (8):
> riscv: add ARCH_HAS_SET_MEMORY support
> riscv: add ARCH_HAS_SET_DIRECT_MAP support
> riscv: add ARCH_SUPPORTS_DEBUG_PAGEALLOC support
> riscv: move exception table immediately after RO_DATA
> riscv: add alignment for text, rodata and data sections
> riscv: add STRICT_KERNEL_RWX support
> riscv: add DEBUG_WX support
> riscv: add two hook functions of ftrace
>
> arch/riscv/Kconfig | 6 +
> arch/riscv/Kconfig.debug | 30 +++++
> arch/riscv/include/asm/ptdump.h | 6 +
> arch/riscv/include/asm/set_memory.h | 41 ++++++
> arch/riscv/kernel/ftrace.c | 18 +++
> arch/riscv/kernel/vmlinux.lds.S | 12 +-
> arch/riscv/mm/Makefile | 1 +
> arch/riscv/mm/init.c | 47 +++++++
> arch/riscv/mm/pageattr.c | 187 ++++++++++++++++++++++++++++
> 9 files changed, 344 insertions(+), 4 deletions(-)
> create mode 100644 arch/riscv/include/asm/set_memory.h
> create mode 100644 arch/riscv/mm/pageattr.c

Sorry, I had to run last night without quite finishing the patch set. Just so
we're on the same page: there's some issues with the patch set, I'm assuming
you're submitting a v2 so I'm dropping this from my inbox.

Thanks!