aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2012-06-05 18:28:30 -0400
committerCasey Schaufler <casey@schaufler-ca.com>2012-07-13 18:49:23 -0400
commit1880eff77e7a7cb46c68fae7cfa33f72f0a6e70e (patch)
treefc4b9a2ca7c643a30cbe2260886fdbd969bf2b50
parenteb982cb4cf6405b97ea1f9e1d10864981f269d46 (diff)
Smack: onlycap limits on CAP_MAC_ADMIN
Smack is integrated with the POSIX capabilities scheme, using the capabilities CAP_MAC_OVERRIDE and CAP_MAC_ADMIN to determine if a process is allowed to ignore Smack checks or change Smack related data respectively. Smack provides an additional restriction that if an onlycap value is set by writing to /smack/onlycap only tasks with that Smack label are allowed to use CAP_MAC_OVERRIDE. This change adds CAP_MAC_ADMIN as a capability that is affected by the onlycap mechanism. Targeted for git://git.gitorious.org/smack-next/kernel.git Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
-rw-r--r--security/smack/smack.h13
-rw-r--r--security/smack/smack_access.c9
-rw-r--r--security/smack/smack_lsm.c17
-rw-r--r--security/smack/smackfs.c21
4 files changed, 34 insertions, 26 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 76feb31eb823..99b36124f712 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -283,6 +283,19 @@ static inline char *smk_of_current(void)
283} 283}
284 284
285/* 285/*
286 * Is the task privileged and allowed to be privileged
287 * by the onlycap rule.
288 */
289static inline int smack_privileged(int cap)
290{
291 if (!capable(cap))
292 return 0;
293 if (smack_onlycap == NULL || smack_onlycap == smk_of_current())
294 return 1;
295 return 0;
296}
297
298/*
286 * logging functions 299 * logging functions
287 */ 300 */
288#define SMACK_AUDIT_DENIED 0x1 301#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)
220 } 220 }
221 221
222 /* 222 /*
223 * Return if a specific label has been designated as the 223 * Allow for priviliged to override policy.
224 * only one that gets privilege and current does not
225 * have that label.
226 */ 224 */
227 if (smack_onlycap != NULL && smack_onlycap != sp) 225 if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE))
228 goto out_audit;
229
230 if (capable(CAP_MAC_OVERRIDE))
231 rc = 0; 226 rc = 0;
232 227
233out_audit: 228out_audit:
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 29bb4e7fa5e8..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)
217 int rc = 0; 217 int rc = 0;
218 char *sp = smk_of_current(); 218 char *sp = smk_of_current();
219 219
220 if (capable(CAP_MAC_OVERRIDE)) 220 if (smack_privileged(CAP_MAC_OVERRIDE))
221 return 0; 221 return 0;
222 222
223 if (sp != smack_known_floor.smk_known) 223 if (sp != smack_known_floor.smk_known)
@@ -821,7 +821,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
821 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || 821 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
822 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 822 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
823 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 823 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
824 if (!capable(CAP_MAC_ADMIN)) 824 if (!smack_privileged(CAP_MAC_ADMIN))
825 rc = -EPERM; 825 rc = -EPERM;
826 /* 826 /*
827 * check label validity here so import wont fail on 827 * check label validity here so import wont fail on
@@ -831,7 +831,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
831 smk_import(value, size) == NULL) 831 smk_import(value, size) == NULL)
832 rc = -EINVAL; 832 rc = -EINVAL;
833 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { 833 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
834 if (!capable(CAP_MAC_ADMIN)) 834 if (!smack_privileged(CAP_MAC_ADMIN))
835 rc = -EPERM; 835 rc = -EPERM;
836 if (size != TRANS_TRUE_SIZE || 836 if (size != TRANS_TRUE_SIZE ||
837 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) 837 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
@@ -927,7 +927,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
927 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 927 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
928 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || 928 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
929 strcmp(name, XATTR_NAME_SMACKMMAP)) { 929 strcmp(name, XATTR_NAME_SMACKMMAP)) {
930 if (!capable(CAP_MAC_ADMIN)) 930 if (!smack_privileged(CAP_MAC_ADMIN))
931 rc = -EPERM; 931 rc = -EPERM;
932 } else 932 } else
933 rc = cap_inode_removexattr(dentry, name); 933 rc = cap_inode_removexattr(dentry, name);
@@ -1716,7 +1716,8 @@ static int smack_task_wait(struct task_struct *p)
1716 * state into account in the decision as well as 1716 * state into account in the decision as well as
1717 * the smack value. 1717 * the smack value.
1718 */ 1718 */
1719 if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) 1719 if (smack_privileged(CAP_MAC_OVERRIDE) ||
1720 has_capability(p, CAP_MAC_OVERRIDE))
1720 rc = 0; 1721 rc = 0;
1721 /* we log only if we didn't get overriden */ 1722 /* we log only if we didn't get overriden */
1722 out_log: 1723 out_log:
@@ -2717,7 +2718,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2717 if (p != current) 2718 if (p != current)
2718 return -EPERM; 2719 return -EPERM;
2719 2720
2720 if (!capable(CAP_MAC_ADMIN)) 2721 if (!smack_privileged(CAP_MAC_ADMIN))
2721 return -EPERM; 2722 return -EPERM;
2722 2723
2723 if (value == NULL || size == 0 || size >= SMK_LONGLABEL) 2724 if (value == NULL || size == 0 || size >= SMK_LONGLABEL)
@@ -2780,7 +2781,7 @@ static int smack_unix_stream_connect(struct sock *sock,
2780 smk_ad_setfield_u_net_sk(&ad, other); 2781 smk_ad_setfield_u_net_sk(&ad, other);
2781#endif 2782#endif
2782 2783
2783 if (!capable(CAP_MAC_OVERRIDE)) 2784 if (!smack_privileged(CAP_MAC_OVERRIDE))
2784 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2785 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2785 2786
2786 /* 2787 /*
@@ -2816,7 +2817,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2816 smk_ad_setfield_u_net_sk(&ad, other->sk); 2817 smk_ad_setfield_u_net_sk(&ad, other->sk);
2817#endif 2818#endif
2818 2819
2819 if (!capable(CAP_MAC_OVERRIDE)) 2820 if (!smack_privileged(CAP_MAC_OVERRIDE))
2820 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2821 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2821 2822
2822 return rc; 2823 return rc;
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 3686db7e2c6b..21529658662b 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -595,13 +595,12 @@ static int smk_open_load(struct inode *inode, struct file *file)
595static ssize_t smk_write_load(struct file *file, const char __user *buf, 595static ssize_t smk_write_load(struct file *file, const char __user *buf,
596 size_t count, loff_t *ppos) 596 size_t count, loff_t *ppos)
597{ 597{
598
599 /* 598 /*
600 * Must have privilege. 599 * Must have privilege.
601 * No partial writes. 600 * No partial writes.
602 * Enough data must be present. 601 * Enough data must be present.
603 */ 602 */
604 if (!capable(CAP_MAC_ADMIN)) 603 if (!smack_privileged(CAP_MAC_ADMIN))
605 return -EPERM; 604 return -EPERM;
606 605
607 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, 606 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
@@ -787,7 +786,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
787 * No partial writes. 786 * No partial writes.
788 * Enough data must be present. 787 * Enough data must be present.
789 */ 788 */
790 if (!capable(CAP_MAC_ADMIN)) 789 if (!smack_privileged(CAP_MAC_ADMIN))
791 return -EPERM; 790 return -EPERM;
792 if (*ppos != 0) 791 if (*ppos != 0)
793 return -EINVAL; 792 return -EINVAL;
@@ -1090,7 +1089,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1090 * "<addr/mask, as a.b.c.d/e><space><label>" 1089 * "<addr/mask, as a.b.c.d/e><space><label>"
1091 * "<addr, as a.b.c.d><space><label>" 1090 * "<addr, as a.b.c.d><space><label>"
1092 */ 1091 */
1093 if (!capable(CAP_MAC_ADMIN)) 1092 if (!smack_privileged(CAP_MAC_ADMIN))
1094 return -EPERM; 1093 return -EPERM;
1095 if (*ppos != 0) 1094 if (*ppos != 0)
1096 return -EINVAL; 1095 return -EINVAL;
@@ -1267,7 +1266,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,
1267 char temp[80]; 1266 char temp[80];
1268 int i; 1267 int i;
1269 1268
1270 if (!capable(CAP_MAC_ADMIN)) 1269 if (!smack_privileged(CAP_MAC_ADMIN))
1271 return -EPERM; 1270 return -EPERM;
1272 1271
1273 if (count >= sizeof(temp) || count == 0) 1272 if (count >= sizeof(temp) || count == 0)
@@ -1334,7 +1333,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1334 char temp[80]; 1333 char temp[80];
1335 int i; 1334 int i;
1336 1335
1337 if (!capable(CAP_MAC_ADMIN)) 1336 if (!smack_privileged(CAP_MAC_ADMIN))
1338 return -EPERM; 1337 return -EPERM;
1339 1338
1340 if (count >= sizeof(temp) || count == 0) 1339 if (count >= sizeof(temp) || count == 0)
@@ -1412,7 +1411,7 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf,
1412 char temp[80]; 1411 char temp[80];
1413 int i; 1412 int i;
1414 1413
1415 if (!capable(CAP_MAC_ADMIN)) 1414 if (!smack_privileged(CAP_MAC_ADMIN))
1416 return -EPERM; 1415 return -EPERM;
1417 1416
1418 if (count >= sizeof(temp) || count == 0) 1417 if (count >= sizeof(temp) || count == 0)
@@ -1503,7 +1502,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1503 char *data; 1502 char *data;
1504 int rc = count; 1503 int rc = count;
1505 1504
1506 if (!capable(CAP_MAC_ADMIN)) 1505 if (!smack_privileged(CAP_MAC_ADMIN))
1507 return -EPERM; 1506 return -EPERM;
1508 1507
1509 data = kzalloc(count + 1, GFP_KERNEL); 1508 data = kzalloc(count + 1, GFP_KERNEL);
@@ -1586,7 +1585,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1586 char *sp = smk_of_task(current->cred->security); 1585 char *sp = smk_of_task(current->cred->security);
1587 int rc = count; 1586 int rc = count;
1588 1587
1589 if (!capable(CAP_MAC_ADMIN)) 1588 if (!smack_privileged(CAP_MAC_ADMIN))
1590 return -EPERM; 1589 return -EPERM;
1591 1590
1592 /* 1591 /*
@@ -1664,7 +1663,7 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf,
1664 char temp[32]; 1663 char temp[32];
1665 int i; 1664 int i;
1666 1665
1667 if (!capable(CAP_MAC_ADMIN)) 1666 if (!smack_privileged(CAP_MAC_ADMIN))
1668 return -EPERM; 1667 return -EPERM;
1669 1668
1670 if (count >= sizeof(temp) || count == 0) 1669 if (count >= sizeof(temp) || count == 0)
@@ -1885,7 +1884,7 @@ static ssize_t smk_write_load2(struct file *file, const char __user *buf,
1885 /* 1884 /*
1886 * Must have privilege. 1885 * Must have privilege.
1887 */ 1886 */
1888 if (!capable(CAP_MAC_ADMIN)) 1887 if (!smack_privileged(CAP_MAC_ADMIN))
1889 return -EPERM; 1888 return -EPERM;
1890 1889
1891 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, 1890 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,