mirror of
https://github.com/openharmony/kernel_linux_common_modules.git
synced 2026-08-26 17:16:37 -04:00
feat: Support PAC(Pointer Authentication Code) for linux kernel
Signed-off-by: Haryslee <lihao189@huawei.com>
This commit is contained in:
@@ -8,5 +8,6 @@
|
||||
./code_sign
|
||||
./container_escape_detection
|
||||
./module_sample
|
||||
./pac/
|
||||
|
||||
As for the specific use of the licenses, please refer to the relevant description in the documents.
|
||||
|
||||
@@ -66,6 +66,7 @@ Note:If the text contains special characters, please escape them according to th
|
||||
<policyitem type="compatibility" name="GPL" path="container_escape_detection/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="compatibility" name="GPL" path="tzdriver/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="compatibility" name="GPL" path="module_sample/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="compatibility" name="GPL" path="pac/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
|
||||
<policyitem type="license" name="GPL" path="newip/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="xpm/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
@@ -75,6 +76,7 @@ Note:If the text contains special characters, please escape them according to th
|
||||
<policyitem type="license" name="GPL" path="code_sign/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="container_escape_detection/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="module_sample/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="tzdriver/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="pac/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
|
||||
<policyitem type="copyright" name="Huawei Technologies Co." path="tzdriver/.*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Copyright information"/>
|
||||
@@ -97,6 +99,7 @@ Note:If the text contains special characters, please escape them according to th
|
||||
<filteritem type="filepath" name="newip/figures/.*"/>
|
||||
<filteritem type="filepath" name="xpm/figures/.*"/>
|
||||
<filteritem type="filepath" name="qos_auth/figures/.*"/>
|
||||
<filteritem type="filepath" name="ucollection/figures/.*"/>
|
||||
<filteritem type="filepath" name="tzdriver/figures/.*"/>
|
||||
<filteritem type="filepath" name="pac/figures/.*"/>
|
||||
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
#
|
||||
# Makefile for the Linux PAC module.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_ARM64_PTR_AUTH_EXT) += src/pointer_auth_key.o
|
||||
obj-$(CONFIG_ARM64_PTR_AUTH_EXT) += src/asm_pointer_auth_key.o
|
||||
obj-$(CONFIG_ARM64_PTR_AUTH_DATA_FIELD) += src/pointer_auth_context.o
|
||||
obj-$(CONFIG_ARM64_PTR_AUTH_DATA_FIELD) += src/asm_pointer_auth_context.o
|
||||
obj-$(CONFIG_CONSTRUCTORS) += src/asm_pointer_auth_constructors.o
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
## 背景
|
||||
|
||||
现阶段,内存安全漏洞是对计算机系统安全最严重的威胁。从漏洞利用的角度分析,借助常见的攻击手段,包括利用缓冲区溢出等实现JOP/ROP攻击,攻击者可以实现控制流劫持,最终导致任意代码执行,这严重摧毁了一个系统的安全性。另一方面,在攻击者利用内存漏洞做提权的过程中,通常会修改指向关键数据(如Cred)的数据指针,这类攻击被归纳为DOP攻击,同样会对系统安全产生严重威胁。
|
||||
因此,系统需要高效的漏洞防利用机制,以保护系统的控制流完整性和数据流完整性,这对于提升系统的安全竞争力具有重要意义。当前,从安全性角度,对于系统安全主流的JOP/ROP/DOP攻击,PAC机制均能实现有效防护。
|
||||
|
||||
## PAC(Pointer Authentication Code)模块
|
||||
|
||||
PAC模块利用ARMv8.3-a架构提供的PAC特性,基于linux内核提供PAC相关的特性支持,包括密钥管理、数据和指针签名验签,以及任务切换上下文、异常中断上下文的PAC保护机制。PAC主要功能实现如下:
|
||||
|
||||
### 1.密钥管理
|
||||
|
||||
ARMv8.3-a指令集引入了硬件安全特性PAC,用于保护内存中指针和其他数据的完整性。原理是:ARM硬件基于QARMA密码算法,将被保护的指针或数据、用于签名的密钥和盐值作为输入,计算输出一个MAC值,对于指针来说,将有效的MAC值存放在指针的未使用高位,对于数据来说,需要另开辟内存用于保存MAC值。
|
||||
|
||||
<img src="./figures/pac.png" width=600 alt="PAC原理"/>
|
||||
|
||||
Linux内核的密钥管理分为用户态密钥和内核态密钥,示意图如下:
|
||||
|
||||

|
||||
|
||||
### 2.关键数据和指针保护
|
||||
|
||||
Linux内核可以利用PAC模块对任务切换上下文、异常中断上下文中的关键字段进行保护,防止在上下文切换的过程中,攻击者利用内存漏洞提权修改关键字段,最终导致任意代码执行。
|
||||
|
||||

