Skip to content

Commit cd4771f

Browse files
committed
Merge branch 'x86-entry-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 syscall entry updates from Ingo Molnar: "These changes relate to the preparatory cleanup of syscall function type signatures - to fix indirect call mismatches with Control-Flow Integrity (CFI) checking. No change in behavior intended" * 'x86-entry-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/mm: Use the correct function type for native_set_fixmap() syscalls/x86: Fix function types in COND_SYSCALL syscalls/x86: Use the correct function type for sys_ni_syscall syscalls/x86: Use COMPAT_SYSCALL_DEFINE0 for IA32 (rt_)sigreturn syscalls/x86: Wire up COMPAT_SYSCALL_DEFINE0 syscalls/x86: Use the correct function type in SYSCALL_DEFINE0
2 parents a25bbc2 + f53e2cd commit cd4771f

File tree

7 files changed

+81
-36
lines changed

7 files changed

+81
-36
lines changed

arch/x86/entry/syscall_32.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@
1010
#ifdef CONFIG_IA32_EMULATION
1111
/* On X86_64, we use struct pt_regs * to pass parameters to syscalls */
1212
#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *);
13-
14-
/* this is a lie, but it does not hurt as sys_ni_syscall just returns -EINVAL */
15-
extern asmlinkage long sys_ni_syscall(const struct pt_regs *);
16-
13+
#define __sys_ni_syscall __ia32_sys_ni_syscall
1714
#else /* CONFIG_IA32_EMULATION */
1815
#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
1916
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
17+
#define __sys_ni_syscall sys_ni_syscall
2018
#endif /* CONFIG_IA32_EMULATION */
2119

2220
#include <asm/syscalls_32.h>
@@ -29,6 +27,6 @@ __visible const sys_call_ptr_t ia32_sys_call_table[__NR_syscall_compat_max+1] =
2927
* Smells like a compiler bug -- it doesn't work
3028
* when the & below is removed.
3129
*/
32-
[0 ... __NR_syscall_compat_max] = &sys_ni_syscall,
30+
[0 ... __NR_syscall_compat_max] = &__sys_ni_syscall,
3331
#include <asm/syscalls_32.h>
3432
};

arch/x86/entry/syscall_64.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44
#include <linux/linkage.h>
55
#include <linux/sys.h>
66
#include <linux/cache.h>
7+
#include <linux/syscalls.h>
78
#include <asm/asm-offsets.h>
89
#include <asm/syscall.h>
910

10-
/* this is a lie, but it does not hurt as sys_ni_syscall just returns -EINVAL */
11-
extern asmlinkage long sys_ni_syscall(const struct pt_regs *);
11+
extern asmlinkage long sys_ni_syscall(void);
12+
13+
SYSCALL_DEFINE0(ni_syscall)
14+
{
15+
return sys_ni_syscall();
16+
}
17+
1218
#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *);
1319
#define __SYSCALL_X32(nr, sym, qual) __SYSCALL_64(nr, sym, qual)
1420
#include <asm/syscalls_64.h>
@@ -23,7 +29,7 @@ asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
2329
* Smells like a compiler bug -- it doesn't work
2430
* when the & below is removed.
2531
*/
26-
[0 ... __NR_syscall_max] = &sys_ni_syscall,
32+
[0 ... __NR_syscall_max] = &__x64_sys_ni_syscall,
2733
#include <asm/syscalls_64.h>
2834
};
2935

@@ -40,7 +46,7 @@ asmlinkage const sys_call_ptr_t x32_sys_call_table[__NR_syscall_x32_max+1] = {
4046
* Smells like a compiler bug -- it doesn't work
4147
* when the & below is removed.
4248
*/
43-
[0 ... __NR_syscall_x32_max] = &sys_ni_syscall,
49+
[0 ... __NR_syscall_x32_max] = &__x64_sys_ni_syscall,
4450
#include <asm/syscalls_64.h>
4551
};
4652

