2021-04-12 16:17:59

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 00/10] riscv: improve self-protection

From: Jisheng Zhang <[email protected]>

patch1 removes the non-necessary setup_zero_page()
patch2 is a trivial improvement patch to move some functions to .init
section

Then following patches improve self-protection by:

Marking some variables __ro_after_init
Constifing some variables
Enabling ARCH_HAS_STRICT_MODULE_RWX

Hi Anup,

I kept the __init modification to trap_init(), I will cook a trivial
series to provide a __weak but NULL trap_init() implementation in
init/main.c then remove all NULL implementation from all arch.

Thanks

Since v2:
- collect Reviewed-by tag
- add one patch to remove unnecessary setup_zero_page()

Since v1:
- no need to move bpf_jit_alloc_exec() and bpf_jit_free_exec() to core
because RV32 uses the default module_alloc() for jit code which also
meets W^X after patch8
- fix a build error caused by local debug code clean up


Jisheng Zhang (10):
riscv: mm: Remove setup_zero_page()
riscv: add __init section marker to some functions
riscv: Mark some global variables __ro_after_init
riscv: Constify sys_call_table
riscv: Constify sbi_ipi_ops
riscv: kprobes: Implement alloc_insn_page()
riscv: bpf: Write protect JIT code
riscv: bpf: Avoid breaking W^X on RV64
riscv: module: Create module allocations without exec permissions
riscv: Set ARCH_HAS_STRICT_MODULE_RWX if MMU

arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/smp.h | 4 ++--
arch/riscv/include/asm/syscall.h | 2 +-
arch/riscv/kernel/cpufeature.c | 2 +-
arch/riscv/kernel/module.c | 10 ++++++++--
arch/riscv/kernel/probes/kprobes.c | 8 ++++++++
arch/riscv/kernel/sbi.c | 10 +++++-----
arch/riscv/kernel/smp.c | 6 +++---
arch/riscv/kernel/syscall_table.c | 2 +-
arch/riscv/kernel/time.c | 2 +-
arch/riscv/kernel/traps.c | 2 +-
arch/riscv/kernel/vdso.c | 4 ++--
arch/riscv/mm/init.c | 16 +++++-----------
arch/riscv/mm/kasan_init.c | 6 +++---
arch/riscv/mm/ptdump.c | 2 +-
arch/riscv/net/bpf_jit_comp64.c | 2 +-
arch/riscv/net/bpf_jit_core.c | 1 +
17 files changed, 45 insertions(+), 35 deletions(-)

--
2.31.0



2021-04-12 16:18:55

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 01/10] riscv: mm: Remove setup_zero_page()

From: Jisheng Zhang <[email protected]>

The empty_zero_page sits at .bss..page_aligned section, so will be
cleared to zero during clearing bss, we don't need to clear it again.

Signed-off-by: Jisheng Zhang <[email protected]>
---
arch/riscv/mm/init.c | 6 ------
1 file changed, 6 deletions(-)

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 7f5036fbee8c..dbeaa4144e4d 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -57,11 +57,6 @@ static void __init zone_sizes_init(void)
free_area_init(max_zone_pfns);
}

-static void setup_zero_page(void)
-{
- memset((void *)empty_zero_page, 0, PAGE_SIZE);
-}
-
#if defined(CONFIG_MMU) && defined(CONFIG_DEBUG_VM)
static inline void print_mlk(char *name, unsigned long b, unsigned long t)
{
@@ -589,7 +584,6 @@ void mark_rodata_ro(void)
void __init paging_init(void)
{
setup_vm_final();
- setup_zero_page();
}

void __init misc_mem_init(void)
--
2.31.0


2021-04-12 16:19:35

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 03/10] riscv: Mark some global variables __ro_after_init

From: Jisheng Zhang <[email protected]>

All of these are never modified after init, so they can be
__ro_after_init.

