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 | ||