|
||||
|
||||
## 目录
|
||||
|
||||
PAC主要代码目录结构如下:
|
||||
|
||||
```
|
||||
# 代码路径 /kernel/linux/common_modules/pac
|
||||
├── config # 关键数据、指针标记配置文件
|
||||
├── figures # ReadMe 内嵌图例
|
||||
├── include # PAC头文件
|
||||
├── src # PAC代码
|
||||
└── Makefile
|
||||
```
|
||||
|
||||
## 配置指导
|
||||
|
||||
1. PAC使能
|
||||
|
||||
`CONFIG_ARM64_PTR_AUTH=y`
|
||||
|
||||
2. 密钥使能
|
||||
|
||||
`CONFIG_ARM64_PTR_AUTH_EXT=y`
|
||||
|
||||
3. 关键数据和指针保护使能
|
||||
|
||||
`CONFIG_ARM64_PTR_AUTH_DATA_PTR=y`
|
||||
|
||||
`CONFIG_ARM64_PTR_AUTH_DATA_FIELD=y`
|
||||
|
||||
4. 前向CFI使能
|
||||
|
||||
`CONFIG_ARM64_PTR_AUTH_FWD_CFI=y`
|
||||
|
||||
## 相关仓
|
||||
|
||||
[内核子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%86%85%E6%A0%B8%E5%AD%90%E7%B3%BB%E7%BB%9F.md)
|
||||
|
||||
[kernel_linux_5.10](https://gitee.com/openharmony/kernel_linux_5.10)
|
||||
|
||||
[kernel_linux_config](https://gitee.com/openharmony/kernel_linux_config)
|
||||
|
||||
[kernel_linux_build](https://gitee.com/openharmony/kernel_linux_build)
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
OHOS_SOURCE_ROOT=$1
|
||||
KERNEL_BUILD_ROOT=$2
|
||||
PRODUCT_NAME=$3
|
||||
KERNEL_VERSION=$4
|
||||
PAC_SOURCE_ROOT=$OHOS_SOURCE_ROOT/kernel/linux/common_modules/pac
|
||||
|
||||
function main()
|
||||
{
|
||||
pushd .
|
||||
|
||||
if [ ! -d " $KERNEL_BUILD_ROOT/arch/arm64/pac/src" ]; then
|
||||
mkdir -p $KERNEL_BUILD_ROOT/arch/arm64/pac/src
|
||||
fi
|
||||
|
||||
if [ ! -d " $KERNEL_BUILD_ROOT/arch/arm64/pac/config" ]; then
|
||||
mkdir -p $KERNEL_BUILD_ROOT/arch/arm64/pac/config
|
||||
fi
|
||||
|
||||
cd $KERNEL_BUILD_ROOT/arch/arm64/pac
|
||||
ln -s -f $(realpath --relative-to=$KERNEL_BUILD_ROOT/arch/arm64/pac $PAC_SOURCE_ROOT)/Makefile ./Makefile
|
||||
|
||||
cd $KERNEL_BUILD_ROOT/arch/arm64/pac/config
|
||||
ln -s -f $(realpath --relative-to=$KERNEL_BUILD_ROOT/arch/arm64/pac/config $PAC_SOURCE_ROOT/config)/config.txt ./config.txt
|
||||
|
||||
cd $KERNEL_BUILD_ROOT/arch/arm64/pac/src
|
||||
ln -s -f $(realpath --relative-to=$KERNEL_BUILD_ROOT/arch/arm64/pac/src $PAC_SOURCE_ROOT/src)/* ./
|
||||
|
||||
cd $KERNEL_BUILD_ROOT/arch/arm64/include/asm
|
||||
ln -s -f $(realpath --relative-to=$KERNEL_BUILD_ROOT/arch/arm64/include/asm $PAC_SOURCE_ROOT/include)/* ./
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
main
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
struct.task_struct mm
|
||||
struct.task_struct real_parent
|
||||
struct.task_struct sched_task_group
|
||||
struct.task_struct files
|
||||
struct.task_struct nsproxy
|
||||
struct.task_struct ptracer_cred
|
||||
struct.task_struct real_cred
|
||||
struct.task_struct cred
|
||||
struct.task_struct security
|
||||
struct.task_struct splice_pipe
|
||||
struct.task_struct fs
|
||||
struct.cred session_keyring
|
||||
struct.cred process_keyring
|
||||
struct.cred thread_keyring
|
||||
struct.cred request_key_auth
|
||||
struct.cred security
|
||||
struct.cred user
|
||||
struct.cred user_ns
|
||||
struct.cred group_info
|
||||
struct.super_block s_root
|
||||
struct.super_block s_xattr
|
||||
struct.super_block s_d_op
|
||||
struct.super_block s_vop
|
||||
struct.super_block s_security
|
||||
struct.mount mnt_parent
|
||||
struct.mount mnt_mountpoint
|
||||
struct.mount mnt_mp
|
||||
struct.vfsmount mnt_root
|
||||
struct.vfsmount mnt_sb
|
||||
struct.inode i_op
|
||||
struct.inode i_sb
|
||||
struct.inode i_verity_info
|
||||
struct.inode i_security
|
||||
struct.inode i_mapping
|
||||
struct.dentry d_parent
|
||||
struct.dentry d_inode
|
||||
struct.dentry d_op
|
||||
struct.dentry d_sb
|
||||
struct.selinux_state status_page
|
||||
struct.selinux_state avc
|
||||
struct.selinux_state policy
|
||||
struct.avc_entry xp_node
|
||||
struct.shmid_kernel shm_file
|
||||
struct.file f_security
|
||||
struct.msg_msg security
|
||||
struct.kern_ipc_perm security
|
||||
struct.lsm_info blobs
|
||||
struct.sock_fprog filter
|
||||
struct.nsproxy mnt_ns
|
||||
struct.nsproxy pid_ns_for_children
|
||||
struct.nsproxy net_ns
|
||||
struct.nsproxy uts_ns
|
||||
struct.nsproxy ipc_ns
|
||||
struct.nsproxy time_ns
|
||||
struct.nsproxy time_ns_for_children
|
||||
struct.nsproxy cgroup_ns
|
||||
Executable
Executable
Executable
@@ -0,0 +1,172 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_POINTER_AUTH_CONTEXT_H
|
||||
#define __ASM_POINTER_AUTH_CONTEXT_H
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
/* Compute and store hash value of cpu context. */
|
||||
.macro sign_thread_context_common, tmp1=x0, tmp2=x1, tmp3=x2
|
||||
pacga \tmp2, \tmp1, \tmp2
|
||||
pacga \tmp2, \tmp3, \tmp2
|
||||
str \tmp2, [\tmp1, CPU_CONTEXT_PAC_HASH]
|
||||
.endm
|
||||
|
||||
/* Compute and auth hash value of cpu context. */
|
||||
.macro auth_thread_context_common, tmp1=x0, tmp2=x1, tmp3=x2
|
||||
pacga \tmp2, \tmp1, \tmp2
|
||||
pacga \tmp2, \tmp3, \tmp2
|
||||
ldr \tmp3, [\tmp1, CPU_CONTEXT_PAC_HASH]
|
||||
cmp \tmp2, \tmp3
|
||||
b.ne .Lthread_context_pac_panic\@
|
||||
b .Lauth_thread_context_done\@
|
||||
.Lthread_context_pac_panic\@:
|
||||
adrp x0, .Lthread_context_pac_str
|
||||
add x0, x0, :lo12:.Lthread_context_pac_str
|
||||
bl panic
|
||||
.Lauth_thread_context_done\@:
|
||||
.endm
|
||||
|
||||
/* Compute and store hash value of the regs. */
|
||||
.macro sign_exception_context_common, tmp1=x0, tmp2=x1, tmp3=x2, tmp4=x3, tmp5=x4, tmp6=x5, tmp7=x6
|
||||
pacga \tmp2, \tmp1, \tmp2
|
||||
pacga \tmp2, \tmp3, \tmp2
|
||||
pacga \tmp2, \tmp4, \tmp2
|
||||
pacga \tmp2, \tmp5, \tmp2
|
||||
pacga \tmp2, \tmp6, \tmp2
|
||||
pacga \tmp2, \tmp7, \tmp2
|
||||
str \tmp2, [\tmp1, S_PAC_HASH]
|
||||
.endm
|
||||
|
||||
/* Compute and auth hash value of the regs. */
|
||||
.macro auth_exception_context_common, tmp1=x0, tmp2=x1, tmp3=x2, tmp4=x3, tmp5=x4, tmp6=x5, tmp7=x6
|
||||
pacga \tmp2, \tmp1, \tmp2
|
||||
pacga \tmp2, \tmp3, \tmp2
|
||||
pacga \tmp2, \tmp4, \tmp2
|
||||
pacga \tmp2, \tmp5, \tmp2
|
||||
pacga \tmp2, \tmp6, \tmp2
|
||||
pacga \tmp2, \tmp7, \tmp2
|
||||
ldr \tmp3, [\tmp1, S_PAC_HASH]
|
||||
cmp \tmp2, \tmp3
|
||||
b.ne .Lpt_regs_pac_panic\@
|
||||
b .Lauth_exception_context_done\@
|
||||
.Lpt_regs_pac_panic\@:
|
||||
adrp x0, .Lpt_regs_pac_panic_str
|
||||
add x0, x0, :lo12:.Lpt_regs_pac_panic_str
|
||||
bl panic
|
||||
.Lauth_exception_context_done\@:
|
||||
.endm
|
||||
|
||||
.Lpt_regs_pac_panic_str:
|
||||
.asciz "Failed to match pac hash of exception context!\n"
|
||||
.align 2
|
||||
|
||||
.Lthread_context_pac_str:
|
||||
.asciz "Failed to match pac hash of cpu context!\n"
|
||||
.align 2
|
||||
|
||||
.macro pac_cpu_context sign_or_auth
|
||||
.if \sign_or_auth == 0
|
||||
/* x0: base of curr task */
|
||||
mov x2, x0
|
||||
.else
|
||||
/* x1: base of next task */
|
||||
mov x2, x1
|
||||
.endif
|
||||
add x2, x2, #THREAD_CPU_CONTEXT
|
||||
/* sign sp, lr of cpu context. */
|
||||
mov x3, lr
|
||||
mov x4, x9
|
||||
.if \sign_or_auth == 0
|
||||
sign_thread_context_common x2, x3, x4
|
||||
.else
|
||||
auth_thread_context_common x2, x3, x4
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro sign_cpu_context sign=0
|
||||
pac_cpu_context \sign
|
||||
.endm
|
||||
|
||||
.macro auth_cpu_context auth=1
|
||||
pac_cpu_context \auth
|
||||
.endm
|
||||
|
||||
.macro prepare_compat_pt_regs, sign_or_auth
|
||||
/* base of pt_regs */
|
||||
mov x23, sp
|
||||
mov x24, #0
|
||||
mov x25, #0
|
||||
/* sign lr, sp, pc, pstate of compat task */
|
||||
mov x26, x14
|
||||
mov x27, x13
|
||||
mrs x20, elr_el1
|
||||
.if \sign_or_auth == 0
|
||||
mrs x21, spsr_el1
|
||||
.else
|
||||
mov x21, x22
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro prepare_pt_regs, el, sign_or_auth
|
||||
/* base of pt_regs */
|
||||
mov x23, sp
|
||||
/* sign x16, x17, lr, sp, pc, pstate of task */
|
||||
mov x24, x16
|
||||
mov x25, x17
|
||||
.if \sign_or_auth == 0
|
||||
mov x26, lr
|
||||
.else
|
||||
ldr x26, [x23, #S_LR]
|
||||
.endif
|
||||
.if \el == 0
|
||||
mrs x27, sp_el0
|
||||
.else
|
||||
add x27, x23, #S_FRAME_SIZE
|
||||
.endif
|
||||
mrs x20, elr_el1
|
||||
.if \sign_or_auth == 0
|
||||
mrs x21, spsr_el1
|
||||
.else
|
||||
mov x21, x22
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro pac_pt_regs, el, sign_or_auth
|
||||
.if \el == 0
|
||||
/* Test the task is in the mode of 32-bit or 64-bit */
|
||||
mrs x23, spsr_el1
|
||||
mov x24, #(PSR_MODE32_BIT | PSR_MODE_MASK)
|
||||
mov x25, #(PSR_MODE32_BIT | PSR_MODE_EL0t)
|
||||
and x23, x23, x24
|
||||
sub x23, x23, x25
|
||||
cbnz x23, .Lis_not_compat_task\@
|
||||
/* Task in 32-bit mode */
|
||||
prepare_compat_pt_regs \sign_or_auth
|
||||
b .Lpac_handle\@
|
||||
.endif
|
||||
/* Task in 64-bit mode */
|
||||
.Lis_not_compat_task\@:
|
||||
prepare_pt_regs \el, \sign_or_auth
|
||||
/* Call the sign or auth function. */
|
||||
.Lpac_handle\@:
|
||||
.if \sign_or_auth == 0
|
||||
sign_exception_context_common x23, x24, x25, x26, x27, x20, x21
|
||||
.else
|
||||
auth_exception_context_common x23, x24, x25, x26, x27, x20, x21
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro sign_pt_regs, el, sign=0
|
||||
pac_pt_regs \el, \sign
|
||||
.endm
|
||||
|
||||
.macro auth_pt_regs, el, auth=1
|
||||
pac_pt_regs \el, \auth
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_POINTER_AUTH_CONTEXT_H */
|
||||
@@ -0,0 +1,64 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*
|
||||
* Pointer authentication keys initialisation.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_POINTER_AUTH_KEY_H
|
||||
#define __ASM_POINTER_AUTH_KEY_H
|
||||
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/cpucaps.h>
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
.macro __ptrauth_address_keys_install_kernel tmp1, tmp2, tmp3
|
||||
ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_KERNEL_KEY_APIB]
|
||||
msr_s SYS_APIBKEYLO_EL1, \tmp2
|
||||
msr_s SYS_APIBKEYHI_EL1, \tmp3
|
||||
|
||||
adr_l \tmp1, kernel_common_keys
|
||||
ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_KERNEL_KEY_APIA]
|
||||
msr_s SYS_APIAKEYLO_EL1, \tmp2
|
||||
msr_s SYS_APIAKEYHI_EL1, \tmp3
|
||||
|
||||
ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_KERNEL_KEY_APDA]
|
||||
msr_s SYS_APDAKEYLO_EL1, \tmp2
|
||||
msr_s SYS_APDAKEYHI_EL1, \tmp3
|
||||
|
||||
ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_KERNEL_KEY_APDB]
|
||||
msr_s SYS_APDBKEYLO_EL1, \tmp2
|
||||
msr_s SYS_APDBKEYHI_EL1, \tmp3
|
||||
.endm
|
||||
|
||||
.macro __ptrauth_generic_key_install_kernel tmp1, tmp2, tmp3
|
||||
ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_KERNEL_KEY_APGA]
|
||||
msr_s SYS_APGAKEYLO_EL1, \tmp2
|
||||
msr_s SYS_APGAKEYHI_EL1, \tmp3
|
||||
.endm
|
||||
|
||||
.macro ptrauth_keys_install_kernel_all tsk, tmp1, tmp2, tmp3
|
||||
mov \tmp1, #THREAD_KEYS_KERNEL
|
||||
add \tmp1, \tsk, \tmp1
|
||||
|
||||
alternative_if_not ARM64_HAS_ADDRESS_AUTH
|
||||
b .Lno_addr_auth\@
|
||||
alternative_else_nop_endif
|
||||
__ptrauth_address_keys_install_kernel \tmp1, \tmp2, \tmp3
|
||||
|
||||
.Lno_addr_auth\@:
|
||||
alternative_if ARM64_HAS_GENERIC_AUTH
|
||||
__ptrauth_generic_key_install_kernel \tmp1, \tmp2, \tmp3
|
||||
alternative_else_nop_endif
|
||||
isb
|
||||
.endm
|
||||
|
||||
.macro __ptrauth_keys_install_kernel_all tsk, tmp1, tmp2, tmp3
|
||||
mov \tmp1, #THREAD_KEYS_KERNEL
|
||||
add \tmp1, \tsk, \tmp1
|
||||
__ptrauth_address_keys_install_kernel \tmp1, \tmp2, \tmp3
|
||||
__ptrauth_generic_key_install_kernel \tmp1, \tmp2, \tmp3
|
||||
.endm
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __POINTER_AUTH_COMMON_H__
|
||||
#define __POINTER_AUTH_COMMON_H__
|
||||
|
||||
#define is_addr_error(addr) (((addr) >> 48) ^ 0xffff)
|
||||
|
||||
#define pauth_sign(type, key, addr, mod) \
|
||||
pauth_common(pac, type, key, addr, mod)
|
||||
|
||||
#define pauth_validate(type, key, addr, mod) \
|
||||
pauth_common(aut, type, key, addr, mod)
|
||||
|
||||
#define pauth_strip(type, addr) \
|
||||
({ \
|
||||
const void *__addr = (addr); \
|
||||
\
|
||||
asm ("xpac" #type " %0\n" : "+r" (__addr)); \
|
||||
(typeof (addr))__addr; \
|
||||
})
|
||||
|
||||
#define pauth_hash(addr, mod) ((unsigned int) (pauth_pacga(addr, mod) >> 32))
|
||||
|
||||
#define pauth_common(prefix, type, key, addr, mod) \
|
||||
({ \
|
||||
const void *__addr = (addr); \
|
||||
unsigned long __mod = (unsigned long)(mod); \
|
||||
\
|
||||
if (__builtin_constant_p(mod) && (__mod == 0)) \
|
||||
asm (#prefix #type "z" #key " %0\n" : "+r" (__addr)); \
|
||||
else \
|
||||
asm (#prefix #type #key " %0, %1\n" : "+r" (__addr) : \
|
||||
"r" (__mod)); \
|
||||
(typeof (addr))(__addr); \
|
||||
})
|
||||
|
||||
#define pauth_get_raw_data(addr) \
|
||||
({ \
|
||||
const void *__addr; \
|
||||
asm ("mov %0, %1\n" : "=&r" (__addr) : \
|
||||
"r" (addr)); \
|
||||
(void *)(__addr); \
|
||||
})
|
||||
|
||||
#define pauth_sign_function(fun, mod, key) \
|
||||
({ \
|
||||
const void *__fun = (fun); \
|
||||
unsigned long __mod = (unsigned long)(mod); \
|
||||
asm ("paci" #key " %0, %1\n" : "+r" (__fun) : \
|
||||
"r" (__mod)); \
|
||||
(void *)(__fun); \
|
||||
})
|
||||
|
||||
#define pauth_pacda(addr, mod) pauth_common(pac, d, a, addr, mod)
|
||||
|
||||
#define pauth_pacdb(addr, mod) pauth_common(pac, d, b, addr, mod)
|
||||
|
||||
#define pauth_pacia(addr, mod) pauth_common(pac, i, a, addr, mod)
|
||||
|
||||
#define pauth_pacib(addr, mod) pauth_common(pac, i, b, addr, mod)
|
||||
|
||||
#define pauth_pacga(addr, mod) \
|
||||
({ \
|
||||
const void *__addr = (addr); \
|
||||
unsigned long __mod = (unsigned long)(mod); \
|
||||
unsigned long __pac; \
|
||||
\
|
||||
asm ("pacga %0, %1, %2\n" : "=r" (__pac) : "r" (__addr), \
|
||||
"r" (__mod)); \
|
||||
__pac; \
|
||||
})
|
||||
|
||||
#define pauth_autda(addr, mod) pauth_common(aut, d, a, addr, mod)
|
||||
|
||||
#define pauth_autdb(addr, mod) pauth_common(aut, d, b, addr, mod)
|
||||
|
||||
#define pauth_autia(addr, mod) pauth_common(aut, i, a, addr, mod)
|
||||
|
||||
#define pauth_autib(addr, mod) pauth_common(aut, i, b, addr, mod)
|
||||
|
||||
#define pauth_xpacd(addr) pauth_strip(d, addr)
|
||||
|
||||
#define pauth_xpaci(addr) pauth_strip(i, addr)
|
||||
|
||||
#endif /* __POINTER_AUTH_COMMON_H__ */
|
||||
@@ -0,0 +1,119 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __POINTER_AUTH_CONTEXT_H
|
||||
#define __POINTER_AUTH_CONTEXT_H
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
enum pac_pt_regs {
|
||||
REGS_X16 = 0,
|
||||
REGS_X17,
|
||||
REGS_LR,
|
||||
REGS_SP,
|
||||
REGS_PC,
|
||||
REGS_PSTATE,
|
||||
};
|
||||
|
||||
void sign_thread_context(void *cpu_context);
|
||||
void auth_thread_context(void *cpu_context);
|
||||
|
||||
void sign_exception_context_asm(void *regs);
|
||||
void auth_exception_context_asm(void *regs);
|
||||
|
||||
int set_exception_context_register_asm(void *regs, int offset, u64 val);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
void sign_compat_exception_context_asm(void *regs);
|
||||
void auth_compat_exception_context_asm(void *regs);
|
||||
|
||||
int set_compat_exception_context_register_asm(void *regs, int offset, u64 val);
|
||||
#else
|
||||
static inline void sign_compat_exception_context_asm(void *regs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void auth_compat_exception_context_asm(void *regs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int set_compat_exception_context_register_asm(void *regs, int offset, u64 val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void sign_compat_exception_context_unsafe(void *regs)
|
||||
{
|
||||
return sign_compat_exception_context_asm(regs);
|
||||
}
|
||||
|
||||
static inline void auth_compat_exception_context_unsafe(void *regs)
|
||||
{
|
||||
return auth_compat_exception_context_asm(regs);
|
||||
}
|
||||
|
||||
static inline void sign_exception_context_unsafe(void *regs)
|
||||
{
|
||||
if (compat_user_mode((struct pt_regs *)regs)) {
|
||||
sign_compat_exception_context_asm(regs);
|
||||
} else {
|
||||
sign_exception_context_asm(regs);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void auth_exception_context_unsafe(void *regs)
|
||||
{
|
||||
if (compat_user_mode((struct pt_regs *)regs)) {
|
||||
auth_compat_exception_context_asm(regs);
|
||||
} else {
|
||||
auth_exception_context_asm(regs);
|
||||
}
|
||||
}
|
||||
|
||||
#define resign_compat_exception_context_start(regs) \
|
||||
do { \
|
||||
unsigned long irq_flags; \
|
||||
local_irq_save(irq_flags); \
|
||||
auth_compat_exception_context_asm(regs);
|
||||
|
||||
#define resign_compat_exception_context_end(regs) \
|
||||
sign_compat_exception_context_asm(regs); \
|
||||
local_irq_restore(irq_flags); \
|
||||
} while (0)
|
||||
|
||||
#define resign_exception_context_start(regs) \
|
||||
do { \
|
||||
unsigned long irq_flags; \
|
||||
local_irq_save(irq_flags); \
|
||||
auth_exception_context_unsafe(regs);
|
||||
|
||||
#define resign_exception_context_end(regs) \
|
||||
sign_exception_context_unsafe(regs); \
|
||||
local_irq_restore(irq_flags); \
|
||||
} while (0)
|
||||
|
||||
#define sign_exception_context_start(regs) \
|
||||
do { \
|
||||
unsigned long irq_flags; \
|
||||
local_irq_save(irq_flags);
|
||||
|
||||
#define sign_exception_context_end(regs) \
|
||||
sign_exception_context_unsafe(regs); \
|
||||
local_irq_restore(irq_flags); \
|
||||
} while (0)
|
||||
|
||||
void sign_compat_exception_context(void *regs);
|
||||
void auth_compat_exception_context(void *regs);
|
||||
void sign_exception_context(void *regs);
|
||||
void auth_exception_context(void *regs);
|
||||
|
||||
int set_compat_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val);
|
||||
void set_compat_exception_context_register_index(struct pt_regs *regs, int index, u64 val);
|
||||
int set_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val);
|
||||
void set_exception_context_register_index(struct pt_regs *regs, int index, u64 val);
|
||||
|
||||
#endif /* __POINTER_AUTH_CONTEXT_H */
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
.pushsection ".init.text", "ax"
|
||||
|
||||
SYM_CODE_START(init_constructors)
|
||||
mov x21, x30
|
||||
adrp x19, __ctors_end
|
||||
adrp x20, __ctors_start
|
||||
add x19, x19, #:lo12:__ctors_end
|
||||
add x20, x20, #:lo12:__ctors_start
|
||||
cmp x20, x19
|
||||
b.cs 4f
|
||||
3: ldr x8, [x20], #8
|
||||
blr x8
|
||||
cmp x20, x19
|
||||
b.cc 3b
|
||||
4: mov x30, x21
|
||||
ret
|
||||
SYM_CODE_END(init_constructors)
|
||||
@@ -0,0 +1,246 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "asm/asm_pointer_auth_context.h"
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
/* Obtain the regs of compat task to sign or authenticate. */
|
||||
.macro ldr_compat_pt_regs
|
||||
mov x1, #0
|
||||
mov x2, #0
|
||||
/* load lr, sp, pc, pstate of compat task */
|
||||
ldr x3, [x0, #S_COMPAT_LR]
|
||||
ldr x4, [x0, #S_COMPAT_SP]
|
||||
ldr x5, [x0, #S_PC]
|
||||
ldr x6, [x0, #S_PSTATE]
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/* Obtain the regs of task to sign or authenticate. */
|
||||
.macro ldr_pt_regs
|
||||
/* load x16, x17, lr, sp, pc, pstate of task */
|
||||
ldp x1, x2, [x0, #S_X16]
|
||||
ldr x3, [x0, #S_LR]
|
||||
ldr x4, [x0, #S_SP]
|
||||
ldr x5, [x0, #S_PC]
|
||||
ldr x6, [x0, #S_PSTATE]
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Register sign_thread_context for AArch64.
|
||||
* void sign_thread_context(struct cpu_context *cpu_context)
|
||||
* On entry:
|
||||
* x0: the pointer of cpu_context
|
||||
*/
|
||||
SYM_FUNC_START(sign_thread_context)
|
||||
mrs x9, daif
|
||||
msr daifset, #0x2
|
||||
ldr x1, [x0, #CPU_CONTEXT_PC]
|
||||
ldr x2, [x0, #CPU_CONTEXT_SP]
|
||||
sign_thread_context_common
|
||||
msr daif, x9
|
||||
ret
|
||||
SYM_FUNC_END(sign_thread_context)
|
||||
|
||||
/*
|
||||
* Register auth_thread_context for AArch64.
|
||||
* void auth_thread_context(struct cpu_context *cpu_context)
|
||||
* On entry:
|
||||
* x0: the pointer of cpu_context
|
||||
*/
|
||||
SYM_FUNC_START(auth_thread_context)
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
mrs x9, daif
|
||||
msr daifset, #0x2
|
||||
ldr x1, [x0, #CPU_CONTEXT_PC]
|
||||
ldr x2, [x0, #CPU_CONTEXT_SP]
|
||||
auth_thread_context_common
|
||||
msr daif, x9
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
SYM_FUNC_END(auth_thread_context)
|
||||
|
||||
/*
|
||||
* Register set_exception_context_register_asm for AArch64.
|
||||
* int set_exception_context_register_asm(struct pt_regs *regs, int offset, u64 val);
|
||||
* On entry:
|
||||
* x0: the regs of task
|
||||
* x1: the offset of member in pt_regs struct
|
||||
* x2: the value need to be update
|
||||
*/
|
||||
SYM_FUNC_START(set_exception_context_register_asm)
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
mov x9, x1
|
||||
mov x10, x2
|
||||
mrs x11, daif
|
||||
msr daifset, #0x2
|
||||
ldr_pt_regs
|
||||
mov x12, x1
|
||||
mov x13, x2
|
||||
auth_exception_context_common x0, x12, x13
|
||||
cmp x9, #S_LR
|
||||
b.eq .Lupdate_lr
|
||||
b.ls .Lchoose_lower
|
||||
cmp x9, #S_PC
|
||||
b.eq .Lupdate_pc
|
||||
b.cc .Lupdate_sp
|
||||
cmp x9, #S_PSTATE
|
||||
b.eq .Lupdate_pstate
|
||||
.Lerror_return:
|
||||
/* invalid value: return -EINVAL */
|
||||
mov x0, #-22
|
||||
b .Lreturn
|
||||
.Lchoose_lower:
|
||||
cmp x9, #S_X16
|
||||
b.eq .Lupdate_x16
|
||||
b.hi .Lupdate_x17
|
||||
b .Lerror_return
|
||||
.Lupdate_pstate:
|
||||
mov x6, x10
|
||||
.Lupdate_done:
|
||||
str x10, [x0, x9]
|
||||
sign_exception_context_common
|
||||
.Lreturn:
|
||||
mov x0, #0
|
||||
msr daif, x11
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
|
||||
.Lupdate_x16:
|
||||
mov x1, x10
|
||||
b .Lupdate_done
|
||||
.Lupdate_x17:
|
||||
mov x2, x10
|
||||
b .Lupdate_done
|
||||
.Lupdate_lr:
|
||||
mov x3, x10
|
||||
b .Lupdate_done
|
||||
.Lupdate_sp:
|
||||
mov x4, x10
|
||||
b .Lupdate_done
|
||||
.Lupdate_pc:
|
||||
mov x5, x10
|
||||
b .Lupdate_done
|
||||
SYM_FUNC_END(set_exception_context_register_asm)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
/*
|
||||
* Register set_compat_exception_context_register_asm for AArch64.
|
||||
* int set_compat_exception_context_register_asm(struct pt_regs *regs, int offset, u64 val);
|
||||
* On entry:
|
||||
* x0: the regs of compat task
|
||||
* x1: the offset of member in pt_regs struct
|
||||
* x2: the value need to be update
|
||||
*/
|
||||
SYM_FUNC_START(set_compat_exception_context_register_asm)
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
mov x9, x1
|
||||
mov x10, x2
|
||||
mrs x11, daif
|
||||
msr daifset, #0x2
|
||||
ldr_compat_pt_regs
|
||||
mov x12, x1
|
||||
mov x13, x2
|
||||
auth_exception_context_common x0, x12, x13
|
||||
cmp x9, #S_COMPAT_LR
|
||||
b.eq .Lupdate_compat_lr
|
||||
b.ls .Lcompat_choose_lower
|
||||
cmp x9, #S_PSTATE
|
||||
b.eq .Lupdate_compat_pstate
|
||||
b.cc .Lupdate_compat_pc
|
||||
.Lcompat_error_return:
|
||||
/* invalid value: return -EINVAL */
|
||||
mov x0, #-22
|
||||
b .Lcompat_return
|
||||
.Lcompat_choose_lower:
|
||||
cmp x9, #S_COMPAT_SP
|
||||
b.eq .Lupdate_compat_sp
|
||||
b .Lcompat_error_return
|
||||
.Lupdate_compat_pstate:
|
||||
mov x6, x10
|
||||
.Lcompat_update_done:
|
||||
str x10, [x0, x9]
|
||||
sign_exception_context_common
|
||||
.Lcompat_return:
|
||||
mov x0, #0
|
||||
msr daif, x11
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
|
||||
.Lupdate_compat_lr:
|
||||
mov x3, x10
|
||||
b .Lcompat_update_done
|
||||
.Lupdate_compat_sp:
|
||||
mov x4, x10
|
||||
b .Lcompat_update_done
|
||||
.Lupdate_compat_pc:
|
||||
mov x5, x10
|
||||
b .Lcompat_update_done
|
||||
SYM_FUNC_END(set_compat_exception_context_register_asm)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Register sign_exception_context_asm for AArch64.
|
||||
* void sign_exception_context_asm(struct pt_regs *regs);
|
||||
* On entry:
|
||||
* x0: the regs of task
|
||||
*/
|
||||
SYM_FUNC_START(sign_exception_context_asm)
|
||||
ldr_pt_regs
|
||||
sign_exception_context_common
|
||||
ret
|
||||
SYM_FUNC_END(sign_exception_context_asm)
|
||||
|
||||
/*
|
||||
* Register auth_exception_context_asm for AArch64.
|
||||
* void auth_exception_context_asm(struct pt_regs *regs);
|
||||
* On entry:
|
||||
* x0: the regs of task
|
||||
*/
|
||||
SYM_FUNC_START(auth_exception_context_asm)
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
ldr_pt_regs
|
||||
auth_exception_context_common
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
SYM_FUNC_END(auth_exception_context_asm)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
/*
|
||||
* Register sign_compat_exception_context_asm for AArch64.
|
||||
* void sign_compat_exception_context_asm(struct pt_regs *regs);
|
||||
* On entry:
|
||||
* x0: the regs of compat task
|
||||
*/
|
||||
SYM_FUNC_START(sign_compat_exception_context_asm)
|
||||
ldr_compat_pt_regs
|
||||
sign_exception_context_common
|
||||
ret
|
||||
SYM_FUNC_END(sign_compat_exception_context_asm)
|
||||
|
||||
/*
|
||||
* Register auth_compat_exception_context_asm for AArch64.
|
||||
* void auth_compat_exception_context_asm(struct pt_regs *regs);
|
||||
* On entry:
|
||||
* x0: the regs of compat task
|
||||
*/
|
||||
SYM_FUNC_START(auth_compat_exception_context_asm)
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
ldr_compat_pt_regs
|
||||
auth_exception_context_common
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
SYM_FUNC_END(auth_compat_exception_context_asm)
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*
|
||||
* Pointer authentication keys initialisation.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
.pushsection ".init.text", "ax"
|
||||
|
||||
.macro ptrauth_key_init type, tmp
|
||||
mrs x25, ap\type\()keylo_el1
|
||||
str x25, [\tmp]
|
||||
mrs x25, ap\type\()keyhi_el1
|
||||
str x25, [\tmp, #8]
|
||||
.endm
|
||||
|
||||
/* init ptrauth key for kernel backward-edge CFI */
|
||||
.macro ptrauth_back_key_init
|
||||
mov x6, x5 /* x5: address of init task */
|
||||
mov x7, #THREAD_KEYS_KERNEL
|
||||
add x6, x6, x7
|
||||
add x6, x6, #PTRAUTH_KERNEL_KEY_APIB
|
||||
ptrauth_key_init ib, x6
|
||||
.endm
|
||||
|
||||
/* init common ptrauth keys for kernel forward-edge CFI, data pointer DFI and data field DFI */
|
||||
.macro ptrauth_common_keys_init
|
||||
adr_l x7, kernel_common_keys
|
||||
mov x6, x7
|
||||
add x6, x6, #PTRAUTH_KERNEL_KEY_APIA
|
||||
ptrauth_key_init ia, x6
|
||||
|
||||
mov x6, x7
|
||||
add x6, x6, #PTRAUTH_KERNEL_KEY_APDA
|
||||
ptrauth_key_init da, x6
|
||||
|
||||
mov x6, x7
|
||||
add x6, x6, #PTRAUTH_KERNEL_KEY_APDB
|
||||
ptrauth_key_init db, x6
|
||||
|
||||
mov x6, x7
|
||||
add x6, x6, #PTRAUTH_KERNEL_KEY_APGA
|
||||
ptrauth_key_init ga, x6
|
||||
|
||||
.endm
|
||||
|
||||
SYM_CODE_START(ptrauth_kernel_keys_init)
|
||||
ptrauth_back_key_init
|
||||
ptrauth_common_keys_init
|
||||
isb
|
||||
ret
|
||||
SYM_CODE_END(ptrauth_kernel_keys_init)
|
||||
@@ -0,0 +1,133 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
/* The members of arrays below are corresponding to the enum defined in pointer_auth_context.h:
|
||||
* enum pac_pt_regs {
|
||||
* REGS_X16 = 0,
|
||||
* REGS_X17,
|
||||
* REGS_LR,
|
||||
* REGS_SP,
|
||||
* REGS_PC,
|
||||
* REGS_PSTATE,
|
||||
* };
|
||||
*
|
||||
* compat_regs_offset_array[]:
|
||||
* S_X14: the offset of compat_lr
|
||||
* S_X13: the offset of compat_sp
|
||||
*/
|
||||
static off_t compat_regs_offset_array[] = {0, 0, S_X14, S_X13, S_PC, S_PSTATE};
|
||||
static off_t regs_offset_array[] = {S_X16, S_X17, S_LR, S_SP, S_PC, S_PSTATE};
|
||||
|
||||
int set_compat_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val)
|
||||
{
|
||||
switch (regs_enum) {
|
||||
case REGS_LR:
|
||||
case REGS_SP:
|
||||
case REGS_PC:
|
||||
case REGS_PSTATE:
|
||||
return set_compat_exception_context_register_asm(regs, compat_regs_offset_array[regs_enum], val);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int set_exception_context_register(void *regs, enum pac_pt_regs regs_enum, u64 val)
|
||||
{
|
||||
if (compat_user_mode((struct pt_regs *)regs)) {
|
||||
return set_compat_exception_context_register(regs, regs_enum, val);
|
||||
} else {
|
||||
switch (regs_enum) {
|
||||
case REGS_X16:
|
||||
case REGS_X17:
|
||||
case REGS_LR:
|
||||
case REGS_SP:
|
||||
case REGS_PC:
|
||||
case REGS_PSTATE:
|
||||
return set_exception_context_register_asm(regs, regs_offset_array[regs_enum], val);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_compat_exception_context_register_index(struct pt_regs *regs, int index, uint64_t val)
|
||||
{
|
||||
/* 14 means the index of compat_lr */
|
||||
if (index == 14) {
|
||||
set_compat_exception_context_register_asm(regs, S_X14, val);
|
||||
/* 13 means the index of compat_sp */
|
||||
} else if (index == 13) {
|
||||
set_compat_exception_context_register_asm(regs, S_X13, val);
|
||||
} else {
|
||||
regs->regs[index] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void set_exception_context_register_index(struct pt_regs *regs, int index, uint64_t val)
|
||||
{
|
||||
off_t offset;
|
||||
|
||||
if (compat_user_mode(regs)) {
|
||||
set_compat_exception_context_register_index(regs, index, val);
|
||||
} else {
|
||||
switch (index) {
|
||||
/* 16 means the index of regs[16] */
|
||||
case 16:
|
||||
/* 17 means the index of regs[17] */
|
||||
case 17:
|
||||
/* 30 means the index of regs[30] */
|
||||
case 30:
|
||||
offset = offsetof(struct pt_regs, regs[index]);
|
||||
set_exception_context_register_asm(regs, offset, val);
|
||||
break;
|
||||
default:
|
||||
regs->regs[index] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sign_compat_exception_context(void *regs)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
local_irq_save(irq_flags);
|
||||
sign_compat_exception_context_asm(regs);
|
||||
local_irq_restore(irq_flags);
|
||||
}
|
||||
|
||||
void auth_compat_exception_context(void *regs)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
local_irq_save(irq_flags);
|
||||
auth_compat_exception_context_asm(regs);
|
||||
local_irq_restore(irq_flags);
|
||||
}
|
||||
|
||||
void sign_exception_context(void *regs)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
local_irq_save(irq_flags);
|
||||
if (compat_user_mode((struct pt_regs *)regs)) {
|
||||
sign_compat_exception_context_asm(regs);
|
||||
} else {
|
||||
sign_exception_context_asm(regs);
|
||||
}
|
||||
local_irq_restore(irq_flags);
|
||||
}
|
||||
|
||||
void auth_exception_context(void *regs)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
local_irq_save(irq_flags);
|
||||
if (compat_user_mode((struct pt_regs *)regs)) {
|
||||
auth_compat_exception_context_asm(regs);
|
||||
} else {
|
||||
auth_exception_context_asm(regs);
|
||||
}
|
||||
local_irq_restore(irq_flags);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*
|
||||
* Pointer authentication keys initialisation.
|
||||
*/
|
||||
|
||||
#include <asm/pointer_auth.h>
|
||||
|
||||
struct ptrauth_keys_kernel_common kernel_common_keys = {{-1, -1}};
|
||||
Reference in New Issue
Block a user