mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
When libc locks the CFI status through the following prctl: - PR_LOCK_SHADOW_STACK_STATUS - PR_LOCK_INDIR_BR_LP_STATUS A newly execd address space will inherit the lock status if it does not clear the lock bits. Since the lock bits remain set, libc will later fail to enable the landing pad and shadow stack. Signed-off-by: Zong Li <zong.li@sifive.com> Link: https://patch.msgid.link/20260323065640.4045713-1-zong.li@sifive.com [pjw@kernel.org: ensure we unlock before changing state; cleaned up subject line] Signed-off-by: Paul Walmsley <pjw@kernel.org>
98 lines
3.0 KiB
C
98 lines
3.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0
|
|
* Copyright (C) 2024 Rivos, Inc.
|
|
* Deepak Gupta <debug@rivosinc.com>
|
|
*/
|
|
#ifndef _ASM_RISCV_USERCFI_H
|
|
#define _ASM_RISCV_USERCFI_H
|
|
|
|
#define CMDLINE_DISABLE_RISCV_USERCFI_FCFI 1
|
|
#define CMDLINE_DISABLE_RISCV_USERCFI_BCFI 2
|
|
#define CMDLINE_DISABLE_RISCV_USERCFI 3
|
|
|
|
#ifndef __ASSEMBLER__
|
|
#include <linux/types.h>
|
|
#include <linux/prctl.h>
|
|
#include <linux/errno.h>
|
|
|
|
struct task_struct;
|
|
struct kernel_clone_args;
|
|
|
|
extern unsigned long riscv_nousercfi;
|
|
|
|
#ifdef CONFIG_RISCV_USER_CFI
|
|
struct cfi_state {
|
|
unsigned long ubcfi_en : 1; /* Enable for backward cfi. */
|
|
unsigned long ubcfi_locked : 1;
|
|
unsigned long ufcfi_en : 1; /* Enable for forward cfi. Note that ELP goes in sstatus */
|
|
unsigned long ufcfi_locked : 1;
|
|
unsigned long user_shdw_stk; /* Current user shadow stack pointer */
|
|
unsigned long shdw_stk_base; /* Base address of shadow stack */
|
|
unsigned long shdw_stk_size; /* size of shadow stack */
|
|
};
|
|
|
|
unsigned long shstk_alloc_thread_stack(struct task_struct *tsk,
|
|
const struct kernel_clone_args *args);
|
|
void shstk_release(struct task_struct *tsk);
|
|
void set_shstk_base(struct task_struct *task, unsigned long shstk_addr, unsigned long size);
|
|
unsigned long get_shstk_base(struct task_struct *task, unsigned long *size);
|
|
void set_active_shstk(struct task_struct *task, unsigned long shstk_addr);
|
|
bool is_shstk_enabled(struct task_struct *task);
|
|
bool is_shstk_locked(struct task_struct *task);
|
|
bool is_shstk_allocated(struct task_struct *task);
|
|
void set_shstk_lock(struct task_struct *task, bool lock);
|
|
void set_shstk_status(struct task_struct *task, bool enable);
|
|
unsigned long get_active_shstk(struct task_struct *task);
|
|
int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr);
|
|
int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_ptr);
|
|
bool is_indir_lp_enabled(struct task_struct *task);
|
|
bool is_indir_lp_locked(struct task_struct *task);
|
|
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)
|
|
|
|
#else
|
|
|
|
#define shstk_alloc_thread_stack(tsk, args) 0
|
|
|
|
#define shstk_release(tsk)
|
|
|
|
#define get_shstk_base(task, size) 0UL
|
|
|
|
#define set_shstk_base(task, shstk_addr, size) do {} while (0)
|
|
|
|
#define set_active_shstk(task, shstk_addr) do {} while (0)
|
|
|
|
#define is_shstk_enabled(task) false
|
|
|
|
#define is_shstk_locked(task) false
|
|
|
|
#define is_shstk_allocated(task) false
|
|
|
|
#define set_shstk_lock(task, lock) do {} while (0)
|
|
|
|
#define set_shstk_status(task, enable) do {} while (0)
|
|
|
|
#define is_indir_lp_enabled(task) false
|
|
|
|
#define is_indir_lp_locked(task) false
|
|
|
|
#define set_indir_lp_status(task, enable) do {} while (0)
|
|
|
|
#define set_indir_lp_lock(task, lock) do {} while (0)
|
|
|
|
#define restore_user_shstk(tsk, shstk_ptr) -EINVAL
|
|
|
|
#define save_user_shstk(tsk, saved_shstk_ptr) -EINVAL
|
|
|
|
#define get_active_shstk(task) 0UL
|
|
|
|
#endif /* CONFIG_RISCV_USER_CFI */
|
|
|
|
bool is_user_shstk_enabled(void);
|
|
bool is_user_lpad_enabled(void);
|
|
|
|
#endif /* __ASSEMBLER__ */
|
|
|
|
#endif /* _ASM_RISCV_USERCFI_H */
|