Signed-off-by: Jisheng Zhang <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
---
arch/riscv/kernel/sbi.c | 8 ++++----
arch/riscv/kernel/smp.c | 4 ++--
arch/riscv/kernel/time.c | 2 +-
arch/riscv/kernel/vdso.c | 4 ++--
arch/riscv/mm/init.c | 6 +++---
5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
index 7fbf044d9593..6ebffd579379 100644
--- a/arch/riscv/kernel/sbi.c
+++ b/arch/riscv/kernel/sbi.c
@@ -11,14 +11,14 @@
#include <asm/smp.h>

/* default SBI version is 0.1 */
-unsigned long sbi_spec_version = SBI_SPEC_VERSION_DEFAULT;
+unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT;
EXPORT_SYMBOL(sbi_spec_version);

-static void (*__sbi_set_timer)(uint64_t stime);
-static int (*__sbi_send_ipi)(const unsigned long *hart_mask);
+static void (*__sbi_set_timer)(uint64_t stime) __ro_after_init;
+static int (*__sbi_send_ipi)(const unsigned long *hart_mask) __ro_after_init;
static int (*__sbi_rfence)(int fid, const unsigned long *hart_mask,
unsigned long start, unsigned long size,
- unsigned long arg4, unsigned long arg5);
+ unsigned long arg4, unsigned long arg5) __ro_after_init;

struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
unsigned long arg1, unsigned long arg2,
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index 8325d33411d8..476e2e4bc5c5 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -32,7 +32,7 @@ enum ipi_message_type {
IPI_MAX
};

-unsigned long __cpuid_to_hartid_map[NR_CPUS] = {
+unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = {
[0 ... NR_CPUS-1] = INVALID_HARTID
};

@@ -87,7 +87,7 @@ static void ipi_stop(void)
wait_for_interrupt();
}

-static struct riscv_ipi_ops *ipi_ops;
+static struct riscv_ipi_ops *ipi_ops __ro_after_init;

void riscv_set_ipi_ops(struct riscv_ipi_ops *ops)
{
diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
index 1b432264f7ef..8217b0f67c6c 100644
--- a/arch/riscv/kernel/time.c
+++ b/arch/riscv/kernel/time.c
@@ -11,7 +11,7 @@
#include <asm/processor.h>
#include <asm/timex.h>

-unsigned long riscv_timebase;
+unsigned long riscv_timebase __ro_after_init;
EXPORT_SYMBOL_GPL(riscv_timebase);

void __init time_init(void)
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 3f1d35e7c98a..25a3b8849599 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -20,8 +20,8 @@

extern char vdso_start[], vdso_end[];

-static unsigned int vdso_pages;
-static struct page **vdso_pagelist;
+static unsigned int vdso_pages __ro_after_init;
+static struct page **vdso_pagelist __ro_after_init;

/*
* The vDSO data page.
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index ecd485662b07..bccf1b81af24 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -145,11 +145,11 @@ void __init setup_bootmem(void)
}

#ifdef CONFIG_MMU
-static struct pt_alloc_ops pt_ops;
+static struct pt_alloc_ops pt_ops __ro_after_init;

-unsigned long va_pa_offset;
+unsigned long va_pa_offset __ro_after_init;
EXPORT_SYMBOL(va_pa_offset);
-unsigned long pfn_base;
+unsigned long pfn_base __ro_after_init;
EXPORT_SYMBOL(pfn_base);

pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
--
2.31.0


2021-04-12 16:21:34

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 04/10] riscv: Constify sys_call_table

From: Jisheng Zhang <[email protected]>

Constify the sys_call_table so that it will be placed in the .rodata
section. This will cause attempts to modify the table to fail when
strict page permissions are in place.

Signed-off-by: Jisheng Zhang <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
---
arch/riscv/include/asm/syscall.h | 2 +-
arch/riscv/kernel/syscall_table.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 49350c8bd7b0..b933b1583c9f 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -15,7 +15,7 @@
#include <linux/err.h>

/* The array of function pointers for syscalls. */
-extern void *sys_call_table[];
+extern void * const sys_call_table[];

/*
* Only the low 32 bits of orig_r0 are meaningful, so we return int.
diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c
index f1ead9df96ca..a63c667c27b3 100644
--- a/arch/riscv/kernel/syscall_table.c
+++ b/arch/riscv/kernel/syscall_table.c
@@ -13,7 +13,7 @@
#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),

-void *sys_call_table[__NR_syscalls] = {
+void * const sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls - 1] = sys_ni_syscall,
#include <asm/unistd.h>
};
--
2.31.0


2021-04-12 16:29:19

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 06/10] riscv: kprobes: Implement alloc_insn_page()

From: Jisheng Zhang <[email protected]>

Allocate PAGE_KERNEL_READ_EXEC(read only, executable) page for kprobes
insn page. This is to prepare for STRICT_MODULE_RWX.

Signed-off-by: Jisheng Zhang <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
---
arch/riscv/kernel/probes/kprobes.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
index 7e2c78e2ca6b..8c1f7a30aeed 100644
--- a/arch/riscv/kernel/probes/kprobes.c
+++ b/arch/riscv/kernel/probes/kprobes.c
@@ -84,6 +84,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
return 0;
}

+void *alloc_insn_page(void)
+{
+ return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
+ GFP_KERNEL, PAGE_KERNEL_READ_EXEC,
+ VM_FLUSH_RESET_PERMS, NUMA_NO_NODE,
+ __builtin_return_address(0));
+}
+
/* install breakpoint in text */
void __kprobes arch_arm_kprobe(struct kprobe *p)
{
--
2.31.0


2021-04-12 16:31:26

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 07/10] riscv: bpf: Write protect JIT code

From: Jisheng Zhang <[email protected]>

Call bpf_jit_binary_lock_ro() to write protect JIT code.

Signed-off-by: Jisheng Zhang <[email protected]>
---
arch/riscv/net/bpf_jit_core.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
index 3630d447352c..40d5bf113fee 100644
--- a/arch/riscv/net/bpf_jit_core.c
+++ b/arch/riscv/net/bpf_jit_core.c
@@ -152,6 +152,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns);

