diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/smack/smack_lsm.c | 36 | ||||
| -rw-r--r-- | security/smack/smackfs.c | 61 |
2 files changed, 74 insertions, 23 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 2b5d6f72f678..25cbfa3f71f4 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -1251,9 +1251,8 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) | |||
| 1251 | 1251 | ||
| 1252 | switch (smack_net_nltype) { | 1252 | switch (smack_net_nltype) { |
| 1253 | case NETLBL_NLTYPE_CIPSOV4: | 1253 | case NETLBL_NLTYPE_CIPSOV4: |
| 1254 | nlsp->domain = NULL; | 1254 | nlsp->domain = kstrdup(smack, GFP_ATOMIC); |
| 1255 | nlsp->flags = NETLBL_SECATTR_DOMAIN; | 1255 | nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; |
| 1256 | nlsp->flags |= NETLBL_SECATTR_MLS_LVL; | ||
| 1257 | 1256 | ||
| 1258 | rc = smack_to_cipso(smack, &cipso); | 1257 | rc = smack_to_cipso(smack, &cipso); |
| 1259 | if (rc == 0) { | 1258 | if (rc == 0) { |
| @@ -1282,15 +1281,14 @@ static int smack_netlabel(struct sock *sk) | |||
| 1282 | { | 1281 | { |
| 1283 | struct socket_smack *ssp; | 1282 | struct socket_smack *ssp; |
| 1284 | struct netlbl_lsm_secattr secattr; | 1283 | struct netlbl_lsm_secattr secattr; |
| 1285 | int rc = 0; | 1284 | int rc; |
| 1286 | 1285 | ||
| 1287 | ssp = sk->sk_security; | 1286 | ssp = sk->sk_security; |
| 1288 | netlbl_secattr_init(&secattr); | 1287 | netlbl_secattr_init(&secattr); |
| 1289 | smack_to_secattr(ssp->smk_out, &secattr); | 1288 | smack_to_secattr(ssp->smk_out, &secattr); |
| 1290 | if (secattr.flags != NETLBL_SECATTR_NONE) | 1289 | rc = netlbl_sock_setattr(sk, &secattr); |
| 1291 | rc = netlbl_sock_setattr(sk, &secattr); | ||
| 1292 | |||
| 1293 | netlbl_secattr_destroy(&secattr); | 1290 | netlbl_secattr_destroy(&secattr); |
| 1291 | |||
| 1294 | return rc; | 1292 | return rc; |
| 1295 | } | 1293 | } |
| 1296 | 1294 | ||
| @@ -1313,6 +1311,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
| 1313 | struct inode_smack *nsp = inode->i_security; | 1311 | struct inode_smack *nsp = inode->i_security; |
| 1314 | struct socket_smack *ssp; | 1312 | struct socket_smack *ssp; |
| 1315 | struct socket *sock; | 1313 | struct socket *sock; |
| 1314 | int rc = 0; | ||
| 1316 | 1315 | ||
| 1317 | if (value == NULL || size > SMK_LABELLEN) | 1316 | if (value == NULL || size > SMK_LABELLEN) |
| 1318 | return -EACCES; | 1317 | return -EACCES; |
| @@ -1341,7 +1340,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
| 1341 | ssp->smk_in = sp; | 1340 | ssp->smk_in = sp; |
| 1342 | else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { | 1341 | else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { |
| 1343 | ssp->smk_out = sp; | 1342 | ssp->smk_out = sp; |
| 1344 | return smack_netlabel(sock->sk); | 1343 | rc = smack_netlabel(sock->sk); |
| 1344 | if (rc != 0) | ||
| 1345 | printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", | ||
| 1346 | __func__, -rc); | ||
| 1345 | } else | 1347 | } else |
| 1346 | return -EOPNOTSUPP; | 1348 | return -EOPNOTSUPP; |
| 1347 | 1349 | ||
| @@ -2214,6 +2216,9 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) | |||
| 2214 | ssp->smk_packet[0] = '\0'; | 2216 | ssp->smk_packet[0] = '\0'; |
| 2215 | 2217 | ||
| 2216 | rc = smack_netlabel(sk); | 2218 | rc = smack_netlabel(sk); |
| 2219 | if (rc != 0) | ||
| 2220 | printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", | ||
| 2221 | __func__, -rc); | ||
| 2217 | } | 2222 | } |
| 2218 | 2223 | ||
| 2219 | /** | 2224 | /** |
| @@ -2346,6 +2351,20 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
| 2346 | } | 2351 | } |
| 2347 | 2352 | ||
| 2348 | /* | 2353 | /* |
| 2354 | * smack_secctx_to_secid - return the secid for a smack label | ||
| 2355 | * @secdata: smack label | ||
| 2356 | * @seclen: how long result is | ||
| 2357 | * @secid: outgoing integer | ||
| 2358 | * | ||
| 2359 | * Exists for audit and networking code. | ||
| 2360 | */ | ||
| 2361 | static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) | ||
| 2362 | { | ||
| 2363 | *secid = smack_to_secid(secdata); | ||
| 2364 | return 0; | ||
| 2365 | } | ||
| 2366 | |||
| 2367 | /* | ||
| 2349 | * smack_release_secctx - don't do anything. | 2368 | * smack_release_secctx - don't do anything. |
| 2350 | * @key_ref: unused | 2369 | * @key_ref: unused |
| 2351 | * @context: unused | 2370 | * @context: unused |
| @@ -2475,6 +2494,7 @@ static struct security_operations smack_ops = { | |||
| 2475 | .key_permission = smack_key_permission, | 2494 | .key_permission = smack_key_permission, |
| 2476 | #endif /* CONFIG_KEYS */ | 2495 | #endif /* CONFIG_KEYS */ |
| 2477 | .secid_to_secctx = smack_secid_to_secctx, | 2496 | .secid_to_secctx = smack_secid_to_secctx, |
| 2497 | .secctx_to_secid = smack_secctx_to_secid, | ||
| 2478 | .release_secctx = smack_release_secctx, | 2498 | .release_secctx = smack_release_secctx, |
| 2479 | }; | 2499 | }; |
| 2480 | 2500 | ||
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 15aa37f65b39..358c92c1a153 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <net/cipso_ipv4.h> | 24 | #include <net/cipso_ipv4.h> |
| 25 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
| 26 | #include <linux/ctype.h> | 26 | #include <linux/ctype.h> |
| 27 | #include <linux/audit.h> | ||
| 27 | #include "smack.h" | 28 | #include "smack.h" |
| 28 | 29 | ||
| 29 | /* | 30 | /* |
| @@ -45,6 +46,7 @@ enum smk_inos { | |||
| 45 | */ | 46 | */ |
| 46 | static DEFINE_MUTEX(smack_list_lock); | 47 | static DEFINE_MUTEX(smack_list_lock); |
| 47 | static DEFINE_MUTEX(smack_cipso_lock); | 48 | static DEFINE_MUTEX(smack_cipso_lock); |
| 49 | static DEFINE_MUTEX(smack_ambient_lock); | ||
| 48 | 50 | ||
| 49 | /* | 51 | /* |
| 50 | * This is the "ambient" label for network traffic. | 52 | * This is the "ambient" label for network traffic. |
| @@ -342,6 +344,9 @@ void smk_cipso_doi(void) | |||
| 342 | struct cipso_v4_doi *doip; | 344 | struct cipso_v4_doi *doip; |
| 343 | struct netlbl_audit audit_info; | 345 | struct netlbl_audit audit_info; |
| 344 | 346 | ||
| 347 | audit_info.loginuid = audit_get_loginuid(current); | ||
| 348 | audit_info.secid = smack_to_secid(current->security); | ||
| 349 | |||
| 345 | rc = netlbl_cfg_map_del(NULL, &audit_info); | 350 | rc = netlbl_cfg_map_del(NULL, &audit_info); |
| 346 | if (rc != 0) | 351 | if (rc != 0) |
| 347 | printk(KERN_WARNING "%s:%d remove rc = %d\n", | 352 | printk(KERN_WARNING "%s:%d remove rc = %d\n", |
| @@ -363,6 +368,30 @@ void smk_cipso_doi(void) | |||
| 363 | __func__, __LINE__, rc); | 368 | __func__, __LINE__, rc); |
| 364 | } | 369 | } |
| 365 | 370 | ||
| 371 | /** | ||
| 372 | * smk_unlbl_ambient - initialize the unlabeled domain | ||
| 373 | */ | ||
| 374 | void smk_unlbl_ambient(char *oldambient) | ||
| 375 | { | ||
| 376 | int rc; | ||
| 377 | struct netlbl_audit audit_info; | ||
| 378 | |||
| 379 | audit_info.loginuid = audit_get_loginuid(current); | ||
| 380 | audit_info.secid = smack_to_secid(current->security); | ||
| 381 | |||
| 382 | if (oldambient != NULL) { | ||
| 383 | rc = netlbl_cfg_map_del(oldambient, &audit_info); | ||
| 384 | if (rc != 0) | ||
| 385 | printk(KERN_WARNING "%s:%d remove rc = %d\n", | ||
| 386 | __func__, __LINE__, rc); | ||
| 387 | } | ||
| 388 | |||
| 389 | rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info); | ||
| 390 | if (rc != 0) | ||
| 391 | printk(KERN_WARNING "%s:%d add rc = %d\n", | ||
| 392 | __func__, __LINE__, rc); | ||
| 393 | } | ||
| 394 | |||
| 366 | /* | 395 | /* |
| 367 | * Seq_file read operations for /smack/cipso | 396 | * Seq_file read operations for /smack/cipso |
| 368 | */ | 397 | */ |
| @@ -709,7 +738,6 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, | |||
| 709 | size_t cn, loff_t *ppos) | 738 | size_t cn, loff_t *ppos) |
| 710 | { | 739 | { |
| 711 | ssize_t rc; | 740 | ssize_t rc; |
| 712 | char out[SMK_LABELLEN]; | ||
| 713 | int asize; | 741 | int asize; |
| 714 | 742 | ||
| 715 | if (*ppos != 0) | 743 | if (*ppos != 0) |
| @@ -717,23 +745,18 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, | |||
| 717 | /* | 745 | /* |
| 718 | * Being careful to avoid a problem in the case where | 746 | * Being careful to avoid a problem in the case where |
| 719 | * smack_net_ambient gets changed in midstream. | 747 | * smack_net_ambient gets changed in midstream. |
| 720 | * Since smack_net_ambient is always set with a value | ||
| 721 | * from the label list, including initially, and those | ||
| 722 | * never get freed, the worst case is that the pointer | ||
| 723 | * gets changed just after this strncpy, in which case | ||
| 724 | * the value passed up is incorrect. Locking around | ||
| 725 | * smack_net_ambient wouldn't be any better than this | ||
| 726 | * copy scheme as by the time the caller got to look | ||
| 727 | * at the ambient value it would have cleared the lock | ||
| 728 | * and been changed. | ||
| 729 | */ | 748 | */ |
| 730 | strncpy(out, smack_net_ambient, SMK_LABELLEN); | 749 | mutex_lock(&smack_ambient_lock); |
| 731 | asize = strlen(out) + 1; | ||
| 732 | 750 | ||
| 733 | if (cn < asize) | 751 | asize = strlen(smack_net_ambient) + 1; |
| 734 | return -EINVAL; | 752 | |
| 753 | if (cn >= asize) | ||
| 754 | rc = simple_read_from_buffer(buf, cn, ppos, | ||
| 755 | smack_net_ambient, asize); | ||
| 756 | else | ||
| 757 | rc = -EINVAL; | ||
| 735 | 758 | ||
| 736 | rc = simple_read_from_buffer(buf, cn, ppos, out, asize); | 759 | mutex_unlock(&smack_ambient_lock); |
| 737 | 760 | ||
| 738 | return rc; | 761 | return rc; |
| 739 | } | 762 | } |
| @@ -751,6 +774,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, | |||
| 751 | size_t count, loff_t *ppos) | 774 | size_t count, loff_t *ppos) |
| 752 | { | 775 | { |
| 753 | char in[SMK_LABELLEN]; | 776 | char in[SMK_LABELLEN]; |
| 777 | char *oldambient; | ||
| 754 | char *smack; | 778 | char *smack; |
| 755 | 779 | ||
| 756 | if (!capable(CAP_MAC_ADMIN)) | 780 | if (!capable(CAP_MAC_ADMIN)) |
| @@ -766,7 +790,13 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, | |||
| 766 | if (smack == NULL) | 790 | if (smack == NULL) |
| 767 | return -EINVAL; | 791 | return -EINVAL; |
| 768 | 792 | ||
| 793 | mutex_lock(&smack_ambient_lock); | ||
| 794 | |||
| 795 | oldambient = smack_net_ambient; | ||
| 769 | smack_net_ambient = smack; | 796 | smack_net_ambient = smack; |
| 797 | smk_unlbl_ambient(oldambient); | ||
| 798 | |||
| 799 | mutex_unlock(&smack_ambient_lock); | ||
| 770 | 800 | ||
| 771 | return count; | 801 | return count; |
| 772 | } | 802 | } |
| @@ -974,6 +1004,7 @@ static int __init init_smk_fs(void) | |||
| 974 | 1004 | ||
| 975 | sema_init(&smack_write_sem, 1); | 1005 | sema_init(&smack_write_sem, 1); |
| 976 | smk_cipso_doi(); | 1006 | smk_cipso_doi(); |
| 1007 | smk_unlbl_ambient(NULL); | ||
| 977 | 1008 | ||
| 978 | return err; | 1009 | return err; |
| 979 | } | 1010 | } |
