summaryrefslogtreecommitdiffstats
path: root/kernel/seccomp.c
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2014-06-25 18:55:25 -0400
committerKees Cook <keescook@chromium.org>2014-07-18 15:13:37 -0400
commit3b23dd12846215eff4afb073366b80c0c4d7543e (patch)
treea1c32b31840891799098d2842fefd2d5b06d2fc5 /kernel/seccomp.c
parent1f41b450416e689b9b7c8bfb750a98604f687a9b (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.c71
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 */
505static long seccomp_set_mode(unsigned long seccomp_mode, char __user *filter) 498static 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
512out:
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 */
530static 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);
531out: 543out:
532 return ret; 544 return ret;
533} 545}
546#else
547static 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 */
542long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter) 560long 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}