if (!prog->is_func || extra_pass) {
+ bpf_jit_binary_lock_ro(jit_data->header);
out_offset:
kfree(ctx->offset);
kfree(jit_data);
--
2.31.0


2021-04-12 16:33:42

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 08/10] riscv: bpf: Avoid breaking W^X on RV64

From: Jisheng Zhang <[email protected]>

bpf_jit_binary_lock_ro() in core not only set RO but also set EXEC
permission when JIT is done, so no need to allocate RWX from the
beginning, and it's not safe.

Signed-off-by: Jisheng Zhang <[email protected]>
---
arch/riscv/net/bpf_jit_comp64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index b44ff52f84a6..1c61a82a2856 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -1153,7 +1153,7 @@ void *bpf_jit_alloc_exec(unsigned long size)
{
return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START,
BPF_JIT_REGION_END, GFP_KERNEL,
- PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
+ PAGE_KERNEL, 0, NUMA_NO_NODE,
__builtin_return_address(0));
}

--
2.31.0


2021-04-12 16:34:03

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 09/10] riscv: module: Create module allocations without exec permissions

From: Jisheng Zhang <[email protected]>

The core code manages the executable permissions of code regions of
modules explicitly, it is not necessary to create the module vmalloc
regions with RWX permissions. Create them with RW- permissions instead.

Signed-off-by: Jisheng Zhang <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
---
arch/riscv/kernel/module.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 104fba889cf7..e89367bba7c9 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -407,14 +407,20 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
return 0;
}

-#if defined(CONFIG_MMU) && defined(CONFIG_64BIT)
+#ifdef CONFIG_MMU
+
+#ifdef CONFIG_64BIT
#define VMALLOC_MODULE_START \
max(PFN_ALIGN((unsigned long)&_end - SZ_2G), VMALLOC_START)
+#else
+#define VMALLOC_MODULE_START VMALLOC_START
+#endif
+
void *module_alloc(unsigned long size)
{
return __vmalloc_node_range(size, 1, VMALLOC_MODULE_START,
VMALLOC_END, GFP_KERNEL,
- PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
+ PAGE_KERNEL, 0, NUMA_NO_NODE,
__builtin_return_address(0));
}
#endif
--
2.31.0


