2023-07-10 19:04:04

by Sami Tolvanen

[permalink] [raw]
Subject: [PATCH v2 0/6] riscv: KCFI support

This series adds KCFI support for RISC-V. KCFI is a fine-grained
forward-edge control-flow integrity scheme supported in Clang >=16,
which ensures indirect calls in instrumented code can only branch to
functions whose type matches the function pointer type, thus making
code reuse attacks more difficult.

Patch 1 implements a pt_regs based syscall wrapper to address
function pointer type mismatches in syscall handling. Patches 2 and 3
annotate indirectly called assembly functions with CFI types. Patch 4
implements error handling for indirect call checks. Patch 5 disables
CFI for arch/riscv/purgatory. Patch 6 finally allows CONFIG_CFI_CLANG
to be enabled for RISC-V.

Note that Clang 16 has a generic architecture-agnostic KCFI
implementation, which does work with the kernel, but doesn't produce
a stable code sequence for indirect call checks, which means
potential failures just trap and won't result in informative error
messages. Clang 17 includes a RISC-V specific back-end implementation
for KCFI, which emits a predictable code sequence for the checks and a
.kcfi_traps section with locations of the traps, which patch 5 uses to
produce more useful errors.

The type mismatch fixes and annotations in the first three patches
also become necessary in future if the kernel decides to support
fine-grained CFI implemented using the hardware landing pad
feature proposed in the in-progress Zicfisslp extension. Once the
specification is ratified and hardware support emerges, implementing
runtime patching support that replaces KCFI instrumentation with
Zicfisslp landing pads might also be feasible (similarly to KCFI to
FineIBT patching on x86_64), allowing distributions to ship a unified
kernel binary for all devices.

---

Changes in v2:
- Rebased on 6.5-rc1.
- Sorted Kconfig entries alphabetically.


Sami Tolvanen (6):
riscv: Implement syscall wrappers
riscv: Add types to indirectly called assembly functions
riscv: Add ftrace_stub_graph
riscv: Add CFI error handling
riscv/purgatory: Disable CFI
riscv: Allow CONFIG_CFI_CLANG to be selected

arch/riscv/Kconfig | 3 +
arch/riscv/include/asm/cfi.h | 22 ++++++
arch/riscv/include/asm/insn.h | 10 +++
arch/riscv/include/asm/syscall.h | 5 +-
arch/riscv/include/asm/syscall_wrapper.h | 87 ++++++++++++++++++++++++
arch/riscv/kernel/Makefile | 2 +
arch/riscv/kernel/cfi.c | 77 +++++++++++++++++++++
arch/riscv/kernel/compat_syscall_table.c | 8 ++-
arch/riscv/kernel/mcount.S | 9 ++-
arch/riscv/kernel/suspend_entry.S | 5 +-
arch/riscv/kernel/sys_riscv.c | 6 ++
arch/riscv/kernel/syscall_table.c | 8 ++-
arch/riscv/kernel/traps.c | 4 +-
arch/riscv/purgatory/Makefile | 4 ++
14 files changed, 238 insertions(+), 12 deletions(-)
create mode 100644 arch/riscv/include/asm/cfi.h
create mode 100644 arch/riscv/include/asm/syscall_wrapper.h
create mode 100644 arch/riscv/kernel/cfi.c


base-commit: 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5
--
2.41.0.255.g8b1d071c50-goog



2023-07-10 19:08:45

by Sami Tolvanen

[permalink] [raw]
Subject: [PATCH v2 5/6] riscv/purgatory: Disable CFI

Filter out CC_FLAGS_CFI when CONFIG_CFI_CLANG.

Reviewed-by: Kees Cook <[email protected]>
Tested-by: Nathan Chancellor <[email protected]>
Signed-off-by: Sami Tolvanen <[email protected]>
---
arch/riscv/purgatory/Makefile | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/arch/riscv/purgatory/Makefile b/arch/riscv/purgatory/Makefile
index dc20e166983e..9e6476719abb 100644
--- a/arch/riscv/purgatory/Makefile
+++ b/arch/riscv/purgatory/Makefile
@@ -77,6 +77,10 @@ ifdef CONFIG_STACKPROTECTOR_STRONG
PURGATORY_CFLAGS_REMOVE += -fstack-protector-strong
endif

+ifdef CONFIG_CFI_CLANG
+PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_CFI)
+endif
+
CFLAGS_REMOVE_purgatory.o += $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_purgatory.o += $(PURGATORY_CFLAGS)

--
2.41.0.255.g8b1d071c50-goog


2023-07-10 19:12:14

by Sami Tolvanen

[permalink] [raw]
Subject: [PATCH v2 6/6] riscv: Allow CONFIG_CFI_CLANG to be selected

Select ARCH_SUPPORTS_CFI_CLANG to allow CFI_CLANG to be selected
on riscv.

Reviewed-by: Kees Cook <[email protected]>
Tested-by: Nathan Chancellor <[email protected]>
Signed-off-by: Sami Tolvanen <[email protected]>
---
arch/riscv/Kconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 29fdba9d8514..68c790b181c3 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -43,6 +43,7 @@ config RISCV
select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
select ARCH_STACKWALK
select ARCH_SUPPORTS_ATOMIC_RMW
+ select ARCH_SUPPORTS_CFI_CLANG
select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
select ARCH_SUPPORTS_HUGETLBFS if MMU
select ARCH_SUPPORTS_PAGE_TABLE_CHECK if MMU
--
2.41.0.255.g8b1d071c50-goog


