Skip to content

Commit 9ed5be8

Browse files
committed
1
1 parent b3de570 commit 9ed5be8

2 files changed

Lines changed: 436 additions & 0 deletions

File tree

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
From db365d6e6cf0b6c09c25e10427b95bb8cdbec2a5 Mon Sep 17 00:00:00 2001
2+
From: XiaoTong6666 <3278671549@qq.com>
3+
Date: Mon, 22 Jun 2026 18:51:10 +0800
4+
Subject: [PATCH] x86: Add syscall hardening hooks for KernelSU
5+
6+
Change-Id: I3d3fb230e09ac46b42c4e82a4d71767f05310f99
7+
---
8+
arch/x86/entry/common.c | 20 ++++++++++++++++---
9+
arch/x86/entry/syscall_32.c | 8 ++++++++
10+
arch/x86/entry/syscall_x32.c | 6 ++++++
11+
arch/x86/include/asm/cpufeatures.h | 1 +
12+
arch/x86/include/asm/syscall.h | 10 ++++++++++
13+
arch/x86/kernel/cpu/common.c | 31 ++++++++++++++++++++++++++++++
14+
drivers/base/cpu.c | 9 +++++++++
15+
include/linux/cpu.h | 3 +++
16+
8 files changed, 85 insertions(+), 3 deletions(-)
17+
18+
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
19+
index 7b9321c48a90..04287cbdbf6f 100644
20+
--- a/arch/x86/entry/common.c
21+
+++ b/arch/x86/entry/common.c
22+
@@ -44,7 +44,11 @@ static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr)
23+
24+
if (likely(unr < NR_syscalls)) {
25+
unr = array_index_nospec(unr, NR_syscalls);
26+
- regs->ax = x64_sys_call(regs, unr);
27+
+ if (likely(cpu_feature_enabled(X86_FEATURE_INDIRECT_SAFE) &&
28+
+ x86_syscall_hardening_enabled))
29+
+ regs->ax = sys_call_table[unr](regs);
30+
+ else
31+
+ regs->ax = x64_sys_call(regs, unr);
32+
return true;
33+
}
34+
return false;
35+
@@ -61,7 +65,11 @@ static __always_inline bool do_syscall_x32(struct pt_regs *regs, int nr)
36+
37+
if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) {
38+
xnr = array_index_nospec(xnr, X32_NR_syscalls);
39+
- regs->ax = x32_sys_call(regs, xnr);
40+
+ if (likely(cpu_feature_enabled(X86_FEATURE_INDIRECT_SAFE) &&
41+
+ x86_syscall_hardening_enabled))
42+
+ regs->ax = x32_sys_call_table[xnr](regs);
43+
+ else
44+
+ regs->ax = x32_sys_call(regs, xnr);
45+
return true;
46+
}
47+
return false;
48+
@@ -157,7 +165,13 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr)
49+
50+
if (likely(unr < IA32_NR_syscalls)) {
51+
unr = array_index_nospec(unr, IA32_NR_syscalls);
52+
- regs->ax = ia32_sys_call(regs, unr);
53+
+ #ifdef CONFIG_X86_64
54+
+ if (likely(cpu_feature_enabled(X86_FEATURE_INDIRECT_SAFE) &&
55+
+ x86_syscall_hardening_enabled))
56+
+ regs->ax = ia32_sys_call_table[unr](regs);
57+
+ else
58+
+ #endif
59+
+ regs->ax = ia32_sys_call(regs, unr);
60+
} else if (nr != -1) {
61+
regs->ax = __ia32_sys_ni_syscall(regs);
62+
}
63+
diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c
64+
index 8cc9950d7104..e11c7f12d265 100644
65+
--- a/arch/x86/entry/syscall_32.c
66+
+++ b/arch/x86/entry/syscall_32.c
67+
@@ -34,6 +34,14 @@ const sys_call_ptr_t sys_call_table[] = {
68+
#undef __SYSCALL
69+
#endif
70+
71+
+#ifdef CONFIG_IA32_EMULATION
72+
+#define __SYSCALL(nr, sym) __ia32_##sym,
73+
+const sys_call_ptr_t ia32_sys_call_table[] = {
74+
+#include <asm/syscalls_32.h>
75+
+};
76+
+#undef __SYSCALL
77+
+#endif
78+
+
79+
#define __SYSCALL(nr, sym) case nr: return __ia32_##sym(regs);
80+
long ia32_sys_call(const struct pt_regs *regs, unsigned int nr)
81+
{
82+
diff --git a/arch/x86/entry/syscall_x32.c b/arch/x86/entry/syscall_x32.c
83+
index fb77908f44f3..1822215cc215 100644
84+
--- a/arch/x86/entry/syscall_x32.c
85+
+++ b/arch/x86/entry/syscall_x32.c
86+
@@ -15,6 +15,12 @@
87+
#undef __SYSCALL_NORETURN
88+
#define __SYSCALL_NORETURN __SYSCALL
89+
90+
+#define __SYSCALL(nr, sym) __x64_##sym,
91+
+const sys_call_ptr_t x32_sys_call_table[] = {
92+
+#include <asm/syscalls_x32.h>
93+
+};
94+
+#undef __SYSCALL
95+
+
96+
#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
97+
long x32_sys_call(const struct pt_regs *regs, unsigned int nr)
98+
{
99+
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
100+
index 16a8c1f3ff65..07e777057538 100644
101+
--- a/arch/x86/include/asm/cpufeatures.h
102+
+++ b/arch/x86/include/asm/cpufeatures.h
103+
@@ -488,6 +488,7 @@
104+
#define X86_FEATURE_TSA_L1_NO (21*32+12) /* AMD CPU not vulnerable to TSA-L1 */
105+
#define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* Clear CPU buffers using VERW before VMRUN */
106+
#define X86_FEATURE_IBPB_EXIT_TO_USER (21*32+14) /* Use IBPB on exit-to-userspace, see VMSCAPE bug */
107+
+#define X86_FEATURE_INDIRECT_SAFE (21*32+15) /* Indirect syscall dispatch is hardened */
108+
109+
/*
110+
* BUG word(s)
111+
diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
112+
index 7c488ff0c764..8cfd8dd29b7f 100644
113+
--- a/arch/x86/include/asm/syscall.h
114+
+++ b/arch/x86/include/asm/syscall.h
115+
@@ -20,6 +20,16 @@
116+
typedef long (*sys_call_ptr_t)(const struct pt_regs *);
117+
extern const sys_call_ptr_t sys_call_table[];
118+
119+
+#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
120+
+extern const sys_call_ptr_t ia32_sys_call_table[];
121+
+#endif
122+
+
123+
+extern const sys_call_ptr_t x32_sys_call_table[];
124+
+
125+
+#ifdef CONFIG_X86_64
126+
+extern bool x86_syscall_hardening_enabled;
127+
+#endif
128+
+
129+
/*
130+
* These may not exist, but still put the prototypes in so we
131+
* can use IS_ENABLED().
132+
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
133+
index b54717e6fc60..cdaaccbbb553 100644
134+
--- a/arch/x86/kernel/cpu/common.c
135+
+++ b/arch/x86/kernel/cpu/common.c
136+
@@ -280,6 +280,36 @@ static int __init x86_noinvpcid_setup(char *s)
137+
}
138+
early_param("noinvpcid", x86_noinvpcid_setup);
139+
140+
+#ifdef CONFIG_X86_64
141+
+bool x86_syscall_hardening_enabled __ro_after_init = true;
142+
+
143+
+static int __init x86_syscall_hardening_setup(char *str)
144+
+{
145+
+ if (!str)
146+
+ return -EINVAL;
147+
+
148+
+ if (!strcmp(str, "off")) {
149+
+ x86_syscall_hardening_enabled = false;
150+
+ pr_info("syscall_hardening: indirect syscall dispatch disabled\n");
151+
+ return 0;
152+
+ }
153+
+
154+
+ if (!strcmp(str, "on"))
155+
+ return 0;
156+
+
157+
+ return -EINVAL;
158+
+}
159+
+early_param("syscall_hardening", x86_syscall_hardening_setup);
160+
+
161+
+ssize_t cpu_show_syscall_hardening(struct device *dev,
162+
+ struct device_attribute *attr,
163+
+ char *buf)
164+
+{
165+
+ return sysfs_emit(buf, "%s\n",
166+
+ x86_syscall_hardening_enabled ? "on" : "off");
167+
+}
168+
+#endif
169+
+
170+
#ifdef CONFIG_X86_32
171+
static int cachesize_override = -1;
172+
static int disable_x86_serial_nr = 1;
173+
@@ -2444,6 +2474,7 @@ void __init arch_cpu_finalize_init(void)
174+
print_cpu_info(&boot_cpu_data);
175+
}
176+
177+
+ setup_force_cpu_cap(X86_FEATURE_INDIRECT_SAFE);
178+
cpu_select_mitigations();
179+
180+
arch_smt_update();
181+
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
182+
index ee52b106a955..8c9bb7e43f68 100644
183+
--- a/drivers/base/cpu.c
184+
+++ b/drivers/base/cpu.c
185+
@@ -492,6 +492,7 @@ EXPORT_SYMBOL_GPL(cpu_device_create);
186+
#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
187+
static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
188+
#endif
189+
+static DEVICE_ATTR(syscall_hardening, 0444, cpu_show_syscall_hardening, NULL);
190+
191+
static struct attribute *cpu_root_attrs[] = {
192+
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
193+
@@ -514,6 +515,7 @@ static struct attribute *cpu_root_attrs[] = {
194+
#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
195+
&dev_attr_modalias.attr,
196+
#endif
197+
+ &dev_attr_syscall_hardening.attr,
198+
NULL
199+
};
200+
201+
@@ -603,6 +605,13 @@ CPU_SHOW_VULN_FALLBACK(indirect_target_selection);
202+
CPU_SHOW_VULN_FALLBACK(tsa);
203+
CPU_SHOW_VULN_FALLBACK(vmscape);
204+
205+
+ssize_t __weak cpu_show_syscall_hardening(struct device *dev,
206+
+ struct device_attribute *attr,
207+
+ char *buf)
208+
+{
209+
+ return sysfs_emit(buf, "unknown\n");
210+
+}
211+
+
212+
static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
213+
static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
214+
static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
215+
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
216+
index e682c75a3bb0..34379c9f24fe 100644
217+
--- a/include/linux/cpu.h
218+
+++ b/include/linux/cpu.h
219+
@@ -77,6 +77,9 @@ extern ssize_t cpu_show_gds(struct device *dev,
220+
struct device_attribute *attr, char *buf);
221+
extern ssize_t cpu_show_reg_file_data_sampling(struct device *dev,
222+
struct device_attribute *attr, char *buf);
223+
+extern ssize_t cpu_show_syscall_hardening(struct device *dev,
224+
+ struct device_attribute *attr,
225+
+ char *buf);
226+
extern ssize_t cpu_show_indirect_target_selection(struct device *dev,
227+
struct device_attribute *attr, char *buf);
228+
extern ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *buf);
229+
--
230+
2.53.0

0 commit comments

Comments
 (0)