diff options
| author | Kees Cook <keescook@chromium.org> | 2014-06-25 18:55:25 -0400 |
|---|---|---|
| committer | Kees Cook <keescook@chromium.org> | 2014-07-18 15:13:37 -0400 |
| commit | 3b23dd12846215eff4afb073366b80c0c4d7543e (patch) | |
| tree | a1c32b31840891799098d2842fefd2d5b06d2fc5 | |
| parent | 1f41b450416e689b9b7c8bfb750a98604f687a9b (diff) | |
seccomp: split mode setting routines
Separates the two mode setting paths to make things more readable with
fewer #ifdefs within function bodies.
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
| -rw-r--r-- | kernel/seccomp.c | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 9df7def86c3b..05cac2c2eca1 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
| @@ -489,48 +489,66 @@ long prctl_get_seccomp(void) | |||
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | /** | 491 | /** |
| 492 | * seccomp_set_mode: internal function for setting seccomp mode | 492 | * seccomp_set_mode_strict: internal function for setting strict seccomp |
| 493 | * @seccomp_mode: requested mode to use | ||
| 494 | * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER | ||
| 495 | * | ||
| 496 | * This function may be called repeatedly with a @seccomp_mode of | ||
| 497 | * SECCOMP_MODE_FILTER to install additional filters. Every filter | ||
| 498 | * successfully installed will be evaluated (in reverse order) for each system | ||
| 499 | * call the task makes. | ||
| 500 | * | 493 | * |
| 501 | * Once current->seccomp.mode is non-zero, it may not be changed. | 494 | * Once current->seccomp.mode is non-zero, it may not be changed. |
| 502 | * | 495 | * |
| 503 | * Returns 0 on success or -EINVAL on failure. | 496 | * Returns 0 on success or -EINVAL on failure. |
| 504 | */ | 497 | */ |
| 505 | static long seccomp_set_mode(unsigned long seccomp_mode, char __user *filter) | 498 | static long seccomp_set_mode_strict(void) |
| 506 | { | 499 | { |
| 500 | const unsigned long seccomp_mode = SECCOMP_MODE_STRICT; | ||
| 507 | long ret = -EINVAL; | 501 | long ret = -EINVAL; |
| 508 | 502 | ||
| 509 | if (!seccomp_may_assign_mode(seccomp_mode)) | 503 | if (!seccomp_may_assign_mode(seccomp_mode)) |
| 510 | goto out; | 504 | goto out; |
| 511 | 505 | ||
| 512 | switch (seccomp_mode) { | ||
| 513 | case SECCOMP_MODE_STRICT: | ||
| 514 | ret = 0; | ||
| 515 | #ifdef TIF_NOTSC | 506 | #ifdef TIF_NOTSC |
| 516 | disable_TSC(); | 507 | disable_TSC(); |
| 517 | #endif | 508 | #endif |
| 518 | break; | 509 | seccomp_assign_mode(seccomp_mode); |
| 510 | ret = 0; | ||
| 511 | |||
| 512 | out: | ||
| 513 | |||
| 514 | return ret; | ||
| 515 | } | ||
| 516 | |||
| 519 | #ifdef CONFIG_SECCOMP_FILTER | 517 | #ifdef CONFIG_SECCOMP_FILTER |
| 520 | case SECCOMP_MODE_FILTER: | 518 | /** |
| 521 | ret = seccomp_attach_user_filter(filter); | 519 | * seccomp_set_mode_filter: internal function for setting seccomp filter |
| 522 | if (ret) | 520 | * @filter: struct sock_fprog containing filter |
| 523 | goto out; | 521 | * |
| 524 | break; | 522 | * This function may be called repeatedly to install additional filters. |
| 525 | #endif | 523 | * Every filter successfully installed will be evaluated (in reverse order) |
| 526 | default: | 524 | * for each system call the task makes. |
| 525 | * | ||
| 526 | * Once current->seccomp.mode is non-zero, it may not be changed. | ||
| 527 | * | ||
| 528 | * Returns 0 on success or -EINVAL on failure. | ||
| 529 | */ | ||
| 530 | static long seccomp_set_mode_filter(char __user *filter) | ||
| 531 | { | ||
| 532 | const unsigned long seccomp_mode = SECCOMP_MODE_FILTER; | ||
| 533 | long ret = -EINVAL; | ||
| 534 | |||
| 535 | if (!seccomp_may_assign_mode(seccomp_mode)) | ||
| 536 | goto out; | ||
| 537 | |||
| 538 | ret = seccomp_attach_user_filter(filter); | ||
| 539 | if (ret) | ||
| 527 | goto out; | 540 | goto out; |
| 528 | } | ||
| 529 | 541 | ||
| 530 | seccomp_assign_mode(seccomp_mode); | 542 | seccomp_assign_mode(seccomp_mode); |
| 531 | out: | 543 | out: |
| 532 | return ret; | 544 | return ret; |
| 533 | } | 545 | } |
| 546 | #else | ||
| 547 | static inline long seccomp_set_mode_filter(char __user *filter) | ||
| 548 | { | ||
| 549 | return -EINVAL; | ||
| 550 | } | ||
| 551 | #endif | ||
| 534 | 552 | ||
| 535 | /** | 553 | /** |
| 536 | * prctl_set_seccomp: configures current->seccomp.mode | 554 | * prctl_set_seccomp: configures current->seccomp.mode |
| @@ -541,5 +559,12 @@ out: | |||
| 541 | */ | 559 | */ |
| 542 | long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter) | 560 | long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter) |
| 543 | { | 561 | { |
| 544 | return seccomp_set_mode(seccomp_mode, filter); | 562 | switch (seccomp_mode) { |
| 563 | case SECCOMP_MODE_STRICT: | ||
| 564 | return seccomp_set_mode_strict(); | ||
| 565 | case SECCOMP_MODE_FILTER: | ||
| 566 | return seccomp_set_mode_filter(filter); | ||
| 567 | default: | ||
| 568 | return -EINVAL; | ||
| 569 | } | ||
| 545 | } | 570 | } |