2023-07-10 19:28:49

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH v2 0/6] riscv: KCFI support

On Mon, 10 Jul 2023 11:35:45 PDT (-0700), [email protected] wrote:
> This series adds KCFI support for RISC-V. KCFI is a fine-grained
> forward-edge control-flow integrity scheme supported in Clang >=16,
> which ensures indirect calls in instrumented code can only branch to
> functions whose type matches the function pointer type, thus making
> code reuse attacks more difficult.
>
> Patch 1 implements a pt_regs based syscall wrapper to address
> function pointer type mismatches in syscall handling. Patches 2 and 3
> annotate indirectly called assembly functions with CFI types. Patch 4
> implements error handling for indirect call checks. Patch 5 disables
> CFI for arch/riscv/purgatory. Patch 6 finally allows CONFIG_CFI_CLANG
> to be enabled for RISC-V.
>
> Note that Clang 16 has a generic architecture-agnostic KCFI
> implementation, which does work with the kernel, but doesn't produce
> a stable code sequence for indirect call checks, which means
> potential failures just trap and won't result in informative error
> messages. Clang 17 includes a RISC-V specific back-end implementation
> for KCFI, which emits a predictable code sequence for the checks and a
> .kcfi_traps section with locations of the traps, which patch 5 uses to
> produce more useful errors.
>
> The type mismatch fixes and annotations in the first three patches
> also become necessary in future if the kernel decides to support
> fine-grained CFI implemented using the hardware landing pad
> feature proposed in the in-progress Zicfisslp extension. Once the
> specification is ratified and hardware support emerges, implementing
> runtime patching support that replaces KCFI instrumentation with
> Zicfisslp landing pads might also be feasible (similarly to KCFI to
> FineIBT patching on x86_64), allowing distributions to ship a unified
> kernel binary for all devices.
>
> ---
>
> Changes in v2:
> - Rebased on 6.5-rc1.
> - Sorted Kconfig entries alphabetically.
>
>
> Sami Tolvanen (6):
> riscv: Implement syscall wrappers
> riscv: Add types to indirectly called assembly functions
> riscv: Add ftrace_stub_graph
> riscv: Add CFI error handling
> riscv/purgatory: Disable CFI
> riscv: Allow CONFIG_CFI_CLANG to be selected
>
> arch/riscv/Kconfig | 3 +
> arch/riscv/include/asm/cfi.h | 22 ++++++
> arch/riscv/include/asm/insn.h | 10 +++
> arch/riscv/include/asm/syscall.h | 5 +-
> arch/riscv/include/asm/syscall_wrapper.h | 87 ++++++++++++++++++++++++
> arch/riscv/kernel/Makefile | 2 +
> arch/riscv/kernel/cfi.c | 77 +++++++++++++++++++++
> arch/riscv/kernel/compat_syscall_table.c | 8 ++-
> arch/riscv/kernel/mcount.S | 9 ++-
> arch/riscv/kernel/suspend_entry.S | 5 +-
> arch/riscv/kernel/sys_riscv.c | 6 ++
> arch/riscv/kernel/syscall_table.c | 8 ++-
> arch/riscv/kernel/traps.c | 4 +-
> arch/riscv/purgatory/Makefile | 4 ++
> 14 files changed, 238 insertions(+), 12 deletions(-)
> create mode 100644 arch/riscv/include/asm/cfi.h
> create mode 100644 arch/riscv/include/asm/syscall_wrapper.h
> create mode 100644 arch/riscv/kernel/cfi.c
>
>
> base-commit: 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5

Thanks, this generally LGTM it was just a bit late for the last merge
window. I'm still poking around to make sure there's no fallout in rc1,
this is in the queue (but there's some other stuff too).

Subject: Re: [PATCH v2 0/6] riscv: KCFI support

Hello:

This series was applied to riscv/linux.git (for-next)
by Palmer Dabbelt <[email protected]>:

On Mon, 10 Jul 2023 18:35:45 +0000 you wrote:
> This series adds KCFI support for RISC-V. KCFI is a fine-grained
> forward-edge control-flow integrity scheme supported in Clang >=16,
> which ensures indirect calls in instrumented code can only branch to
> functions whose type matches the function pointer type, thus making
> code reuse attacks more difficult.
>
> Patch 1 implements a pt_regs based syscall wrapper to address
> function pointer type mismatches in syscall handling. Patches 2 and 3
> annotate indirectly called assembly functions with CFI types. Patch 4
> implements error handling for indirect call checks. Patch 5 disables
> CFI for arch/riscv/purgatory. Patch 6 finally allows CONFIG_CFI_CLANG
> to be enabled for RISC-V.
>
> [...]

Here is the summary with links:
- [v2,1/6] riscv: Implement syscall wrappers
https://git.kernel.org/riscv/c/08d0ce30e0e4
- [v2,2/6] riscv: Add types to indirectly called assembly functions
https://git.kernel.org/riscv/c/5f59c6855bad
- [v2,3/6] riscv: Add ftrace_stub_graph
https://git.kernel.org/riscv/c/f3a0c23f2539
- [v2,4/6] riscv: Add CFI error handling
https://git.kernel.org/riscv/c/af0ead42f693
- [v2,5/6] riscv/purgatory: Disable CFI
https://git.kernel.org/riscv/c/a72ab0361110
- [v2,6/6] riscv: Allow CONFIG_CFI_CLANG to be selected
https://git.kernel.org/riscv/c/74f8fc31feb4

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html