arch/x86/entry/syscalls/syscall_32.tbl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,13 @@
124124
110 i386 iopl sys_iopl __ia32_sys_iopl
125125
111 i386 vhangup sys_vhangup __ia32_sys_vhangup
126126
112 i386 idle
127-
113 i386 vm86old sys_vm86old sys_ni_syscall
127+
113 i386 vm86old sys_vm86old __ia32_sys_ni_syscall
128128
114 i386 wait4 sys_wait4 __ia32_compat_sys_wait4
129129
115 i386 swapoff sys_swapoff __ia32_sys_swapoff
130130
116 i386 sysinfo sys_sysinfo __ia32_compat_sys_sysinfo
131131
117 i386 ipc sys_ipc __ia32_compat_sys_ipc
132132
118 i386 fsync sys_fsync __ia32_sys_fsync
133-
119 i386 sigreturn sys_sigreturn sys32_sigreturn
133+
119 i386 sigreturn sys_sigreturn __ia32_compat_sys_sigreturn
134134
120 i386 clone sys_clone __ia32_compat_sys_x86_clone
135135
121 i386 setdomainname sys_setdomainname __ia32_sys_setdomainname
136136
122 i386 uname sys_newuname __ia32_sys_newuname
@@ -177,14 +177,14 @@
177177
163 i386 mremap sys_mremap __ia32_sys_mremap
178178
164 i386 setresuid sys_setresuid16 __ia32_sys_setresuid16
179179
165 i386 getresuid sys_getresuid16 __ia32_sys_getresuid16
180-
166 i386 vm86 sys_vm86 sys_ni_syscall
180+
166 i386 vm86 sys_vm86 __ia32_sys_ni_syscall
181181
167 i386 query_module
182182
168 i386 poll sys_poll __ia32_sys_poll
183183
169 i386 nfsservctl
184184
170 i386 setresgid sys_setresgid16 __ia32_sys_setresgid16
185185
171 i386 getresgid sys_getresgid16 __ia32_sys_getresgid16
186186
172 i386 prctl sys_prctl __ia32_sys_prctl
187-
173 i386 rt_sigreturn sys_rt_sigreturn sys32_rt_sigreturn
187+
173 i386 rt_sigreturn sys_rt_sigreturn __ia32_compat_sys_rt_sigreturn
188188
174 i386 rt_sigaction sys_rt_sigaction __ia32_compat_sys_rt_sigaction
189189
175 i386 rt_sigprocmask sys_rt_sigprocmask __ia32_compat_sys_rt_sigprocmask
190190
176 i386 rt_sigpending sys_rt_sigpending __ia32_compat_sys_rt_sigpending

arch/x86/ia32/ia32_signal.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/personality.h>
2222
#include <linux/compat.h>
2323
#include <linux/binfmts.h>
24+
#include <linux/syscalls.h>
2425
#include <asm/ucontext.h>
2526
#include <linux/uaccess.h>
2627
#include <asm/fpu/internal.h>
@@ -118,7 +119,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
118119
return err;
119120
}
120121

121-
asmlinkage long sys32_sigreturn(void)
122+
COMPAT_SYSCALL_DEFINE0(sigreturn)
122123
{
123124
struct pt_regs *regs = current_pt_regs();
124125
struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
@@ -144,7 +145,7 @@ asmlinkage long sys32_sigreturn(void)
144145
return 0;
145146
}
146147

