diff options
author | Casey Schaufler <casey@schaufler-ca.com> | 2012-06-05 18:28:30 -0400 |
---|---|---|
committer | Casey Schaufler <casey@schaufler-ca.com> | 2012-07-13 18:49:23 -0400 |
commit | 1880eff77e7a7cb46c68fae7cfa33f72f0a6e70e (patch) | |
tree | fc4b9a2ca7c643a30cbe2260886fdbd969bf2b50 | |
parent | eb982cb4cf6405b97ea1f9e1d10864981f269d46 (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.h | 13 | ||||
-rw-r--r-- | security/smack/smack_access.c | 9 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 17 | ||||
-rw-r--r-- | security/smack/smackfs.c | 21 |
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 | */ | ||
289 | static 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 | ||
233 | out_audit: | 228 | out_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) | |||
595 | static ssize_t smk_write_load(struct file *file, const char __user *buf, | 595 | static 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, |