aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-07-29 20:38:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-29 20:38:46 -0400
commit7a1e8b80fb1e8ead4cec15d1fc494ed290e4d2e9 (patch)
tree55a36d4256f1ae793b5c8e88c0f158737447193f /kernel
parenta867d7349e94b6409b08629886a819f802377e91 (diff)
parent7616ac70d1bb4f2e9d25c1a82d283f3368a7b632 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "Highlights: - TPM core and driver updates/fixes - IPv6 security labeling (CALIPSO) - Lots of Apparmor fixes - Seccomp: remove 2-phase API, close hole where ptrace can change syscall #" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (156 commits) apparmor: fix SECURITY_APPARMOR_HASH_DEFAULT parameter handling tpm: Add TPM 2.0 support to the Nuvoton i2c driver (NPCT6xx family) tpm: Factor out common startup code tpm: use devm_add_action_or_reset tpm2_i2c_nuvoton: add irq validity check tpm: read burstcount from TPM_STS in one 32-bit transaction tpm: fix byte-order for the value read by tpm2_get_tpm_pt tpm_tis_core: convert max timeouts from msec to jiffies apparmor: fix arg_size computation for when setprocattr is null terminated apparmor: fix oops, validate buffer size in apparmor_setprocattr() apparmor: do not expose kernel stack apparmor: fix module parameters can be changed after policy is locked apparmor: fix oops in profile_unpack() when policy_db is not present apparmor: don't check for vmalloc_addr if kvzalloc() failed apparmor: add missing id bounds check on dfa verification apparmor: allow SYS_CAP_RESOURCE to be sufficient to prlimit another task apparmor: use list_next_entry instead of list_entry_next apparmor: fix refcount race when finding a child profile apparmor: fix ref count leak when profile sha1 hash is read apparmor: check that xindex is in trans_table bounds ...
Diffstat (limited to 'kernel')
-rw-r--r--kernel/capability.c46
-rw-r--r--kernel/seccomp.c144
2 files changed, 92 insertions, 98 deletions
diff --git a/kernel/capability.c b/kernel/capability.c
index 45432b54d5c6..00411c82dac5 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_struct *t, int cap)
361 return has_ns_capability_noaudit(t, &init_user_ns, cap); 361 return has_ns_capability_noaudit(t, &init_user_ns, cap);
362} 362}
363 363
364static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
365{
366 int capable;
367
368 if (unlikely(!cap_valid(cap))) {
369 pr_crit("capable() called with invalid cap=%u\n", cap);
370 BUG();
371 }
372
373 capable = audit ? security_capable(current_cred(), ns, cap) :
374 security_capable_noaudit(current_cred(), ns, cap);
375 if (capable == 0) {
376 current->flags |= PF_SUPERPRIV;
377 return true;
378 }
379 return false;
380}
381
364/** 382/**
365 * ns_capable - Determine if the current task has a superior capability in effect 383 * ns_capable - Determine if the current task has a superior capability in effect
366 * @ns: The usernamespace we want the capability in 384 * @ns: The usernamespace we want the capability in
@@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_struct *t, int cap)
374 */ 392 */
375bool ns_capable(struct user_namespace *ns, int cap) 393bool ns_capable(struct user_namespace *ns, int cap)
376{ 394{
377 if (unlikely(!cap_valid(cap))) { 395 return ns_capable_common(ns, cap, true);
378 pr_crit("capable() called with invalid cap=%u\n", cap);
379 BUG();
380 }
381
382 if (security_capable(current_cred(), ns, cap) == 0) {
383 current->flags |= PF_SUPERPRIV;
384 return true;
385 }
386 return false;
387} 396}
388EXPORT_SYMBOL(ns_capable); 397EXPORT_SYMBOL(ns_capable);
389 398
399/**
400 * ns_capable_noaudit - Determine if the current task has a superior capability
401 * (unaudited) in effect
402 * @ns: The usernamespace we want the capability in
403 * @cap: The capability to be tested for
404 *
405 * Return true if the current task has the given superior capability currently
406 * available for use, false if not.
407 *
408 * This sets PF_SUPERPRIV on the task if the capability is available on the
409 * assumption that it's about to be used.
410 */
411bool ns_capable_noaudit(struct user_namespace *ns, int cap)
412{
413 return ns_capable_common(ns, cap, false);
414}
415EXPORT_SYMBOL(ns_capable_noaudit);
390 416
391/** 417/**
392 * capable - Determine if the current task has a superior capability in effect 418 * capable - Determine if the current task has a superior capability in effect
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 7002796f14a4..54d15eb2b701 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -173,7 +173,7 @@ static int seccomp_check_filter(struct sock_filter *filter, unsigned int flen)
173 * 173 *
174 * Returns valid seccomp BPF response codes. 174 * Returns valid seccomp BPF response codes.
175 */ 175 */
176static u32 seccomp_run_filters(struct seccomp_data *sd) 176static u32 seccomp_run_filters(const struct seccomp_data *sd)
177{ 177{
178 struct seccomp_data sd_local; 178 struct seccomp_data sd_local;
179 u32 ret = SECCOMP_RET_ALLOW; 179 u32 ret = SECCOMP_RET_ALLOW;
@@ -554,20 +554,10 @@ void secure_computing_strict(int this_syscall)
554 BUG(); 554 BUG();
555} 555}
556#else 556#else
557int __secure_computing(void)
558{
559 u32 phase1_result = seccomp_phase1(NULL);
560
561 if (likely(phase1_result == SECCOMP_PHASE1_OK))
562 return 0;
563 else if (likely(phase1_result == SECCOMP_PHASE1_SKIP))
564 return -1;
565 else
566 return seccomp_phase2(phase1_result);
567}
568 557
569#ifdef CONFIG_SECCOMP_FILTER 558#ifdef CONFIG_SECCOMP_FILTER
570static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd) 559static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
560 const bool recheck_after_trace)
571{ 561{
572 u32 filter_ret, action; 562 u32 filter_ret, action;
573 int data; 563 int data;
@@ -599,10 +589,46 @@ static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
599 goto skip; 589 goto skip;
600 590
601 case SECCOMP_RET_TRACE: 591 case SECCOMP_RET_TRACE:
602 return filter_ret; /* Save the rest for phase 2. */ 592 /* We've been put in this state by the ptracer already. */
593 if (recheck_after_trace)
594 return 0;
595
596 /* ENOSYS these calls if there is no tracer attached. */
597 if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
598 syscall_set_return_value(current,
599 task_pt_regs(current),
600 -ENOSYS, 0);
601 goto skip;
602 }
603
604 /* Allow the BPF to provide the event message */
605 ptrace_event(PTRACE_EVENT_SECCOMP, data);
606 /*
607 * The delivery of a fatal signal during event
608 * notification may silently skip tracer notification.
609 * Terminating the task now avoids executing a system
610 * call that may not be intended.
611 */
612 if (fatal_signal_pending(current))
613 do_exit(SIGSYS);
614 /* Check if the tracer forced the syscall to be skipped. */
615 this_syscall = syscall_get_nr(current, task_pt_regs(current));
616 if (this_syscall < 0)
617 goto skip;
618
619 /*
620 * Recheck the syscall, since it may have changed. This
621 * intentionally uses a NULL struct seccomp_data to force
622 * a reload of all registers. This does not goto skip since
623 * a skip would have already been reported.
624 */
625 if (__seccomp_filter(this_syscall, NULL, true))
626 return -1;
627
628 return 0;
603 629
604 case SECCOMP_RET_ALLOW: 630 case SECCOMP_RET_ALLOW:
605 return SECCOMP_PHASE1_OK; 631 return 0;
606 632
607 case SECCOMP_RET_KILL: 633 case SECCOMP_RET_KILL:
608 default: 634 default:
@@ -614,96 +640,38 @@ static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
614 640
615skip: 641skip:
616 audit_seccomp(this_syscall, 0, action); 642 audit_seccomp(this_syscall, 0, action);
617 return SECCOMP_PHASE1_SKIP; 643 return -1;
644}
645#else
646static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
647 const bool recheck_after_trace)
648{
649 BUG();
618} 650}
619#endif 651#endif
620 652
621/** 653int __secure_computing(const struct seccomp_data *sd)
622 * seccomp_phase1() - run fast path seccomp checks on the current syscall
623 * @arg sd: The seccomp_data or NULL
624 *
625 * This only reads pt_regs via the syscall_xyz helpers. The only change
626 * it will make to pt_regs is via syscall_set_return_value, and it will
627 * only do that if it returns SECCOMP_PHASE1_SKIP.
628 *
629 * If sd is provided, it will not read pt_regs at all.
630 *
631 * It may also call do_exit or force a signal; these actions must be
632 * safe.
633 *
634 * If it returns SECCOMP_PHASE1_OK, the syscall passes checks and should
635 * be processed normally.
636 *
637 * If it returns SECCOMP_PHASE1_SKIP, then the syscall should not be
638 * invoked. In this case, seccomp_phase1 will have set the return value
639 * using syscall_set_return_value.
640 *
641 * If it returns anything else, then the return value should be passed
642 * to seccomp_phase2 from a context in which ptrace hooks are safe.
643 */
644u32 seccomp_phase1(struct seccomp_data *sd)
645{ 654{
646 int mode = current->seccomp.mode; 655 int mode = current->seccomp.mode;
647 int this_syscall = sd ? sd->nr : 656 int this_syscall;
648 syscall_get_nr(current, task_pt_regs(current));
649 657
650 if (config_enabled(CONFIG_CHECKPOINT_RESTORE) && 658 if (config_enabled(CONFIG_CHECKPOINT_RESTORE) &&
651 unlikely(current->ptrace & PT_SUSPEND_SECCOMP)) 659 unlikely(current->ptrace & PT_SUSPEND_SECCOMP))
652 return SECCOMP_PHASE1_OK; 660 return 0;
661
662 this_syscall = sd ? sd->nr :
663 syscall_get_nr(current, task_pt_regs(current));
653 664
654 switch (mode) { 665 switch (mode) {
655 case SECCOMP_MODE_STRICT: 666 case SECCOMP_MODE_STRICT:
656 __secure_computing_strict(this_syscall); /* may call do_exit */ 667 __secure_computing_strict(this_syscall); /* may call do_exit */
657 return SECCOMP_PHASE1_OK; 668 return 0;
658#ifdef CONFIG_SECCOMP_FILTER
659 case SECCOMP_MODE_FILTER: 669 case SECCOMP_MODE_FILTER:
660 return __seccomp_phase1_filter(this_syscall, sd); 670 return __seccomp_filter(this_syscall, sd, false);
661#endif
662 default: 671 default:
663 BUG(); 672 BUG();
664 } 673 }
665} 674}
666
667/**
668 * seccomp_phase2() - finish slow path seccomp work for the current syscall
669 * @phase1_result: The return value from seccomp_phase1()
670 *
671 * This must be called from a context in which ptrace hooks can be used.
672 *
673 * Returns 0 if the syscall should be processed or -1 to skip the syscall.
674 */
675int seccomp_phase2(u32 phase1_result)
676{
677 struct pt_regs *regs = task_pt_regs(current);
678 u32 action = phase1_result & SECCOMP_RET_ACTION;
679 int data = phase1_result & SECCOMP_RET_DATA;
680
681 BUG_ON(action != SECCOMP_RET_TRACE);
682
683 audit_seccomp(syscall_get_nr(current, regs), 0, action);
684
685 /* Skip these calls if there is no tracer. */
686 if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
687 syscall_set_return_value(current, regs,
688 -ENOSYS, 0);
689 return -1;
690 }
691
692 /* Allow the BPF to provide the event message */
693 ptrace_event(PTRACE_EVENT_SECCOMP, data);
694 /*
695 * The delivery of a fatal signal during event
696 * notification may silently skip tracer notification.
697 * Terminating the task now avoids executing a system
698 * call that may not be intended.
699 */
700 if (fatal_signal_pending(current))
701 do_exit(SIGSYS);
702 if (syscall_get_nr(current, regs) < 0)
703 return -1; /* Explicit request to skip. */
704
705 return 0;
706}
707#endif /* CONFIG_HAVE_ARCH_SECCOMP_FILTER */ 675#endif /* CONFIG_HAVE_ARCH_SECCOMP_FILTER */
708 676
709long prctl_get_seccomp(void) 677long prctl_get_seccomp(void)