Re: [PATCH 4/6] riscv: Add CFI error handling

From: Kees Cook
Date: Fri Jun 30 2023 - 14:27:07 EST


On Thu, Jun 29, 2023 at 11:42:49PM +0000, Sami Tolvanen wrote:
> With CONFIG_CFI_CLANG, the compiler injects a type preamble immediately
> before each function and a check to validate the target function type
> before indirect calls:
>
> ; type preamble
> .word <id>
> function:
> ...
> ; indirect call check
> lw t1, -4(a0)
> lui t2, <hi20>
> addiw t2, t2, <lo12>
> beq t1, t2, .Ltmp0
> ebreak
> .Ltmp0:
> jarl a0
>
> Implement error handling code for the ebreak traps emitted for the
> checks. This produces the following oops on a CFI failure (generated
> using lkdtm):
>
> [ 21.177245] CFI failure at lkdtm_indirect_call+0x22/0x32 [lkdtm]
> (target: lkdtm_increment_int+0x0/0x18 [lkdtm]; expected type: 0x3ad55aca)
> [ 21.178483] Kernel BUG [#1]
> [ 21.178671] Modules linked in: lkdtm
> [ 21.179037] CPU: 1 PID: 104 Comm: sh Not tainted
> 6.3.0-rc6-00037-g37d5ec6297ab #1
> [ 21.179511] Hardware name: riscv-virtio,qemu (DT)
> [ 21.179818] epc : lkdtm_indirect_call+0x22/0x32 [lkdtm]
> [ 21.180106] ra : lkdtm_CFI_FORWARD_PROTO+0x48/0x7c [lkdtm]
> [ 21.180426] epc : ffffffff01387092 ra : ffffffff01386f14 sp : ff20000000453cf0
> [ 21.180792] gp : ffffffff81308c38 tp : ff6000000243f080 t0 : ff20000000453b78
> [ 21.181157] t1 : 000000003ad55aca t2 : 000000007e0c52a5 s0 : ff20000000453d00
> [ 21.181506] s1 : 0000000000000001 a0 : ffffffff0138d170 a1 : ffffffff013870bc
> [ 21.181819] a2 : b5fea48dd89aa700 a3 : 0000000000000001 a4 : 0000000000000fff
> [ 21.182169] a5 : 0000000000000004 a6 : 00000000000000b7 a7 : 0000000000000000
> [ 21.182591] s2 : ff20000000453e78 s3 : ffffffffffffffea s4 : 0000000000000012
> [ 21.183001] s5 : ff600000023c7000 s6 : 0000000000000006 s7 : ffffffff013882a0
> [ 21.183653] s8 : 0000000000000008 s9 : 0000000000000002 s10: ffffffff0138d878
> [ 21.184245] s11: ffffffff0138d878 t3 : 0000000000000003 t4 : 0000000000000000
> [ 21.184591] t5 : ffffffff8133df08 t6 : ffffffff8133df07
> [ 21.184858] status: 0000000000000120 badaddr: 0000000000000000
> cause: 0000000000000003
> [ 21.185415] [<ffffffff01387092>] lkdtm_indirect_call+0x22/0x32 [lkdtm]
> [ 21.185772] [<ffffffff01386f14>] lkdtm_CFI_FORWARD_PROTO+0x48/0x7c [lkdtm]
> [ 21.186093] [<ffffffff01383552>] lkdtm_do_action+0x22/0x34 [lkdtm]
> [ 21.186445] [<ffffffff0138350c>] direct_entry+0x128/0x13a [lkdtm]
> [ 21.186817] [<ffffffff8033ed8c>] full_proxy_write+0x58/0xb2
> [ 21.187352] [<ffffffff801d4fe8>] vfs_write+0x14c/0x33a
> [ 21.187644] [<ffffffff801d5328>] ksys_write+0x64/0xd4
> [ 21.187832] [<ffffffff801d53a6>] sys_write+0xe/0x1a
> [ 21.188171] [<ffffffff80003996>] ret_from_syscall+0x0/0x2
> [ 21.188595] Code: 0513 0f65 a303 ffc5 53b7 7e0c 839b 2a53 0363 0073 (9002) 9582
> [ 21.189178] ---[ end trace 0000000000000000 ]---
> [ 21.189590] Kernel panic - not syncing: Fatal exception
>
> Signed-off-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx>

Looks good -- should the noaddr failure paths include any warnings of
their own? (i.e. isn't that unexpected?)

Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx>

--
Kees Cook