1717#include <asm/csr.h>
1818#include <asm/usercfi.h>
1919
20+ unsigned long riscv_nousercfi __read_mostly ;
21+
2022#define SHSTK_ENTRY_SIZE sizeof(void *)
2123
2224bool is_shstk_enabled (struct task_struct * task )
@@ -59,7 +61,7 @@ unsigned long get_active_shstk(struct task_struct *task)
5961
6062void set_shstk_status (struct task_struct * task , bool enable )
6163{
62- if (!cpu_supports_shadow_stack ())
64+ if (!is_user_shstk_enabled ())
6365 return ;
6466
6567 task -> thread_info .user_cfi_state .ubcfi_en = enable ? 1 : 0 ;
@@ -89,7 +91,7 @@ bool is_indir_lp_locked(struct task_struct *task)
8991
9092void set_indir_lp_status (struct task_struct * task , bool enable )
9193{
92- if (!cpu_supports_indirect_br_lp_instr ())
94+ if (!is_user_lpad_enabled ())
9395 return ;
9496
9597 task -> thread_info .user_cfi_state .ufcfi_en = enable ? 1 : 0 ;
@@ -257,7 +259,7 @@ SYSCALL_DEFINE3(map_shadow_stack, unsigned long, addr, unsigned long, size, unsi
257259 bool set_tok = flags & SHADOW_STACK_SET_TOKEN ;
258260 unsigned long aligned_size = 0 ;
259261
260- if (!cpu_supports_shadow_stack ())
262+ if (!is_user_shstk_enabled ())
261263 return - EOPNOTSUPP ;
262264
263265 /* Anything other than set token should result in invalid param */
@@ -304,7 +306,7 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *tsk,
304306 unsigned long addr , size ;
305307
306308 /* If shadow stack is not supported, return 0 */
307- if (!cpu_supports_shadow_stack ())
309+ if (!is_user_shstk_enabled ())
308310 return 0 ;
309311
310312 /*
@@ -350,7 +352,7 @@ void shstk_release(struct task_struct *tsk)
350352{
351353 unsigned long base = 0 , size = 0 ;
352354 /* If shadow stack is not supported or not enabled, nothing to release */
353- if (!cpu_supports_shadow_stack () || !is_shstk_enabled (tsk ))
355+ if (!is_user_shstk_enabled () || !is_shstk_enabled (tsk ))
354356 return ;
355357
356358 /*
@@ -379,7 +381,7 @@ int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *st
379381{
380382 unsigned long bcfi_status = 0 ;
381383
382- if (!cpu_supports_shadow_stack ())
384+ if (!is_user_shstk_enabled ())
383385 return - EINVAL ;
384386
385387 /* this means shadow stack is enabled on the task */
@@ -393,7 +395,7 @@ int arch_set_shadow_stack_status(struct task_struct *t, unsigned long status)
393395 unsigned long size = 0 , addr = 0 ;
394396 bool enable_shstk = false;
395397
396- if (!cpu_supports_shadow_stack ())
398+ if (!is_user_shstk_enabled ())
397399 return - EINVAL ;
398400
399401 /* Reject unknown flags */
@@ -446,7 +448,7 @@ int arch_lock_shadow_stack_status(struct task_struct *task,
446448 unsigned long arg )
447449{
448450 /* If shtstk not supported or not enabled on task, nothing to lock here */
449- if (!cpu_supports_shadow_stack () ||
451+ if (!is_user_shstk_enabled () ||
450452 !is_shstk_enabled (task ) || arg != 0 )
451453 return - EINVAL ;
452454
@@ -459,7 +461,7 @@ int arch_get_indir_br_lp_status(struct task_struct *t, unsigned long __user *sta
459461{
460462 unsigned long fcfi_status = 0 ;
461463
462- if (!cpu_supports_indirect_br_lp_instr ())
464+ if (!is_user_lpad_enabled ())
463465 return - EINVAL ;
464466
465467 /* indirect branch tracking is enabled on the task or not */
@@ -472,7 +474,7 @@ int arch_set_indir_br_lp_status(struct task_struct *t, unsigned long status)
472474{
473475 bool enable_indir_lp = false;
474476
475- if (!cpu_supports_indirect_br_lp_instr ())
477+ if (!is_user_lpad_enabled ())
476478 return - EINVAL ;
477479
478480 /* indirect branch tracking is locked and further can't be modified by user */
@@ -496,11 +498,45 @@ int arch_lock_indir_br_lp_status(struct task_struct *task,
496498 * If indirect branch tracking is not supported or not enabled on task,
497499 * nothing to lock here
498500 */
499- if (!cpu_supports_indirect_br_lp_instr () ||
501+ if (!is_user_lpad_enabled () ||
500502 !is_indir_lp_enabled (task ) || arg != 0 )
501503 return - EINVAL ;
502504
503505 set_indir_lp_lock (task );
504506
505507 return 0 ;
506508}
509+
510+ bool is_user_shstk_enabled (void )
511+ {
512+ return (cpu_supports_shadow_stack () &&
513+ !(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI ));
514+ }
515+
516+ bool is_user_lpad_enabled (void )
517+ {
518+ return (cpu_supports_indirect_br_lp_instr () &&
519+ !(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI ));
520+ }
521+
522+ static int __init setup_global_riscv_enable (char * str )
523+ {
524+ if (strcmp (str , "all" ) == 0 )
525+ riscv_nousercfi = CMDLINE_DISABLE_RISCV_USERCFI ;
526+
527+ if (strcmp (str , "fcfi" ) == 0 )
528+ riscv_nousercfi |= CMDLINE_DISABLE_RISCV_USERCFI_FCFI ;
529+
530+ if (strcmp (str , "bcfi" ) == 0 )
531+ riscv_nousercfi |= CMDLINE_DISABLE_RISCV_USERCFI_BCFI ;
532+
533+ if (riscv_nousercfi )
534+ pr_info ("RISC-V user CFI disabled via cmdline - shadow stack status : %s, landing pad status : %s\n" ,
535+ (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI ) ? "disabled" :
536+ "enabled" , (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI ) ?
537+ "disabled" : "enabled" );
538+
539+ return 1 ;
540+ }
541+
542+ __setup ("riscv_nousercfi=" , setup_global_riscv_enable );
0 commit comments