diff options
author | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-02-25 22:26:14 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-02-25 22:26:14 -0500 |
commit | 91e229bbad6524aabaac8717b2f559283670c37a (patch) | |
tree | 84a55e4ac2dcf23add97bd9fde3e9cb232c12b30 /security/smack/smack_lsm.c | |
parent | 6e5e93424dc66542c548dfaa3bfebe30d46d50dd (diff) | |
parent | bfa274e2436fc7ef72ef51c878083647f1cfd429 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 123 |
1 files changed, 102 insertions, 21 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 2b5d6f72f678..770eb067e165 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -584,14 +584,20 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | |||
584 | static int smack_inode_setxattr(struct dentry *dentry, char *name, | 584 | static int smack_inode_setxattr(struct dentry *dentry, char *name, |
585 | void *value, size_t size, int flags) | 585 | void *value, size_t size, int flags) |
586 | { | 586 | { |
587 | if (!capable(CAP_MAC_ADMIN)) { | 587 | int rc = 0; |
588 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || | ||
589 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || | ||
590 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) | ||
591 | return -EPERM; | ||
592 | } | ||
593 | 588 | ||
594 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | 589 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || |
590 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || | ||
591 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { | ||
592 | if (!capable(CAP_MAC_ADMIN)) | ||
593 | rc = -EPERM; | ||
594 | } else | ||
595 | rc = cap_inode_setxattr(dentry, name, value, size, flags); | ||
596 | |||
597 | if (rc == 0) | ||
598 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | ||
599 | |||
600 | return rc; | ||
595 | } | 601 | } |
596 | 602 | ||
597 | /** | 603 | /** |
@@ -658,10 +664,20 @@ static int smack_inode_getxattr(struct dentry *dentry, char *name) | |||
658 | */ | 664 | */ |
659 | static int smack_inode_removexattr(struct dentry *dentry, char *name) | 665 | static int smack_inode_removexattr(struct dentry *dentry, char *name) |
660 | { | 666 | { |
661 | if (strcmp(name, XATTR_NAME_SMACK) == 0 && !capable(CAP_MAC_ADMIN)) | 667 | int rc = 0; |
662 | return -EPERM; | ||
663 | 668 | ||
664 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | 669 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || |
670 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || | ||
671 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { | ||
672 | if (!capable(CAP_MAC_ADMIN)) | ||
673 | rc = -EPERM; | ||
674 | } else | ||
675 | rc = cap_inode_removexattr(dentry, name); | ||
676 | |||
677 | if (rc == 0) | ||
678 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | ||
679 | |||
680 | return rc; | ||
665 | } | 681 | } |
666 | 682 | ||
667 | /** | 683 | /** |
@@ -1016,7 +1032,12 @@ static void smack_task_getsecid(struct task_struct *p, u32 *secid) | |||
1016 | */ | 1032 | */ |
1017 | static int smack_task_setnice(struct task_struct *p, int nice) | 1033 | static int smack_task_setnice(struct task_struct *p, int nice) |
1018 | { | 1034 | { |
1019 | return smk_curacc(p->security, MAY_WRITE); | 1035 | int rc; |
1036 | |||
1037 | rc = cap_task_setnice(p, nice); | ||
1038 | if (rc == 0) | ||
1039 | rc = smk_curacc(p->security, MAY_WRITE); | ||
1040 | return rc; | ||
1020 | } | 1041 | } |
1021 | 1042 | ||
1022 | /** | 1043 | /** |
@@ -1028,7 +1049,12 @@ static int smack_task_setnice(struct task_struct *p, int nice) | |||
1028 | */ | 1049 | */ |
1029 | static int smack_task_setioprio(struct task_struct *p, int ioprio) | 1050 | static int smack_task_setioprio(struct task_struct *p, int ioprio) |
1030 | { | 1051 | { |
1031 | return smk_curacc(p->security, MAY_WRITE); | 1052 | int rc; |
1053 | |||
1054 | rc = cap_task_setioprio(p, ioprio); | ||
1055 | if (rc == 0) | ||
1056 | rc = smk_curacc(p->security, MAY_WRITE); | ||
1057 | return rc; | ||
1032 | } | 1058 | } |
1033 | 1059 | ||
1034 | /** | 1060 | /** |
@@ -1053,7 +1079,12 @@ static int smack_task_getioprio(struct task_struct *p) | |||
1053 | static int smack_task_setscheduler(struct task_struct *p, int policy, | 1079 | static int smack_task_setscheduler(struct task_struct *p, int policy, |
1054 | struct sched_param *lp) | 1080 | struct sched_param *lp) |
1055 | { | 1081 | { |
1056 | return smk_curacc(p->security, MAY_WRITE); | 1082 | int rc; |
1083 | |||
1084 | rc = cap_task_setscheduler(p, policy, lp); | ||
1085 | if (rc == 0) | ||
1086 | rc = smk_curacc(p->security, MAY_WRITE); | ||
1087 | return rc; | ||
1057 | } | 1088 | } |
1058 | 1089 | ||
1059 | /** | 1090 | /** |
@@ -1093,6 +1124,11 @@ static int smack_task_movememory(struct task_struct *p) | |||
1093 | static int smack_task_kill(struct task_struct *p, struct siginfo *info, | 1124 | static int smack_task_kill(struct task_struct *p, struct siginfo *info, |
1094 | int sig, u32 secid) | 1125 | int sig, u32 secid) |
1095 | { | 1126 | { |
1127 | int rc; | ||
1128 | |||
1129 | rc = cap_task_kill(p, info, sig, secid); | ||
1130 | if (rc != 0) | ||
1131 | return rc; | ||
1096 | /* | 1132 | /* |
1097 | * Special cases where signals really ought to go through | 1133 | * Special cases where signals really ought to go through |
1098 | * in spite of policy. Stephen Smalley suggests it may | 1134 | * in spite of policy. Stephen Smalley suggests it may |
@@ -1251,9 +1287,8 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) | |||
1251 | 1287 | ||
1252 | switch (smack_net_nltype) { | 1288 | switch (smack_net_nltype) { |
1253 | case NETLBL_NLTYPE_CIPSOV4: | 1289 | case NETLBL_NLTYPE_CIPSOV4: |
1254 | nlsp->domain = NULL; | 1290 | nlsp->domain = kstrdup(smack, GFP_ATOMIC); |
1255 | nlsp->flags = NETLBL_SECATTR_DOMAIN; | 1291 | nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; |
1256 | nlsp->flags |= NETLBL_SECATTR_MLS_LVL; | ||
1257 | 1292 | ||
1258 | rc = smack_to_cipso(smack, &cipso); | 1293 | rc = smack_to_cipso(smack, &cipso); |
1259 | if (rc == 0) { | 1294 | if (rc == 0) { |
@@ -1282,15 +1317,14 @@ static int smack_netlabel(struct sock *sk) | |||
1282 | { | 1317 | { |
1283 | struct socket_smack *ssp; | 1318 | struct socket_smack *ssp; |
1284 | struct netlbl_lsm_secattr secattr; | 1319 | struct netlbl_lsm_secattr secattr; |
1285 | int rc = 0; | 1320 | int rc; |
1286 | 1321 | ||
1287 | ssp = sk->sk_security; | 1322 | ssp = sk->sk_security; |
1288 | netlbl_secattr_init(&secattr); | 1323 | netlbl_secattr_init(&secattr); |
1289 | smack_to_secattr(ssp->smk_out, &secattr); | 1324 | smack_to_secattr(ssp->smk_out, &secattr); |
1290 | if (secattr.flags != NETLBL_SECATTR_NONE) | 1325 | rc = netlbl_sock_setattr(sk, &secattr); |
1291 | rc = netlbl_sock_setattr(sk, &secattr); | ||
1292 | |||
1293 | netlbl_secattr_destroy(&secattr); | 1326 | netlbl_secattr_destroy(&secattr); |
1327 | |||
1294 | return rc; | 1328 | return rc; |
1295 | } | 1329 | } |
1296 | 1330 | ||
@@ -1313,6 +1347,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
1313 | struct inode_smack *nsp = inode->i_security; | 1347 | struct inode_smack *nsp = inode->i_security; |
1314 | struct socket_smack *ssp; | 1348 | struct socket_smack *ssp; |
1315 | struct socket *sock; | 1349 | struct socket *sock; |
1350 | int rc = 0; | ||
1316 | 1351 | ||
1317 | if (value == NULL || size > SMK_LABELLEN) | 1352 | if (value == NULL || size > SMK_LABELLEN) |
1318 | return -EACCES; | 1353 | return -EACCES; |
@@ -1341,7 +1376,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
1341 | ssp->smk_in = sp; | 1376 | ssp->smk_in = sp; |
1342 | else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { | 1377 | else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { |
1343 | ssp->smk_out = sp; | 1378 | ssp->smk_out = sp; |
1344 | return smack_netlabel(sock->sk); | 1379 | rc = smack_netlabel(sock->sk); |
1380 | if (rc != 0) | ||
1381 | printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", | ||
1382 | __func__, -rc); | ||
1345 | } else | 1383 | } else |
1346 | return -EOPNOTSUPP; | 1384 | return -EOPNOTSUPP; |
1347 | 1385 | ||
@@ -1776,6 +1814,27 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) | |||
1776 | return smk_curacc(isp, may); | 1814 | return smk_curacc(isp, may); |
1777 | } | 1815 | } |
1778 | 1816 | ||
1817 | /* module stacking operations */ | ||
1818 | |||
1819 | /** | ||
1820 | * smack_register_security - stack capability module | ||
1821 | * @name: module name | ||
1822 | * @ops: module operations - ignored | ||
1823 | * | ||
1824 | * Allow the capability module to register. | ||
1825 | */ | ||
1826 | static int smack_register_security(const char *name, | ||
1827 | struct security_operations *ops) | ||
1828 | { | ||
1829 | if (strcmp(name, "capability") != 0) | ||
1830 | return -EINVAL; | ||
1831 | |||
1832 | printk(KERN_INFO "%s: Registering secondary module %s\n", | ||
1833 | __func__, name); | ||
1834 | |||
1835 | return 0; | ||
1836 | } | ||
1837 | |||
1779 | /** | 1838 | /** |
1780 | * smack_d_instantiate - Make sure the blob is correct on an inode | 1839 | * smack_d_instantiate - Make sure the blob is correct on an inode |
1781 | * @opt_dentry: unused | 1840 | * @opt_dentry: unused |
@@ -2214,6 +2273,9 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) | |||
2214 | ssp->smk_packet[0] = '\0'; | 2273 | ssp->smk_packet[0] = '\0'; |
2215 | 2274 | ||
2216 | rc = smack_netlabel(sk); | 2275 | rc = smack_netlabel(sk); |
2276 | if (rc != 0) | ||
2277 | printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", | ||
2278 | __func__, -rc); | ||
2217 | } | 2279 | } |
2218 | 2280 | ||
2219 | /** | 2281 | /** |
@@ -2346,6 +2408,20 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
2346 | } | 2408 | } |
2347 | 2409 | ||
2348 | /* | 2410 | /* |
2411 | * smack_secctx_to_secid - return the secid for a smack label | ||
2412 | * @secdata: smack label | ||
2413 | * @seclen: how long result is | ||
2414 | * @secid: outgoing integer | ||
2415 | * | ||
2416 | * Exists for audit and networking code. | ||
2417 | */ | ||
2418 | static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) | ||
2419 | { | ||
2420 | *secid = smack_to_secid(secdata); | ||
2421 | return 0; | ||
2422 | } | ||
2423 | |||
2424 | /* | ||
2349 | * smack_release_secctx - don't do anything. | 2425 | * smack_release_secctx - don't do anything. |
2350 | * @key_ref: unused | 2426 | * @key_ref: unused |
2351 | * @context: unused | 2427 | * @context: unused |
@@ -2393,6 +2469,8 @@ static struct security_operations smack_ops = { | |||
2393 | .inode_post_setxattr = smack_inode_post_setxattr, | 2469 | .inode_post_setxattr = smack_inode_post_setxattr, |
2394 | .inode_getxattr = smack_inode_getxattr, | 2470 | .inode_getxattr = smack_inode_getxattr, |
2395 | .inode_removexattr = smack_inode_removexattr, | 2471 | .inode_removexattr = smack_inode_removexattr, |
2472 | .inode_need_killpriv = cap_inode_need_killpriv, | ||
2473 | .inode_killpriv = cap_inode_killpriv, | ||
2396 | .inode_getsecurity = smack_inode_getsecurity, | 2474 | .inode_getsecurity = smack_inode_getsecurity, |
2397 | .inode_setsecurity = smack_inode_setsecurity, | 2475 | .inode_setsecurity = smack_inode_setsecurity, |
2398 | .inode_listsecurity = smack_inode_listsecurity, | 2476 | .inode_listsecurity = smack_inode_listsecurity, |
@@ -2452,6 +2530,8 @@ static struct security_operations smack_ops = { | |||
2452 | .netlink_send = cap_netlink_send, | 2530 | .netlink_send = cap_netlink_send, |
2453 | .netlink_recv = cap_netlink_recv, | 2531 | .netlink_recv = cap_netlink_recv, |
2454 | 2532 | ||
2533 | .register_security = smack_register_security, | ||
2534 | |||
2455 | .d_instantiate = smack_d_instantiate, | 2535 | .d_instantiate = smack_d_instantiate, |
2456 | 2536 | ||
2457 | .getprocattr = smack_getprocattr, | 2537 | .getprocattr = smack_getprocattr, |
@@ -2475,6 +2555,7 @@ static struct security_operations smack_ops = { | |||
2475 | .key_permission = smack_key_permission, | 2555 | .key_permission = smack_key_permission, |
2476 | #endif /* CONFIG_KEYS */ | 2556 | #endif /* CONFIG_KEYS */ |
2477 | .secid_to_secctx = smack_secid_to_secctx, | 2557 | .secid_to_secctx = smack_secid_to_secctx, |
2558 | .secctx_to_secid = smack_secctx_to_secid, | ||
2478 | .release_secctx = smack_release_secctx, | 2559 | .release_secctx = smack_release_secctx, |
2479 | }; | 2560 | }; |
2480 | 2561 | ||