2021-04-13 04:44:00

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 02/10] riscv: add __init section marker to some functions

From: Jisheng Zhang <[email protected]>

They are not needed after booting, so mark them as __init to move them
to the __init section.

Signed-off-by: Jisheng Zhang <[email protected]>
---
arch/riscv/kernel/cpufeature.c | 2 +-
arch/riscv/kernel/traps.c | 2 +-
arch/riscv/mm/init.c | 4 ++--
arch/riscv/mm/kasan_init.c | 6 +++---
arch/riscv/mm/ptdump.c | 2 +-
5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index ac202f44a670..e4741e1f0add 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -59,7 +59,7 @@ bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit)
}
EXPORT_SYMBOL_GPL(__riscv_isa_extension_available);

-void riscv_fill_hwcap(void)
+void __init riscv_fill_hwcap(void)
{
struct device_node *node;
const char *isa;
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 0879b5df11b9..041f4b44262e 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -196,6 +196,6 @@ int is_valid_bugaddr(unsigned long pc)
#endif /* CONFIG_GENERIC_BUG */

/* stvec & scratch is already set from head.S */
-void trap_init(void)
+void __init trap_init(void)
{
}
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index dbeaa4144e4d..ecd485662b07 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -70,7 +70,7 @@ static inline void print_mlm(char *name, unsigned long b, unsigned long t)
(((t) - (b)) >> 20));
}

-static void print_vm_layout(void)
+static void __init print_vm_layout(void)
{
pr_notice("Virtual kernel memory layout:\n");
print_mlk("fixmap", (unsigned long)FIXADDR_START,
@@ -553,7 +553,7 @@ static inline void setup_vm_final(void)
#endif /* CONFIG_MMU */

#ifdef CONFIG_STRICT_KERNEL_RWX
-void protect_kernel_text_data(void)
+void __init protect_kernel_text_data(void)
{
unsigned long text_start = (unsigned long)_start;
unsigned long init_text_start = (unsigned long)__init_text_begin;
diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c
index ec0029097251..e459290d2629 100644
--- a/arch/riscv/mm/kasan_init.c
+++ b/arch/riscv/mm/kasan_init.c
@@ -48,7 +48,7 @@ asmlinkage void __init kasan_early_init(void)
local_flush_tlb_all();
}

-static void kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned long end)
+static void __init kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned long end)
{
phys_addr_t phys_addr;
pte_t *ptep, *base_pte;
@@ -70,7 +70,7 @@ static void kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned long en
set_pmd(pmd, pfn_pmd(PFN_DOWN(__pa(base_pte)), PAGE_TABLE));
}

-static void kasan_populate_pmd(pgd_t *pgd, unsigned long vaddr, unsigned long end)
+static void __init kasan_populate_pmd(pgd_t *pgd, unsigned long vaddr, unsigned long end)
{
phys_addr_t phys_addr;
pmd_t *pmdp, *base_pmd;
@@ -105,7 +105,7 @@ static void kasan_populate_pmd(pgd_t *pgd, unsigned long vaddr, unsigned long en
set_pgd(pgd, pfn_pgd(PFN_DOWN(__pa(base_pmd)), PAGE_TABLE));
}

-static void kasan_populate_pgd(unsigned long vaddr, unsigned long end)
+static void __init kasan_populate_pgd(unsigned long vaddr, unsigned long end)
{
phys_addr_t phys_addr;
pgd_t *pgdp = pgd_offset_k(vaddr);
diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
index ace74dec7492..3b7b6e4d025e 100644
--- a/arch/riscv/mm/ptdump.c
+++ b/arch/riscv/mm/ptdump.c
@@ -331,7 +331,7 @@ static int ptdump_show(struct seq_file *m, void *v)

DEFINE_SHOW_ATTRIBUTE(ptdump);

-static int ptdump_init(void)
+static int __init ptdump_init(void)
{
unsigned int i, j;

--
2.31.0


2021-04-13 04:47:15

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 05/10] riscv: Constify sbi_ipi_ops

From: Jisheng Zhang <[email protected]>

Constify the sbi_ipi_ops so that it will be placed in the .rodata
section. This will cause attempts to modify it to fail when strict
page permissions are in place.

Signed-off-by: Jisheng Zhang <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
---
arch/riscv/include/asm/smp.h | 4 ++--
arch/riscv/kernel/sbi.c | 2 +-
arch/riscv/kernel/smp.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h
index df1f7c4cd433..a7d2811f3536 100644
--- a/arch/riscv/include/asm/smp.h
+++ b/arch/riscv/include/asm/smp.h
@@ -46,7 +46,7 @@ int riscv_hartid_to_cpuid(int hartid);
void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out);

/* Set custom IPI operations */
-void riscv_set_ipi_ops(struct riscv_ipi_ops *ops);
+void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops);

