diff options
Diffstat (limited to 'security/smack')
-rw-r--r-- | security/smack/smack.h | 14 | ||||
-rw-r--r-- | security/smack/smack_access.c | 9 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 25 | ||||
-rw-r--r-- | security/smack/smackfs.c | 61 |
4 files changed, 55 insertions, 54 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h index cc361b8f3d13..99b36124f712 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -43,7 +43,6 @@ struct superblock_smack { char *smk_hat; char *smk_default; int smk_initialized; - spinlock_t smk_sblock; /* for initialization */ }; struct socket_smack { @@ -284,6 +283,19 @@ static inline char *smk_of_current(void) } /* + * Is the task privileged and allowed to be privileged + * by the onlycap rule. + */ +static inline int smack_privileged(int cap) +{ + if (!capable(cap)) + return 0; + if (smack_onlycap == NULL || smack_onlycap == smk_of_current()) + return 1; + return 0; +} + +/* * logging functions */ #define SMACK_AUDIT_DENIED 0x1 diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 9f3705e92712..db14689a21e0 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -220,14 +220,9 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) } /* - * Return if a specific label has been designated as the - * only one that gets privilege and current does not - * have that label. + * Allow for priviliged to override policy. */ - if (smack_onlycap != NULL && smack_onlycap != sp) - goto out_audit; - - if (capable(CAP_MAC_OVERRIDE)) + if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE)) rc = 0; out_audit: diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ee0bb5735f35..8221514cc997 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -217,7 +217,7 @@ static int smack_syslog(int typefrom_file) int rc = 0; char *sp = smk_of_current(); - if (capable(CAP_MAC_OVERRIDE)) + if (smack_privileged(CAP_MAC_OVERRIDE)) return 0; if (sp != smack_known_floor.smk_known) @@ -251,7 +251,6 @@ static int smack_sb_alloc_security(struct super_block *sb) sbsp->smk_floor = smack_known_floor.smk_known; sbsp->smk_hat = smack_known_hat.smk_known; sbsp->smk_initialized = 0; - spin_lock_init(&sbsp->smk_sblock); sb->s_security = sbsp; @@ -332,13 +331,10 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) char *commap; char *nsp; - spin_lock(&sp->smk_sblock); - if (sp->smk_initialized != 0) { - spin_unlock(&sp->smk_sblock); + if (sp->smk_initialized != 0) return 0; - } + sp->smk_initialized = 1; - spin_unlock(&sp->smk_sblock); for (op = data; op != NULL; op = commap) { commap = strchr(op, ','); @@ -825,7 +821,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) rc = -EPERM; /* * check label validity here so import wont fail on @@ -835,7 +831,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, smk_import(value, size) == NULL) rc = -EINVAL; } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) rc = -EPERM; if (size != TRANS_TRUE_SIZE || strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) @@ -931,7 +927,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || strcmp(name, XATTR_NAME_SMACKMMAP)) { - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) rc = -EPERM; } else rc = cap_inode_removexattr(dentry, name); @@ -1720,7 +1716,8 @@ static int smack_task_wait(struct task_struct *p) * state into account in the decision as well as * the smack value. */ - if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) + if (smack_privileged(CAP_MAC_OVERRIDE) || + has_capability(p, CAP_MAC_OVERRIDE)) rc = 0; /* we log only if we didn't get overriden */ out_log: @@ -2721,7 +2718,7 @@ static int smack_setprocattr(struct task_struct *p, char *name, if (p != current) return -EPERM; - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; if (value == NULL || size == 0 || size >= SMK_LONGLABEL) @@ -2784,7 +2781,7 @@ static int smack_unix_stream_connect(struct sock *sock, smk_ad_setfield_u_net_sk(&ad, other); #endif - if (!capable(CAP_MAC_OVERRIDE)) + if (!smack_privileged(CAP_MAC_OVERRIDE)) rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); /* @@ -2820,7 +2817,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) smk_ad_setfield_u_net_sk(&ad, other->sk); #endif - if (!capable(CAP_MAC_OVERRIDE)) + if (!smack_privileged(CAP_MAC_OVERRIDE)) rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); return rc; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 1810c9a4ed48..b1b768e4049a 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -215,28 +215,27 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list, * @access: access string * @rule: Smack rule * @import: if non-zero, import labels + * @len: label length limit * * Returns 0 on success, -1 on failure */ static int smk_fill_rule(const char *subject, const char *object, const char *access, struct smack_rule *rule, - int import) + int import, int len) { - int rc = -1; - int done; const char *cp; struct smack_known *skp; if (import) { - rule->smk_subject = smk_import(subject, 0); + rule->smk_subject = smk_import(subject, len); if (rule->smk_subject == NULL) return -1; - rule->smk_object = smk_import(object, 0); + rule->smk_object = smk_import(object, len); if (rule->smk_object == NULL) return -1; } else { - cp = smk_parse_smack(subject, 0); + cp = smk_parse_smack(subject, len); if (cp == NULL) return -1; skp = smk_find_entry(cp); @@ -245,7 +244,7 @@ static int smk_fill_rule(const char *subject, const char *object, return -1; rule->smk_subject = skp->smk_known; - cp = smk_parse_smack(object, 0); + cp = smk_parse_smack(object, len); if (cp == NULL) return -1; skp = smk_find_entry(cp); @@ -257,7 +256,7 @@ static int smk_fill_rule(const char *subject, const char *object, rule->smk_access = 0; - for (cp = access, done = 0; *cp && !done; cp++) { + for (cp = access; *cp != '\0'; cp++) { switch (*cp) { case '-': break; @@ -282,13 +281,11 @@ static int smk_fill_rule(const char *subject, const char *object, rule->smk_access |= MAY_TRANSMUTE; break; default: - done = 1; - break; + return 0; } } - rc = 0; - return rc; + return 0; } /** @@ -304,7 +301,8 @@ static int smk_parse_rule(const char *data, struct smack_rule *rule, int import) int rc; rc = smk_fill_rule(data, data + SMK_LABELLEN, - data + SMK_LABELLEN + SMK_LABELLEN, rule, import); + data + SMK_LABELLEN + SMK_LABELLEN, rule, import, + SMK_LABELLEN); return rc; } @@ -325,11 +323,11 @@ static int smk_parse_long_rule(const char *data, struct smack_rule *rule, int datalen; int rc = -1; - /* - * This is probably inefficient, but safe. - */ + /* This is inefficient */ datalen = strlen(data); - subject = kzalloc(datalen, GFP_KERNEL); + + /* Our first element can be 64 + \0 with no spaces */ + subject = kzalloc(datalen + 1, GFP_KERNEL); if (subject == NULL) return -1; object = kzalloc(datalen, GFP_KERNEL); @@ -340,7 +338,7 @@ static int smk_parse_long_rule(const char *data, struct smack_rule *rule, goto free_out_o; if (sscanf(data, "%s %s %s", subject, object, access) == 3) - rc = smk_fill_rule(subject, object, access, rule, import); + rc = smk_fill_rule(subject, object, access, rule, import, 0); kfree(access); free_out_o: @@ -520,6 +518,9 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) return; + if (srp->smk_access == 0) + return; + seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); seq_putc(s, ' '); @@ -534,8 +535,6 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) seq_putc(s, 'a'); if (srp->smk_access & MAY_TRANSMUTE) seq_putc(s, 't'); - if (srp->smk_access == 0) - seq_putc(s, '-'); seq_putc(s, '\n'); } @@ -595,13 +594,12 @@ static int smk_open_load(struct inode *inode, struct file *file) static ssize_t smk_write_load(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - /* * Must have privilege. * No partial writes. * Enough data must be present. */ - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, @@ -787,7 +785,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, * No partial writes. * Enough data must be present. */ - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; if (*ppos != 0) return -EINVAL; @@ -1090,7 +1088,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, * "<addr/mask, as a.b.c.d/e><space><label>" * "<addr, as a.b.c.d><space><label>" */ - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; if (*ppos != 0) return -EINVAL; @@ -1267,7 +1265,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf, char temp[80]; int i; - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; if (count >= sizeof(temp) || count == 0) @@ -1334,7 +1332,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf, char temp[80]; int i; - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; if (count >= sizeof(temp) || count == 0) @@ -1412,7 +1410,7 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf, char temp[80]; int i; - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; if (count >= sizeof(temp) || count == 0) @@ -1503,7 +1501,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, char *data; int rc = count; - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; data = kzalloc(count + 1, GFP_KERNEL); @@ -1586,7 +1584,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, char *sp = smk_of_task(current->cred->security); int rc = count; - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; /* @@ -1664,7 +1662,7 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf, char temp[32]; int i; - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; if (count >= sizeof(temp) || count == 0) @@ -1885,7 +1883,7 @@ static ssize_t smk_write_load2(struct file *file, const char __user *buf, /* * Must have privilege. */ - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, @@ -2051,7 +2049,6 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) } root_inode = sb->s_root->d_inode; - root_inode->i_security = new_inode_smack(smack_known_floor.smk_known); return 0; } |