diff options
| -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 |
