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:36:34 -0500
commit211a40c0870457b29100cffea0180fa5083caf96 (patch)
treefae71ac7a443a45391ee6049f2300a5c25fe2272 /security/smack/smackfs.c
parent559595a985e106d2fa9f0c79b7f5805453fed593 (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 8e42800878f4..51f0efc50dab 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -650,10 +650,6 @@ static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
650 650
651 return skp; 651 return skp;
652} 652}
653/*
654#define BEMASK 0x80000000
655*/
656#define BEMASK 0x00000001
657#define BEBITS (sizeof(__be32) * 8) 653#define BEBITS (sizeof(__be32) * 8)
658 654
659/* 655/*
@@ -663,12 +659,10 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
663{ 659{
664 struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v; 660 struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v;
665 unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr; 661 unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr;
666 __be32 bebits; 662 int maskn;
667 int maskn = 0; 663 u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
668 664
669 for (bebits = BEMASK; bebits != 0; maskn++, bebits <<= 1) 665 for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++);
670 if ((skp->smk_mask.s_addr & bebits) == 0)
671 break;
672 666
673 seq_printf(s, "%u.%u.%u.%u/%d %s\n", 667 seq_printf(s, "%u.%u.%u.%u/%d %s\n",
674 hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label); 668 hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label);
@@ -702,6 +696,42 @@ static int smk_open_netlbladdr(struct inode *inode, struct file *file)
702} 696}
703 697
704/** 698/**
699 * smk_netlbladdr_insert
700 * @new : netlabel to insert
701 *
702 * This helper insert netlabel in the smack_netlbladdrs list
703 * sorted by netmask length (longest to smallest)
704 */
705static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
706{
707 struct smk_netlbladdr *m;
708
709 if (smack_netlbladdrs == NULL) {
710 smack_netlbladdrs = new;
711 return;
712 }
713
714 /* the comparison '>' is a bit hacky, but works */
715 if (new->smk_mask.s_addr > smack_netlbladdrs->smk_mask.s_addr) {
716 new->smk_next = smack_netlbladdrs;
717 smack_netlbladdrs = new;
718 return;
719 }
720 for (m = smack_netlbladdrs; m != NULL; m = m->smk_next) {
721 if (m->smk_next == NULL) {
722 m->smk_next = new;
723 return;
724 }
725 if (new->smk_mask.s_addr > m->smk_next->smk_mask.s_addr) {
726 new->smk_next = m->smk_next;
727 m->smk_next = new;
728 return;
729 }
730 }
731}
732
733
734/**
705 * smk_write_netlbladdr - write() for /smack/netlabel 735 * smk_write_netlbladdr - write() for /smack/netlabel
706 * @filp: file pointer, not actually used 736 * @filp: file pointer, not actually used
707 * @buf: where to get the data from 737 * @buf: where to get the data from
@@ -724,8 +754,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
724 struct netlbl_audit audit_info; 754 struct netlbl_audit audit_info;
725 struct in_addr mask; 755 struct in_addr mask;
726 unsigned int m; 756 unsigned int m;
727 __be32 bebits = BEMASK; 757 u32 mask_bits = (1<<31);
728 __be32 nsa; 758 __be32 nsa;
759 u32 temp_mask;
729 760
730 /* 761 /*
731 * Must have privilege. 762 * Must have privilege.
@@ -761,10 +792,13 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
761 if (sp == NULL) 792 if (sp == NULL)
762 return -EINVAL; 793 return -EINVAL;
763 794
764 for (mask.s_addr = 0; m > 0; m--) { 795 for (temp_mask = 0; m > 0; m--) {
765 mask.s_addr |= bebits; 796 temp_mask |= mask_bits;
766 bebits <<= 1; 797 mask_bits >>= 1;
767 } 798 }
799 mask.s_addr = cpu_to_be32(temp_mask);
800
801 newname.sin_addr.s_addr &= mask.s_addr;
768 /* 802 /*
769 * Only allow one writer at a time. Writes should be 803 * Only allow one writer at a time. Writes should be
770 * quite rare and small in any case. 804 * quite rare and small in any case.
@@ -772,6 +806,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
772 mutex_lock(&smk_netlbladdr_lock); 806 mutex_lock(&smk_netlbladdr_lock);
773 807
774 nsa = newname.sin_addr.s_addr; 808 nsa = newname.sin_addr.s_addr;
809 /* try to find if the prefix is already in the list */
775 for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next) 810 for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next)
776 if (skp->smk_host.sin_addr.s_addr == nsa && 811 if (skp->smk_host.sin_addr.s_addr == nsa &&
777 skp->smk_mask.s_addr == mask.s_addr) 812 skp->smk_mask.s_addr == mask.s_addr)
@@ -787,9 +822,8 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
787 rc = 0; 822 rc = 0;
788 skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; 823 skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr;
789 skp->smk_mask.s_addr = mask.s_addr; 824 skp->smk_mask.s_addr = mask.s_addr;
790 skp->smk_next = smack_netlbladdrs;
791 skp->smk_label = sp; 825 skp->smk_label = sp;
792 smack_netlbladdrs = skp; 826 smk_netlbladdr_insert(skp);
793 } 827 }
794 } else { 828 } else {
795 rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, 829 rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,