aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/avc.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/avc.c')
-rw-r--r--security/selinux/avc.c218
1 files changed, 48 insertions, 170 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 236aaa2ea86d..d9fd22488ef8 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -492,23 +492,50 @@ out:
492 return node; 492 return node;
493} 493}
494 494
495static inline void avc_print_ipv6_addr(struct audit_buffer *ab, 495/**
496 struct in6_addr *addr, __be16 port, 496 * avc_audit_pre_callback - SELinux specific information
497 char *name1, char *name2) 497 * will be called by generic audit code
498 * @ab: the audit buffer
499 * @a: audit_data
500 */
501static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
498{ 502{
499 if (!ipv6_addr_any(addr)) 503 struct common_audit_data *ad = a;
500 audit_log_format(ab, " %s=%pI6", name1, addr); 504 struct av_decision *avd = ad->selinux_audit_data.avd;
501 if (port) 505 u32 requested = ad->selinux_audit_data.requested;
502 audit_log_format(ab, " %s=%d", name2, ntohs(port)); 506 int result = ad->selinux_audit_data.result;
507 u32 denied, audited;
508 denied = requested & ~avd->allowed;
509 if (denied) {
510 audited = denied;
511 if (!(audited & avd->auditdeny))
512 return;
513 } else if (result) {
514 audited = denied = requested;
515 } else {
516 audited = requested;
517 if (!(audited & avd->auditallow))
518 return;
519 }
520 audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
521 avc_dump_av(ab, ad->selinux_audit_data.tclass,
522 ad->selinux_audit_data.audited);
523 audit_log_format(ab, " for ");
503} 524}
504 525
505static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr, 526/**
506 __be16 port, char *name1, char *name2) 527 * avc_audit_post_callback - SELinux specific information
528 * will be called by generic audit code
529 * @ab: the audit buffer
530 * @a: audit_data
531 */
532static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
507{ 533{
508 if (addr) 534 struct common_audit_data *ad = a;
509 audit_log_format(ab, " %s=%pI4", name1, &addr); 535 audit_log_format(ab, " ");
510 if (port) 536 avc_dump_query(ab, ad->selinux_audit_data.ssid,
511 audit_log_format(ab, " %s=%d", name2, ntohs(port)); 537 ad->selinux_audit_data.tsid,
538 ad->selinux_audit_data.tclass);
512} 539}
513 540
514/** 541/**
@@ -532,163 +559,14 @@ static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
532 */ 559 */
533void avc_audit(u32 ssid, u32 tsid, 560void avc_audit(u32 ssid, u32 tsid,
534 u16 tclass, u32 requested, 561 u16 tclass, u32 requested,
535 struct av_decision *avd, int result, struct avc_audit_data *a) 562 struct av_decision *avd, int result, struct common_audit_data *a)
536{ 563{
537 struct task_struct *tsk = current; 564 a->selinux_audit_data.avd = avd;
538 struct inode *inode = NULL; 565 a->selinux_audit_data.tclass = tclass;
539 u32 denied, audited; 566 a->selinux_audit_data.requested = requested;
540 struct audit_buffer *ab; 567 a->lsm_pre_audit = avc_audit_pre_callback;
541 568 a->lsm_post_audit = avc_audit_post_callback;
542 denied = requested & ~avd->allowed; 569 common_lsm_audit(a);
543 if (denied) {
544 audited = denied;
545 if (!(audited & avd->auditdeny))
546 return;
547 } else if (result) {
548 audited = denied = requested;
549 } else {
550 audited = requested;
551 if (!(audited & avd->auditallow))
552 return;
553 }
554
555 ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
556 if (!ab)
557 return; /* audit_panic has been called */
558 audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
559 avc_dump_av(ab, tclass, audited);
560 audit_log_format(ab, " for ");
561 if (a && a->tsk)
562 tsk = a->tsk;
563 if (tsk && tsk->pid) {
564 audit_log_format(ab, " pid=%d comm=", tsk->pid);
565 audit_log_untrustedstring(ab, tsk->comm);
566 }
567 if (a) {
568 switch (a->type) {
569 case AVC_AUDIT_DATA_IPC:
570 audit_log_format(ab, " key=%d", a->u.ipc_id);
571 break;
572 case AVC_AUDIT_DATA_CAP:
573 audit_log_format(ab, " capability=%d", a->u.cap);
574 break;
575 case AVC_AUDIT_DATA_FS:
576 if (a->u.fs.path.dentry) {
577 struct dentry *dentry = a->u.fs.path.dentry;
578 if (a->u.fs.path.mnt) {
579 audit_log_d_path(ab, "path=",
580 &a->u.fs.path);
581 } else {
582 audit_log_format(ab, " name=");
583 audit_log_untrustedstring(ab, dentry->d_name.name);
584 }
585 inode = dentry->d_inode;
586 } else if (a->u.fs.inode) {
587 struct dentry *dentry;
588 inode = a->u.fs.inode;
589 dentry = d_find_alias(inode);
590 if (dentry) {
591 audit_log_format(ab, " name=");
592 audit_log_untrustedstring(ab, dentry->d_name.name);
593 dput(dentry);
594 }
595 }
596 if (inode)
597 audit_log_format(ab, " dev=%s ino=%lu",
598 inode->i_sb->s_id,
599 inode->i_ino);
600 break;
601 case AVC_AUDIT_DATA_NET:
602 if (a->u.net.sk) {
603 struct sock *sk = a->u.net.sk;
604 struct unix_sock *u;
605 int len = 0;
606 char *p = NULL;
607
608 switch (sk->sk_family) {
609 case AF_INET: {
610 struct inet_sock *inet = inet_sk(sk);
611
612 avc_print_ipv4_addr(ab, inet->rcv_saddr,
613 inet->sport,
614 "laddr", "lport");
615 avc_print_ipv4_addr(ab, inet->daddr,
616 inet->dport,
617 "faddr", "fport");
618 break;
619 }
620 case AF_INET6: {
621 struct inet_sock *inet = inet_sk(sk);
622 struct ipv6_pinfo *inet6 = inet6_sk(sk);
623
624 avc_print_ipv6_addr(ab, &inet6->rcv_saddr,
625 inet->sport,
626 "laddr", "lport");
627 avc_print_ipv6_addr(ab, &inet6->daddr,
628 inet->dport,
629 "faddr", "fport");
630 break;
631 }
632 case AF_UNIX:
633 u = unix_sk(sk);
634 if (u->dentry) {
635 struct path path = {
636 .dentry = u->dentry,
637 .mnt = u->mnt
638 };
639 audit_log_d_path(ab, "path=",
640 &path);
641 break;
642 }
643 if (!u->addr)
644 break;
645 len = u->addr->len-sizeof(short);
646 p = &u->addr->name->sun_path[0];
647 audit_log_format(ab, " path=");
648 if (*p)
649 audit_log_untrustedstring(ab, p);
650 else
651 audit_log_n_hex(ab, p, len);
652 break;
653 }
654 }
655
656 switch (a->u.net.family) {
657 case AF_INET:
658 avc_print_ipv4_addr(ab, a->u.net.v4info.saddr,
659 a->u.net.sport,
660 "saddr", "src");
661 avc_print_ipv4_addr(ab, a->u.net.v4info.daddr,
662 a->u.net.dport,
663 "daddr", "dest");
664 break;
665 case AF_INET6:
666 avc_print_ipv6_addr(ab, &a->u.net.v6info.saddr,
667 a->u.net.sport,
668 "saddr", "src");
669 avc_print_ipv6_addr(ab, &a->u.net.v6info.daddr,
670 a->u.net.dport,
671 "daddr", "dest");
672 break;
673 }
674 if (a->u.net.netif > 0) {
675 struct net_device *dev;
676
677 /* NOTE: we always use init's namespace */
678 dev = dev_get_by_index(&init_net,
679 a->u.net.netif);
680 if (dev) {
681 audit_log_format(ab, " netif=%s",
682 dev->name);
683 dev_put(dev);
684 }
685 }
686 break;
687 }
688 }
689 audit_log_format(ab, " ");
690 avc_dump_query(ab, ssid, tsid, tclass);
691 audit_log_end(ab);
692} 570}
693 571
694/** 572/**
@@ -956,7 +834,7 @@ out:
956 * another -errno upon other errors. 834 * another -errno upon other errors.
957 */ 835 */
958int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, 836int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
959 u32 requested, struct avc_audit_data *auditdata) 837 u32 requested, struct common_audit_data *auditdata)
960{ 838{
961 struct av_decision avd; 839 struct av_decision avd;
962 int rc; 840 int rc;