]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
riscv: cfi: reject unknown flags in PR_SET_CFI
authorRichard Patel <ripatel@wii.dev>
Mon, 18 May 2026 18:39:18 +0000 (18:39 +0000)
committerPaul Walmsley <pjw@kernel.org>
Sun, 7 Jun 2026 02:17:05 +0000 (20:17 -0600)
prctl(PR_SET_CFI,PR_CFI_BRANCH_LANDING_PADS) silently ignored
unknown control values. Only PR_CFI_{ENABLE,DISABLE,LOCK} should
be permitted.

This changes the behavior of the uABI (fails previously accepted bits
with EINVAL).

Fixes: 08ee1559052b ("prctl: cfi: change the branch landing pad prctl()s to be more descriptive")
Signed-off-by: Richard Patel <ripatel@wii.dev>
Link: https://patch.msgid.link/20260518183918.322545-1-ripatel@wii.dev
[pjw@kernel.org: change the patch description to note that although this is a uABI change, it does not break the uABI]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
arch/riscv/include/asm/usercfi.h
arch/riscv/kernel/usercfi.c
tools/testing/selftests/riscv/cfi/cfitests.c

index f56966edbf5c62d053869a1f7edce313c50e4926..61ee02cee29720e40b71f53364ac8798f77ae846 100644 (file)
@@ -50,6 +50,7 @@ void set_indir_lp_status(struct task_struct *task, bool enable);
 void set_indir_lp_lock(struct task_struct *task, bool lock);
 
 #define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK (PR_SHADOW_STACK_ENABLE)
+#define PR_CFI_SUPPORTED_STATUS_MASK (PR_CFI_ENABLE | PR_CFI_DISABLE | PR_CFI_LOCK)
 
 #else
 
index cbfb4e495e9f9f78d79571d8e0b4efdf6cb4beba..5a7113d69badc2d8dd62ced2b205e6e0933a0f07 100644 (file)
@@ -467,6 +467,9 @@ int arch_prctl_set_branch_landing_pad_state(struct task_struct *t, unsigned long
        if (!is_user_lpad_enabled())
                return -EINVAL;
 
+       if (state & ~PR_CFI_SUPPORTED_STATUS_MASK)
+               return -EINVAL;
+
        /* indirect branch tracking is locked and further can't be modified by user */
        if (is_indir_lp_locked(t))
                return -EINVAL;
index 39d097b6881ff2223f5c61c42bd67594f630a6b0..0e3943461e7d83082e0319bcb1348d96c1840e4e 100644 (file)
@@ -141,6 +141,12 @@ int main(int argc, char *argv[])
 
        ksft_print_msg("Starting risc-v tests\n");
 
+       /* Test unknown PR_CFI bits */
+       ret = my_syscall5(__NR_prctl, PR_SET_CFI, PR_CFI_BRANCH_LANDING_PADS,
+                         PR_CFI_ENABLE | 0xffff0, 0, 0);
+       if (!ret)
+               ksft_exit_fail_msg("PR_SET_CFI accepted reserved branch landing pad bits\n");
+
        /*
         * Landing pad test. Not a lot of kernel changes to support landing
         * pads for user mode except lighting up a bit in senvcfg via a prctl.