summaryrefslogtreecommitdiffstats
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c81
1 files changed, 58 insertions, 23 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 71e2b914363..a1b57e4dba3 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -245,7 +245,7 @@ out:
/**
* smk_write_load - write() for /smack/load
- * @filp: file pointer, not actually used
+ * @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start - must be 0
@@ -334,7 +334,7 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
break;
case 'a':
case 'A':
- rule.smk_access |= MAY_READ;
+ rule.smk_access |= MAY_APPEND;
break;
default:
goto out;
@@ -402,6 +402,7 @@ static void smk_cipso_doi(void)
/**
* smk_unlbl_ambient - initialize the unlabeled domain
+ * @oldambient: previous domain string
*/
static void smk_unlbl_ambient(char *oldambient)
{
@@ -513,7 +514,7 @@ static int smk_open_cipso(struct inode *inode, struct file *file)
/**
* smk_write_cipso - write() for /smack/cipso
- * @filp: file pointer, not actually used
+ * @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start
@@ -650,10 +651,6 @@ static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
return skp;
}
-/*
-#define BEMASK 0x80000000
-*/
-#define BEMASK 0x00000001
#define BEBITS (sizeof(__be32) * 8)
/*
@@ -663,12 +660,10 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
{
struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v;
unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr;
- __be32 bebits;
- int maskn = 0;
+ int maskn;
+ u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
- for (bebits = BEMASK; bebits != 0; maskn++, bebits <<= 1)
- if ((skp->smk_mask.s_addr & bebits) == 0)
- break;
+ for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++);
seq_printf(s, "%u.%u.%u.%u/%d %s\n",
hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label);
@@ -702,8 +697,44 @@ static int smk_open_netlbladdr(struct inode *inode, struct file *file)
}
/**
+ * smk_netlbladdr_insert
+ * @new : netlabel to insert
+ *
+ * This helper insert netlabel in the smack_netlbladdrs list
+ * sorted by netmask length (longest to smallest)
+ */
+static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
+{
+ struct smk_netlbladdr *m;
+
+ if (smack_netlbladdrs == NULL) {
+ smack_netlbladdrs = new;
+ return;
+ }
+
+ /* the comparison '>' is a bit hacky, but works */
+ if (new->smk_mask.s_addr > smack_netlbladdrs->smk_mask.s_addr) {
+ new->smk_next = smack_netlbladdrs;
+ smack_netlbladdrs = new;
+ return;
+ }
+ for (m = smack_netlbladdrs; m != NULL; m = m->smk_next) {
+ if (m->smk_next == NULL) {
+ m->smk_next = new;
+ return;
+ }
+ if (new->smk_mask.s_addr > m->smk_next->smk_mask.s_addr) {
+ new->smk_next = m->smk_next;
+ m->smk_next = new;
+ return;
+ }
+ }
+}
+
+
+/**
* smk_write_netlbladdr - write() for /smack/netlabel
- * @filp: file pointer, not actually used
+ * @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start
@@ -724,8 +755,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
struct netlbl_audit audit_info;
struct in_addr mask;
unsigned int m;
- __be32 bebits = BEMASK;
+ u32 mask_bits = (1<<31);
__be32 nsa;
+ u32 temp_mask;
/*
* Must have privilege.
@@ -761,10 +793,13 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
if (sp == NULL)
return -EINVAL;
- for (mask.s_addr = 0; m > 0; m--) {
- mask.s_addr |= bebits;
- bebits <<= 1;
+ for (temp_mask = 0; m > 0; m--) {
+ temp_mask |= mask_bits;
+ mask_bits >>= 1;
}
+ mask.s_addr = cpu_to_be32(temp_mask);
+
+ newname.sin_addr.s_addr &= mask.s_addr;
/*
* Only allow one writer at a time. Writes should be
* quite rare and small in any case.
@@ -772,6 +807,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
mutex_lock(&smk_netlbladdr_lock);
nsa = newname.sin_addr.s_addr;
+ /* try to find if the prefix is already in the list */
for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next)
if (skp->smk_host.sin_addr.s_addr == nsa &&
skp->smk_mask.s_addr == mask.s_addr)
@@ -787,9 +823,8 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
rc = 0;
skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr;
skp->smk_mask.s_addr = mask.s_addr;
- skp->smk_next = smack_netlbladdrs;
skp->smk_label = sp;
- smack_netlbladdrs = skp;
+ smk_netlbladdr_insert(skp);
}
} else {
rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
@@ -850,7 +885,7 @@ static ssize_t smk_read_doi(struct file *filp, char __user *buf,
/**
* smk_write_doi - write() for /smack/doi
- * @filp: file pointer, not actually used
+ * @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start
@@ -915,7 +950,7 @@ static ssize_t smk_read_direct(struct file *filp, char __user *buf,
/**
* smk_write_direct - write() for /smack/direct
- * @filp: file pointer, not actually used
+ * @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start
@@ -990,7 +1025,7 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
/**
* smk_write_ambient - write() for /smack/ambient
- * @filp: file pointer, not actually used
+ * @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start
@@ -1065,7 +1100,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
/**
* smk_write_onlycap - write() for /smack/onlycap
- * @filp: file pointer, not actually used
+ * @file: file pointer, not actually used
* @buf: where to get the data from
* @count: bytes sent
* @ppos: where to start