aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/avc.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2009-07-12 20:39:36 -0400
committerJames Morris <jmorris@namei.org>2009-07-12 20:39:36 -0400
commitbe940d6279c30a2d7c4e8d1d5435f957f594d66d (patch)
tree965805d563cb756879fd3595230c3ca205da76d1 /security/selinux/avc.c
parentb3a633c8527ef155b1a4e22e8f5abc58f7af54c9 (diff)
Revert "SELinux: Convert avc_audit to use lsm_audit.h"
This reverts commit 8113a8d80f4c6a3dc3724b39b470f3fee9c426b6. The patch causes a stack overflow on my system during boot. Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/avc.c')
-rw-r--r--security/selinux/avc.c218
1 files changed, 170 insertions, 48 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index d9fd22488ef8..236aaa2ea86d 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -492,50 +492,23 @@ out:
492 return node; 492 return node;
493} 493}
494 494
495/** 495static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
496 * avc_audit_pre_callback - SELinux specific information 496 struct in6_addr *addr, __be16 port,
497 * will be called by generic audit code 497 char *name1, char *name2)
498 * @ab: the audit buffer
499 * @a: audit_data
500 */
501static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
502{ 498{
503 struct common_audit_data *ad = a; 499 if (!ipv6_addr_any(addr))
504 struct av_decision *avd = ad->selinux_audit_data.avd; 500 audit_log_format(ab, " %s=%pI6", name1, addr);
505 u32 requested = ad->selinux_audit_data.requested; 501 if (port)
506 int result = ad->selinux_audit_data.result; 502 audit_log_format(ab, " %s=%d", name2, ntohs(port));
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 ");
524} 503}
525 504
526/** 505static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
527 * avc_audit_post_callback - SELinux specific information 506 __be16 port, char *name1, char *name2)
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)
533{ 507{
534 struct common_audit_data *ad = a; 508 if (addr)
535 audit_log_format(ab, " "); 509 audit_log_format(ab, " %s=%pI4", name1, &addr);
536 avc_dump_query(ab, ad->selinux_audit_data.ssid, 510 if (port)
537 ad->selinux_audit_data.tsid, 511 audit_log_format(ab, " %s=%d", name2, ntohs(port));
538 ad->selinux_audit_data.tclass);
539} 512}
540 513
541/** 514/**
@@ -559,14 +532,163 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
559 */ 532 */
560void avc_audit(u32 ssid, u32 tsid, 533void avc_audit(u32 ssid, u32 tsid,
561 u16 tclass, u32 requested, 534 u16 tclass, u32 requested,
562 struct av_decision *avd, int result, struct common_audit_data *a) 535 struct av_decision *avd, int result, struct avc_audit_data *a)
563{ 536{
564 a->selinux_audit_data.avd = avd; 537 struct task_struct *tsk = current;
565 a->selinux_audit_data.tclass = tclass; 538 struct inode *inode = NULL;
566 a->selinux_audit_data.requested = requested; 539 u32 denied, audited;
567 a->lsm_pre_audit = avc_audit_pre_callback; 540 struct audit_buffer *ab;
568 a->lsm_post_audit = avc_audit_post_callback; 541
569 common_lsm_audit(a); 542 denied = requested & ~avd->allowed;
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);
570} 692}
571 693
572/** 694/**
@@ -834,7 +956,7 @@ out:
834 * another -errno upon other errors. 956 * another -errno upon other errors.
835 */ 957 */
836int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, 958int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
837 u32 requested, struct common_audit_data *auditdata) 959 u32 requested, struct avc_audit_data *auditdata)
838{ 960{
839 struct av_decision avd; 961 struct av_decision avd;
840 int rc; 962 int rc;