147-
asmlinkage long sys32_rt_sigreturn(void)
148+
COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
148149
{
149150
struct pt_regs *regs = current_pt_regs();
150151
struct rt_sigframe_ia32 __user *frame;

arch/x86/include/asm/fixmap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ extern pte_t *kmap_pte;
156156
extern pte_t *pkmap_page_table;
157157

158158
void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
159-
void native_set_fixmap(enum fixed_addresses idx,
159+
void native_set_fixmap(unsigned /* enum fixed_addresses */ idx,
160160
phys_addr_t phys, pgprot_t flags);
161161

162162
#ifndef CONFIG_PARAVIRT_XXL

arch/x86/include/asm/syscall_wrapper.h

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef _ASM_X86_SYSCALL_WRAPPER_H
77
#define _ASM_X86_SYSCALL_WRAPPER_H
88

9+
struct pt_regs;
10+
911
/* Mapping of registers to parameters for syscalls on x86-64 and x32 */
1012
#define SC_X86_64_REGS_TO_ARGS(x, ...) \
1113
__MAP(x,__SC_ARGS \
@@ -28,13 +30,21 @@
2830
* kernel/sys_ni.c and SYS_NI in kernel/time/posix-stubs.c to cover this
2931
* case as well.
3032
*/
33+
#define __IA32_COMPAT_SYS_STUB0(x, name) \
34+
asmlinkage long __ia32_compat_sys_##name(const struct pt_regs *regs);\
35+
ALLOW_ERROR_INJECTION(__ia32_compat_sys_##name, ERRNO); \
36+
asmlinkage long __ia32_compat_sys_##name(const struct pt_regs *regs)\
37+
{ \
38+
return __se_compat_sys_##name(); \
39+
}
40+
3141
#define __IA32_COMPAT_SYS_STUBx(x, name, ...) \
3242
asmlinkage long __ia32_compat_sys##name(const struct pt_regs *regs);\
3343
ALLOW_ERROR_INJECTION(__ia32_compat_sys##name, ERRNO); \
3444
asmlinkage long __ia32_compat_sys##name(const struct pt_regs *regs)\
3545
{ \
3646
return __se_compat_sys##name(SC_IA32_REGS_TO_ARGS(x,__VA_ARGS__));\
37-
} \
47+
}
3848

3949
#define __IA32_SYS_STUBx(x, name, ...) \
4050
asmlinkage long __ia32_sys##name(const struct pt_regs *regs); \
@@ -48,16 +58,23 @@
4858
* To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias
4959
* named __ia32_sys_*()
5060
*/
51-
#define SYSCALL_DEFINE0(sname) \
52-
SYSCALL_METADATA(_##sname, 0); \
53-
asmlinkage long __x64_sys_##sname(void); \
54-
ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \
55-
SYSCALL_ALIAS(__ia32_sys_##sname, __x64_sys_##sname); \
56-
asmlinkage long __x64_sys_##sname(void)
5761

58-
#define COND_SYSCALL(name) \
59-
cond_syscall(__x64_sys_##name); \
60-
cond_syscall(__ia32_sys_##name)
62+
#define SYSCALL_DEFINE0(sname) \
63+
SYSCALL_METADATA(_##sname, 0); \
64+
asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\
65+
ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \
66+
SYSCALL_ALIAS(__ia32_sys_##sname, __x64_sys_##sname); \
67+
asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused)
68+
69+
#define COND_SYSCALL(name) \
70+
asmlinkage __weak long __x64_sys_##name(const struct pt_regs *__unused) \
71+
{ \
72+
return sys_ni_syscall(); \
73+
} \
74+
asmlinkage __weak long __ia32_sys_##name(const struct pt_regs *__unused)\
75+
{ \
76+
return sys_ni_syscall(); \
77+
}
6178

6279
#define SYS_NI(name) \
6380
SYSCALL_ALIAS(__x64_sys_##name, sys_ni_posix_timers); \
@@ -75,15 +92,24 @@
7592
* of the x86-64-style parameter ordering of x32 syscalls. The syscalls common
7693
* with x86_64 obviously do not need such care.
7794
*/
95+
#define __X32_COMPAT_SYS_STUB0(x, name, ...) \
96+
asmlinkage long __x32_compat_sys_##name(const struct pt_regs *regs);\
97+
ALLOW_ERROR_INJECTION(__x32_compat_sys_##name, ERRNO); \
98+
asmlinkage long __x32_compat_sys_##name(const struct pt_regs *regs)\
99+
{ \
100+
return __se_compat_sys_##name();\
101+
}
102+
78103
#define __X32_COMPAT_SYS_STUBx(x, name, ...) \
79104
asmlinkage long __x32_compat_sys##name(const struct pt_regs *regs);\
80105
ALLOW_ERROR_INJECTION(__x32_compat_sys##name, ERRNO); \
81106
asmlinkage long __x32_compat_sys##name(const struct pt_regs *regs)\
82107
{ \
83108
return __se_compat_sys##name(SC_X86_64_REGS_TO_ARGS(x,__VA_ARGS__));\
84-
} \
109+
}
85110

86111
#else /* CONFIG_X86_X32 */
112+
#define __X32_COMPAT_SYS_STUB0(x, name)
87113
#define __X32_COMPAT_SYS_STUBx(x, name, ...)
88114
#endif /* CONFIG_X86_X32 */
89115

@@ -94,6 +120,17 @@
94120
* mapping of registers to parameters, we need to generate stubs for each
95121
* of them.
96122
*/
123+
#define COMPAT_SYSCALL_DEFINE0(name) \
124+
static long __se_compat_sys_##name(void); \
125+
static inline long __do_compat_sys_##name(void); \
126+
__IA32_COMPAT_SYS_STUB0(x, name) \
127+
__X32_COMPAT_SYS_STUB0(x, name) \
128+
static long __se_compat_sys_##name(void) \
129+
{ \
130+
return __do_compat_sys_##name(); \
131+
} \
132+
static inline long __do_compat_sys_##name(void)
133+
97134
#define COMPAT_SYSCALL_DEFINEx(x, name, ...) \
98135
static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
99136
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
@@ -181,15 +218,19 @@
181218
* macros to work correctly.
182219
*/
183220
#ifndef SYSCALL_DEFINE0
184-
#define SYSCALL_DEFINE0(sname) \
185-
SYSCALL_METADATA(_##sname, 0); \
186-
asmlinkage long __x64_sys_##sname(void); \
187-
ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \
188-
asmlinkage long __x64_sys_##sname(void)
221+
#define SYSCALL_DEFINE0(sname) \
222+
SYSCALL_METADATA(_##sname, 0); \
223+
asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\
224+
ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \
225+
asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused)
189226
#endif
190227

191228
#ifndef COND_SYSCALL
192-
#define COND_SYSCALL(name) cond_syscall(__x64_sys_##name)
229+
#define COND_SYSCALL(name) \
230+
asmlinkage __weak long __x64_sys_##name(const struct pt_regs *__unused) \
231+
{ \
232+
return sys_ni_syscall(); \
233+
}
193234
#endif
194235

195236
#ifndef SYS_NI
@@ -201,7 +242,6 @@
201242
* For VSYSCALLS, we need to declare these three syscalls with the new
202243
* pt_regs-based calling convention for in-kernel use.
203244
*/
204-
struct pt_regs;
205245
asmlinkage long __x64_sys_getcpu(const struct pt_regs *regs);
206246
asmlinkage long __x64_sys_gettimeofday(const struct pt_regs *regs);
207247
asmlinkage long __x64_sys_time(const struct pt_regs *regs);

arch/x86/mm/pgtable.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,8 @@ void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
643643
fixmaps_set++;
644644
}
645645

646-
void native_set_fixmap(enum fixed_addresses idx, phys_addr_t phys,
647-
pgprot_t flags)
646+
void native_set_fixmap(unsigned /* enum fixed_addresses */ idx,
647+
phys_addr_t phys, pgprot_t flags)
648648
{
649649
/* Sanitize 'prot' against any unsupported bits: */
650650
pgprot_val(flags) &= __default_kernel_pte_mask;

0 commit comments

Comments
 (0)