/* Clear IPI for current CPU */
void riscv_clear_ipi(void);
@@ -92,7 +92,7 @@ static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in,
cpumask_set_cpu(boot_cpu_hartid, out);
}

-static inline void riscv_set_ipi_ops(struct riscv_ipi_ops *ops)
+static inline void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops)
{
}

diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
index 6ebffd579379..7402a417f38e 100644
--- a/arch/riscv/kernel/sbi.c
+++ b/arch/riscv/kernel/sbi.c
@@ -571,7 +571,7 @@ static void sbi_send_cpumask_ipi(const struct cpumask *target)
sbi_send_ipi(cpumask_bits(&hartid_mask));
}

-static struct riscv_ipi_ops sbi_ipi_ops = {
+static const struct riscv_ipi_ops sbi_ipi_ops = {
.ipi_inject = sbi_send_cpumask_ipi
};

diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index 476e2e4bc5c5..366cb87c0e2e 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -87,9 +87,9 @@ static void ipi_stop(void)
wait_for_interrupt();
}

-static struct riscv_ipi_ops *ipi_ops __ro_after_init;
+static const struct riscv_ipi_ops *ipi_ops __ro_after_init;

-void riscv_set_ipi_ops(struct riscv_ipi_ops *ops)
+void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops)
{
ipi_ops = ops;
}
--
2.31.0


2021-04-13 05:18:40

by Jisheng Zhang

[permalink] [raw]
Subject: [PATCH v3 10/10] riscv: Set ARCH_HAS_STRICT_MODULE_RWX if MMU

From: Jisheng Zhang <[email protected]>

Now we can set ARCH_HAS_STRICT_MODULE_RWX for MMU riscv platforms, this
is good from security perspective.

Signed-off-by: Jisheng Zhang <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
---
arch/riscv/Kconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 58a1d69713a9..e8074d248457 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -29,6 +29,7 @@ config RISCV
select ARCH_HAS_SET_DIRECT_MAP
select ARCH_HAS_SET_MEMORY
select ARCH_HAS_STRICT_KERNEL_RWX if MMU
+ select ARCH_HAS_STRICT_MODULE_RWX if MMU
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
--
2.31.0


2021-04-13 12:31:26

by Anup Patel

[permalink] [raw]
Subject: Re: [PATCH v3 02/10] riscv: add __init section marker to some functions

On Mon, Apr 12, 2021 at 9:47 PM Jisheng Zhang <[email protected]> wrote:
>
> From: Jisheng Zhang <[email protected]>
>
> They are not needed after booting, so mark them as __init to move them
> to the __init section.
>
> Signed-off-by: Jisheng Zhang <[email protected]>

Looks good to me.

Reviewed-by: Anup Patel <[email protected]>

Regards,
Anup

