diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/ia32/ia32entry.S | 91 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 1 |
2 files changed, 88 insertions, 4 deletions
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 23d146ce676b..021d71bc69b5 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -15,6 +15,16 @@ | |||
15 | #include <asm/irqflags.h> | 15 | #include <asm/irqflags.h> |
16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
17 | 17 | ||
18 | /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ | ||
19 | #include <linux/elf-em.h> | ||
20 | #define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE) | ||
21 | #define __AUDIT_ARCH_LE 0x40000000 | ||
22 | |||
23 | #ifndef CONFIG_AUDITSYSCALL | ||
24 | #define sysexit_audit int_ret_from_sys_call | ||
25 | #define sysretl_audit int_ret_from_sys_call | ||
26 | #endif | ||
27 | |||
18 | #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) | 28 | #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) |
19 | 29 | ||
20 | .macro IA32_ARG_FIXUP noebp=0 | 30 | .macro IA32_ARG_FIXUP noebp=0 |
@@ -148,13 +158,15 @@ ENTRY(ia32_sysenter_target) | |||
148 | ja ia32_badsys | 158 | ja ia32_badsys |
149 | sysenter_do_call: | 159 | sysenter_do_call: |
150 | IA32_ARG_FIXUP 1 | 160 | IA32_ARG_FIXUP 1 |
161 | sysenter_dispatch: | ||
151 | call *ia32_sys_call_table(,%rax,8) | 162 | call *ia32_sys_call_table(,%rax,8) |
152 | movq %rax,RAX-ARGOFFSET(%rsp) | 163 | movq %rax,RAX-ARGOFFSET(%rsp) |
153 | GET_THREAD_INFO(%r10) | 164 | GET_THREAD_INFO(%r10) |
154 | DISABLE_INTERRUPTS(CLBR_NONE) | 165 | DISABLE_INTERRUPTS(CLBR_NONE) |
155 | TRACE_IRQS_OFF | 166 | TRACE_IRQS_OFF |
156 | testl $_TIF_ALLWORK_MASK,TI_flags(%r10) | 167 | testl $_TIF_ALLWORK_MASK,TI_flags(%r10) |
157 | jnz int_ret_from_sys_call | 168 | jnz sysexit_audit |
169 | sysexit_from_sys_call: | ||
158 | andl $~TS_COMPAT,TI_status(%r10) | 170 | andl $~TS_COMPAT,TI_status(%r10) |
159 | /* clear IF, that popfq doesn't enable interrupts early */ | 171 | /* clear IF, that popfq doesn't enable interrupts early */ |
160 | andl $~0x200,EFLAGS-R11(%rsp) | 172 | andl $~0x200,EFLAGS-R11(%rsp) |
@@ -170,9 +182,63 @@ sysenter_do_call: | |||
170 | TRACE_IRQS_ON | 182 | TRACE_IRQS_ON |
171 | ENABLE_INTERRUPTS_SYSEXIT32 | 183 | ENABLE_INTERRUPTS_SYSEXIT32 |
172 | 184 | ||
173 | sysenter_tracesys: | 185 | #ifdef CONFIG_AUDITSYSCALL |
186 | .macro auditsys_entry_common | ||
187 | movl %esi,%r9d /* 6th arg: 4th syscall arg */ | ||
188 | movl %edx,%r8d /* 5th arg: 3rd syscall arg */ | ||
189 | /* (already in %ecx) 4th arg: 2nd syscall arg */ | ||
190 | movl %ebx,%edx /* 3rd arg: 1st syscall arg */ | ||
191 | movl %eax,%esi /* 2nd arg: syscall number */ | ||
192 | movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ | ||
193 | call audit_syscall_entry | ||
194 | movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ | ||
195 | cmpl $(IA32_NR_syscalls-1),%eax | ||
196 | ja ia32_badsys | ||
197 | movl %ebx,%edi /* reload 1st syscall arg */ | ||
198 | movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ | ||
199 | movl RDX-ARGOFFSET(%rsp),%edx /* reload 3rd syscall arg */ | ||
200 | movl RSI-ARGOFFSET(%rsp),%ecx /* reload 4th syscall arg */ | ||
201 | movl RDI-ARGOFFSET(%rsp),%r8d /* reload 5th syscall arg */ | ||
202 | .endm | ||
203 | |||
204 | .macro auditsys_exit exit | ||
205 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) | ||
206 | jnz int_ret_from_sys_call | ||
207 | TRACE_IRQS_ON | ||
208 | sti | ||
209 | movl %eax,%esi /* second arg, syscall return value */ | ||
210 | cmpl $0,%eax /* is it < 0? */ | ||
211 | setl %al /* 1 if so, 0 if not */ | ||
212 | movzbl %al,%edi /* zero-extend that into %edi */ | ||
213 | inc %edi /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */ | ||
214 | call audit_syscall_exit | ||
215 | GET_THREAD_INFO(%r10) | ||
216 | movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall return value */ | ||
217 | movl RBP-ARGOFFSET(%rsp),%ebp /* reload user register value */ | ||
218 | movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi | ||
219 | cli | ||
220 | TRACE_IRQS_OFF | ||
221 | testl %edi,TI_flags(%r10) | ||
222 | jnz int_with_check | ||
223 | jmp \exit | ||
224 | .endm | ||
225 | |||
226 | sysenter_auditsys: | ||
174 | CFI_RESTORE_STATE | 227 | CFI_RESTORE_STATE |
228 | auditsys_entry_common | ||
229 | movl %ebp,%r9d /* reload 6th syscall arg */ | ||
230 | jmp sysenter_dispatch | ||
231 | |||
232 | sysexit_audit: | ||
233 | auditsys_exit sysexit_from_sys_call | ||
234 | #endif | ||
235 | |||
236 | sysenter_tracesys: | ||
175 | xchgl %r9d,%ebp | 237 | xchgl %r9d,%ebp |
238 | #ifdef CONFIG_AUDITSYSCALL | ||
239 | testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) | ||
240 | jz sysenter_auditsys | ||
241 | #endif | ||
176 | SAVE_REST | 242 | SAVE_REST |
177 | CLEAR_RREGS | 243 | CLEAR_RREGS |
178 | movq %r9,R9(%rsp) | 244 | movq %r9,R9(%rsp) |
@@ -252,13 +318,15 @@ cstar_do_call: | |||
252 | cmpl $IA32_NR_syscalls-1,%eax | 318 | cmpl $IA32_NR_syscalls-1,%eax |
253 | ja ia32_badsys | 319 | ja ia32_badsys |
254 | IA32_ARG_FIXUP 1 | 320 | IA32_ARG_FIXUP 1 |
321 | cstar_dispatch: | ||
255 | call *ia32_sys_call_table(,%rax,8) | 322 | call *ia32_sys_call_table(,%rax,8) |
256 | movq %rax,RAX-ARGOFFSET(%rsp) | 323 | movq %rax,RAX-ARGOFFSET(%rsp) |
257 | GET_THREAD_INFO(%r10) | 324 | GET_THREAD_INFO(%r10) |
258 | DISABLE_INTERRUPTS(CLBR_NONE) | 325 | DISABLE_INTERRUPTS(CLBR_NONE) |
259 | TRACE_IRQS_OFF | 326 | TRACE_IRQS_OFF |
260 | testl $_TIF_ALLWORK_MASK,TI_flags(%r10) | 327 | testl $_TIF_ALLWORK_MASK,TI_flags(%r10) |
261 | jnz int_ret_from_sys_call | 328 | jnz sysretl_audit |
329 | sysretl_from_sys_call: | ||
262 | andl $~TS_COMPAT,TI_status(%r10) | 330 | andl $~TS_COMPAT,TI_status(%r10) |
263 | RESTORE_ARGS 1,-ARG_SKIP,1,1,1 | 331 | RESTORE_ARGS 1,-ARG_SKIP,1,1,1 |
264 | movl RIP-ARGOFFSET(%rsp),%ecx | 332 | movl RIP-ARGOFFSET(%rsp),%ecx |
@@ -270,8 +338,23 @@ cstar_do_call: | |||
270 | CFI_RESTORE rsp | 338 | CFI_RESTORE rsp |
271 | USERGS_SYSRET32 | 339 | USERGS_SYSRET32 |
272 | 340 | ||
273 | cstar_tracesys: | 341 | #ifdef CONFIG_AUDITSYSCALL |
342 | cstar_auditsys: | ||
274 | CFI_RESTORE_STATE | 343 | CFI_RESTORE_STATE |
344 | movl %r9d,R9-ARGOFFSET(%rsp) /* register to be clobbered by call */ | ||
345 | auditsys_entry_common | ||
346 | movl R9-ARGOFFSET(%rsp),%r9d /* reload 6th syscall arg */ | ||
347 | jmp cstar_dispatch | ||
348 | |||
349 | sysretl_audit: | ||
350 | auditsys_exit sysretl_from_sys_call | ||
351 | #endif | ||
352 | |||
353 | cstar_tracesys: | ||
354 | #ifdef CONFIG_AUDITSYSCALL | ||
355 | testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) | ||
356 | jz cstar_auditsys | ||
357 | #endif | ||
275 | xchgl %r9d,%ebp | 358 | xchgl %r9d,%ebp |
276 | SAVE_REST | 359 | SAVE_REST |
277 | CLEAR_RREGS | 360 | CLEAR_RREGS |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index db7d34a89d2e..89434d439605 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -492,6 +492,7 @@ tracesys: | |||
492 | * Has correct top of stack, but partial stack frame. | 492 | * Has correct top of stack, but partial stack frame. |
493 | */ | 493 | */ |
494 | .globl int_ret_from_sys_call | 494 | .globl int_ret_from_sys_call |
495 | .globl int_with_check | ||
495 | int_ret_from_sys_call: | 496 | int_ret_from_sys_call: |
496 | DISABLE_INTERRUPTS(CLBR_NONE) | 497 | DISABLE_INTERRUPTS(CLBR_NONE) |
497 | TRACE_IRQS_OFF | 498 | TRACE_IRQS_OFF |