diff options
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r-- | security/smack/smackfs.c | 81 |
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 |