diff options
Diffstat (limited to 'kernel/seccomp.c')
| -rw-r--r-- | kernel/seccomp.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index ee376beedaf9..5af44b593770 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
| @@ -396,25 +396,29 @@ int __secure_computing(int this_syscall) | |||
| 396 | #ifdef CONFIG_SECCOMP_FILTER | 396 | #ifdef CONFIG_SECCOMP_FILTER |
| 397 | case SECCOMP_MODE_FILTER: { | 397 | case SECCOMP_MODE_FILTER: { |
| 398 | int data; | 398 | int data; |
| 399 | struct pt_regs *regs = task_pt_regs(current); | ||
| 399 | ret = seccomp_run_filters(this_syscall); | 400 | ret = seccomp_run_filters(this_syscall); |
| 400 | data = ret & SECCOMP_RET_DATA; | 401 | data = ret & SECCOMP_RET_DATA; |
| 401 | ret &= SECCOMP_RET_ACTION; | 402 | ret &= SECCOMP_RET_ACTION; |
| 402 | switch (ret) { | 403 | switch (ret) { |
| 403 | case SECCOMP_RET_ERRNO: | 404 | case SECCOMP_RET_ERRNO: |
| 404 | /* Set the low-order 16-bits as a errno. */ | 405 | /* Set the low-order 16-bits as a errno. */ |
| 405 | syscall_set_return_value(current, task_pt_regs(current), | 406 | syscall_set_return_value(current, regs, |
| 406 | -data, 0); | 407 | -data, 0); |
| 407 | goto skip; | 408 | goto skip; |
| 408 | case SECCOMP_RET_TRAP: | 409 | case SECCOMP_RET_TRAP: |
| 409 | /* Show the handler the original registers. */ | 410 | /* Show the handler the original registers. */ |
| 410 | syscall_rollback(current, task_pt_regs(current)); | 411 | syscall_rollback(current, regs); |
| 411 | /* Let the filter pass back 16 bits of data. */ | 412 | /* Let the filter pass back 16 bits of data. */ |
| 412 | seccomp_send_sigsys(this_syscall, data); | 413 | seccomp_send_sigsys(this_syscall, data); |
| 413 | goto skip; | 414 | goto skip; |
| 414 | case SECCOMP_RET_TRACE: | 415 | case SECCOMP_RET_TRACE: |
| 415 | /* Skip these calls if there is no tracer. */ | 416 | /* Skip these calls if there is no tracer. */ |
| 416 | if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) | 417 | if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) { |
| 418 | syscall_set_return_value(current, regs, | ||
| 419 | -ENOSYS, 0); | ||
| 417 | goto skip; | 420 | goto skip; |
| 421 | } | ||
| 418 | /* Allow the BPF to provide the event message */ | 422 | /* Allow the BPF to provide the event message */ |
| 419 | ptrace_event(PTRACE_EVENT_SECCOMP, data); | 423 | ptrace_event(PTRACE_EVENT_SECCOMP, data); |
| 420 | /* | 424 | /* |
| @@ -425,6 +429,9 @@ int __secure_computing(int this_syscall) | |||
| 425 | */ | 429 | */ |
| 426 | if (fatal_signal_pending(current)) | 430 | if (fatal_signal_pending(current)) |
| 427 | break; | 431 | break; |
| 432 | if (syscall_get_nr(current, regs) < 0) | ||
| 433 | goto skip; /* Explicit request to skip. */ | ||
| 434 | |||
| 428 | return 0; | 435 | return 0; |
| 429 | case SECCOMP_RET_ALLOW: | 436 | case SECCOMP_RET_ALLOW: |
| 430 | return 0; | 437 | return 0; |
