aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
authoretienne <etienne.basset@numericable.fr>2009-03-04 01:33:51 -0500
committerJames Morris <jmorris@namei.org>2009-03-04 16:30:01 -0500
commit113a0e4590881ce579ca992a80ddc562b3372ede (patch)
tree29dd1cd1c5f594efb51cdf9530a90ba2f3f2854e /security/smack/smackfs.c
parent454804ab0302b354e35d992d08e53fe03313baaf (diff)
smack: fixes for unlabeled host support
The following patch (against 2.6.29rc5) fixes a few issues in the smack/netlabel "unlabeled host support" functionnality that was added in 2.6.29rc. It should go in before -final. 1) smack_host_label disregard a "0.0.0.0/0 @" rule (or other label), preventing 'tagged' tasks to access Internet (many systems drop packets with IP options) 2) netmasks were not handled correctly, they were stored in a way _not equivalent_ to conversion to be32 (it was equivalent for /0, /8, /16, /24, /32 masks but not other masks) 3) smack_netlbladdr prefixes (IP/mask) were not consistent (mask&IP was not done), so there could have been different list entries for the same IP prefix; if those entries had different labels, well ... 4) they were not sorted 1) 2) 3) are bugs, 4) is a more cosmetic issue. The patch : -creates a new helper smk_netlbladdr_insert to insert a smk_netlbladdr, -sorted by netmask length -use the new sorted nature of smack_netlbladdrs list to simplify smack_host_label : the first match _will_ be the more specific -corrects endianness issues in smk_write_netlbladdr & netlbladdr_seq_show Signed-off-by: <etienne.basset@numericable.fr> Acked-by: Casey Schaufler <casey@schaufler-ca.com> Reviewed-by: Paul Moore <paul.moore@hp.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index fd8d1eb43700..a1b57e4dba3e 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -651,10 +651,6 @@ static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
651 651
652 return skp; 652 return skp;
653} 653}
654/*
655#define BEMASK 0x80000000
656*/
657#define BEMASK 0x00000001
658#define BEBITS (sizeof(__be32) * 8) 654#define BEBITS (sizeof(__be32) * 8)
659 655
660/* 656/*
@@ -664,12 +660,10 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
664{ 660{
665 struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v; 661 struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v;
666 unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr; 662 unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr;
667 __be32 bebits; 663 int maskn;
668 int maskn = 0; 664 u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
669 665
670 for (bebits = BEMASK; bebits != 0; maskn++, bebits <<= 1) 666 for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++);
671 if ((skp->smk_mask.s_addr & bebits) == 0)
672 break;
673 667
674 seq_printf(s, "%u.%u.%u.%u/%d %s\n", 668 seq_printf(s, "%u.%u.%u.%u/%d %s\n",
675 hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label); 669 hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label);
@@ -703,6 +697,42 @@ static int smk_open_netlbladdr(struct inode *inode, struct file *file)
703} 697}
704 698
705/** 699/**
700 * smk_netlbladdr_insert
701 * @new : netlabel to insert
702 *
703 * This helper insert netlabel in the smack_netlbladdrs list
704 * sorted by netmask length (longest to smallest)
705 */
706static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
707{
708 struct smk_netlbladdr *m;
709
710 if (smack_netlbladdrs == NULL) {
711 smack_netlbladdrs = new;
712 return;
713 }
714
715 /* the comparison '>' is a bit hacky, but works */
716 if (new->smk_mask.s_addr > smack_netlbladdrs->smk_mask.s_addr) {
717 new->smk_next = smack_netlbladdrs;
718 smack_netlbladdrs = new;
719 return;
720 }
721 for (m = smack_netlbladdrs; m != NULL; m = m->smk_next) {
722 if (m->smk_next == NULL) {
723 m->smk_next = new;
724 return;
725 }
726 if (new->smk_mask.s_addr > m->smk_next->smk_mask.s_addr) {
727 new->smk_next = m->smk_next;
728 m->smk_next = new;
729 return;
730 }
731 }
732}
733
734
735/**
706 * smk_write_netlbladdr - write() for /smack/netlabel 736 * smk_write_netlbladdr - write() for /smack/netlabel
707 * @file: file pointer, not actually used 737 * @file: file pointer, not actually used
708 * @buf: where to get the data from 738 * @buf: where to get the data from
@@ -725,8 +755,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
725 struct netlbl_audit audit_info; 755 struct netlbl_audit audit_info;
726 struct in_addr mask; 756 struct in_addr mask;
727 unsigned int m; 757 unsigned int m;
728 __be32 bebits = BEMASK; 758 u32 mask_bits = (1<<31);
729 __be32 nsa; 759 __be32 nsa;
760 u32 temp_mask;
730 761
731 /* 762 /*
732 * Must have privilege. 763 * Must have privilege.
@@ -762,10 +793,13 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
762 if (sp == NULL) 793 if (sp == NULL)
763 return -EINVAL; 794 return -EINVAL;
764 795
765 for (mask.s_addr = 0; m > 0; m--) { 796 for (temp_mask = 0; m > 0; m--) {
766 mask.s_addr |= bebits; 797 temp_mask |= mask_bits;
767 bebits <<= 1; 798 mask_bits >>= 1;
768 } 799 }
800 mask.s_addr = cpu_to_be32(temp_mask);
801
802 newname.sin_addr.s_addr &= mask.s_addr;
769 /* 803 /*
770 * Only allow one writer at a time. Writes should be 804 * Only allow one writer at a time. Writes should be
771 * quite rare and small in any case. 805 * quite rare and small in any case.
@@ -773,6 +807,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
773 mutex_lock(&smk_netlbladdr_lock); 807 mutex_lock(&smk_netlbladdr_lock);
774 808
775 nsa = newname.sin_addr.s_addr; 809 nsa = newname.sin_addr.s_addr;
810 /* try to find if the prefix is already in the list */
776 for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next) 811 for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next)
777 if (skp->smk_host.sin_addr.s_addr == nsa && 812 if (skp->smk_host.sin_addr.s_addr == nsa &&
778 skp->smk_mask.s_addr == mask.s_addr) 813 skp->smk_mask.s_addr == mask.s_addr)
@@ -788,9 +823,8 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
788 rc = 0; 823 rc = 0;
789 skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; 824 skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr;
790 skp->smk_mask.s_addr = mask.s_addr; 825 skp->smk_mask.s_addr = mask.s_addr;
791 skp->smk_next = smack_netlbladdrs;
792 skp->smk_label = sp; 826 skp->smk_label = sp;
793 smack_netlbladdrs = skp; 827 smk_netlbladdr_insert(skp);
794 } 828 }
795 } else { 829 } else {
796 rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, 830 rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,