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 /kernel/seccomp.c | |
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>
Diffstat (limited to 'kernel/seccomp.c')
-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 | } |