> ---
> arch/riscv/kernel/cpufeature.c | 2 +-
> arch/riscv/kernel/traps.c | 2 +-
> arch/riscv/mm/init.c | 4 ++--
> arch/riscv/mm/kasan_init.c | 6 +++---
> arch/riscv/mm/ptdump.c | 2 +-
> 5 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index ac202f44a670..e4741e1f0add 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -59,7 +59,7 @@ bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit)
> }
> EXPORT_SYMBOL_GPL(__riscv_isa_extension_available);
>
> -void riscv_fill_hwcap(void)
> +void __init riscv_fill_hwcap(void)
> {
> struct device_node *node;
> const char *isa;
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 0879b5df11b9..041f4b44262e 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -196,6 +196,6 @@ int is_valid_bugaddr(unsigned long pc)
> #endif /* CONFIG_GENERIC_BUG */
>
> /* stvec & scratch is already set from head.S */
> -void trap_init(void)
> +void __init trap_init(void)
> {
> }
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index dbeaa4144e4d..ecd485662b07 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -70,7 +70,7 @@ static inline void print_mlm(char *name, unsigned long b, unsigned long t)
> (((t) - (b)) >> 20));
> }
>
> -static void print_vm_layout(void)
> +static void __init print_vm_layout(void)
> {
> pr_notice("Virtual kernel memory layout:\n");
> print_mlk("fixmap", (unsigned long)FIXADDR_START,
> @@ -553,7 +553,7 @@ static inline void setup_vm_final(void)
> #endif /* CONFIG_MMU */
>
> #ifdef CONFIG_STRICT_KERNEL_RWX
> -void protect_kernel_text_data(void)
> +void __init protect_kernel_text_data(void)
> {
> unsigned long text_start = (unsigned long)_start;
> unsigned long init_text_start = (unsigned long)__init_text_begin;
> diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c
> index ec0029097251..e459290d2629 100644
> --- a/arch/riscv/mm/kasan_init.c
> +++ b/arch/riscv/mm/kasan_init.c
> @@ -48,7 +48,7 @@ asmlinkage void __init kasan_early_init(void)
> local_flush_tlb_all();
> }
>
> -static void kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned long end)
> +static void __init kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned long end)
> {
> phys_addr_t phys_addr;
> pte_t *ptep, *base_pte;
> @@ -70,7 +70,7 @@ static void kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned long en
> set_pmd(pmd, pfn_pmd(PFN_DOWN(__pa(base_pte)), PAGE_TABLE));
> }
>
> -static void kasan_populate_pmd(pgd_t *pgd, unsigned long vaddr, unsigned long end)
> +static void __init kasan_populate_pmd(pgd_t *pgd, unsigned long vaddr, unsigned long end)
> {
> phys_addr_t phys_addr;
> pmd_t *pmdp, *base_pmd;
> @@ -105,7 +105,7 @@ static void kasan_populate_pmd(pgd_t *pgd, unsigned long vaddr, unsigned long en
> set_pgd(pgd, pfn_pgd(PFN_DOWN(__pa(base_pmd)), PAGE_TABLE));
> }
>
> -static void kasan_populate_pgd(unsigned long vaddr, unsigned long end)
> +static void __init kasan_populate_pgd(unsigned long vaddr, unsigned long end)
> {
> phys_addr_t phys_addr;
> pgd_t *pgdp = pgd_offset_k(vaddr);
> diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
> index ace74dec7492..3b7b6e4d025e 100644
> --- a/arch/riscv/mm/ptdump.c
> +++ b/arch/riscv/mm/ptdump.c
> @@ -331,7 +331,7 @@ static int ptdump_show(struct seq_file *m, void *v)
>
> DEFINE_SHOW_ATTRIBUTE(ptdump);
>
> -static int ptdump_init(void)
> +static int __init ptdump_init(void)
> {
> unsigned int i, j;
>
> --
> 2.31.0
>
>

2021-04-13 12:32:21

by Anup Patel

[permalink] [raw]
Subject: Re: [PATCH v3 00/10] riscv: improve self-protection

On Mon, Apr 12, 2021 at 9:46 PM Jisheng Zhang <[email protected]> wrote:
>
> From: Jisheng Zhang <[email protected]>
>
> patch1 removes the non-necessary setup_zero_page()
> patch2 is a trivial improvement patch to move some functions to .init
> section
>
> Then following patches improve self-protection by:
>
> Marking some variables __ro_after_init
> Constifing some variables
> Enabling ARCH_HAS_STRICT_MODULE_RWX
>
> Hi Anup,
>
> I kept the __init modification to trap_init(), I will cook a trivial
> series to provide a __weak but NULL trap_init() implementation in
> init/main.c then remove all NULL implementation from all arch.

Yes, it makes sense to do this as a separate series.

Regards,
Anup

>
> Thanks
>
> Since v2:
> - collect Reviewed-by tag
> - add one patch to remove unnecessary setup_zero_page()
>
> Since v1:
> - no need to move bpf_jit_alloc_exec() and bpf_jit_free_exec() to core
> because RV32 uses the default module_alloc() for jit code which also
> meets W^X after patch8
> - fix a build error caused by local debug code clean up
>
>
> Jisheng Zhang (10):
> riscv: mm: Remove setup_zero_page()
> riscv: add __init section marker to some functions
> riscv: Mark some global variables __ro_after_init
> riscv: Constify sys_call_table
> riscv: Constify sbi_ipi_ops
> riscv: kprobes: Implement alloc_insn_page()
> riscv: bpf: Write protect JIT code
> riscv: bpf: Avoid breaking W^X on RV64
> riscv: module: Create module allocations without exec permissions
> riscv: Set ARCH_HAS_STRICT_MODULE_RWX if MMU
>
> arch/riscv/Kconfig | 1 +
> arch/riscv/include/asm/smp.h | 4 ++--
> arch/riscv/include/asm/syscall.h | 2 +-
> arch/riscv/kernel/cpufeature.c | 2 +-
> arch/riscv/kernel/module.c | 10 ++++++++--
> arch/riscv/kernel/probes/kprobes.c | 8 ++++++++
> arch/riscv/kernel/sbi.c | 10 +++++-----
> arch/riscv/kernel/smp.c | 6 +++---
> arch/riscv/kernel/syscall_table.c | 2 +-
> arch/riscv/kernel/time.c | 2 +-
> arch/riscv/kernel/traps.c | 2 +-
> arch/riscv/kernel/vdso.c | 4 ++--
> arch/riscv/mm/init.c | 16 +++++-----------
> arch/riscv/mm/kasan_init.c | 6 +++---
> arch/riscv/mm/ptdump.c | 2 +-
> arch/riscv/net/bpf_jit_comp64.c | 2 +-
> arch/riscv/net/bpf_jit_core.c | 1 +
> 17 files changed, 45 insertions(+), 35 deletions(-)
>
> --
> 2.31.0
>
>

2021-04-13 13:27:24

by Anup Patel

[permalink] [raw]
Subject: Re: [PATCH v3 01/10] riscv: mm: Remove setup_zero_page()

On Mon, Apr 12, 2021 at 9:47 PM Jisheng Zhang <[email protected]> wrote:
>
> From: Jisheng Zhang <[email protected]>
>
> The empty_zero_page sits at .bss..page_aligned section, so will be
> cleared to zero during clearing bss, we don't need to clear it again.
>
> Signed-off-by: Jisheng Zhang <[email protected]>

Looks good to me.

Reviewed-by: Anup Patel <[email protected]>

Regards,
Anup

> ---
> arch/riscv/mm/init.c | 6 ------
> 1 file changed, 6 deletions(-)
>
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 7f5036fbee8c..dbeaa4144e4d 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -57,11 +57,6 @@ static void __init zone_sizes_init(void)
> free_area_init(max_zone_pfns);
> }
>
> -static void setup_zero_page(void)
> -{
> - memset((void *)empty_zero_page, 0, PAGE_SIZE);
> -}
> -
> #if defined(CONFIG_MMU) && defined(CONFIG_DEBUG_VM)
> static inline void print_mlk(char *name, unsigned long b, unsigned long t)
> {
> @@ -589,7 +584,6 @@ void mark_rodata_ro(void)
> void __init paging_init(void)
> {
> setup_vm_final();
> - setup_zero_page();
> }
>
> void __init misc_mem_init(void)
> --
> 2.31.0
>
>