diff options
| -rw-r--r-- | Documentation/Smack.txt | 42 | ||||
| -rw-r--r-- | security/smack/smack.h | 3 | ||||
| -rw-r--r-- | security/smack/smack_access.c | 3 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 11 | ||||
| -rw-r--r-- | security/smack/smackfs.c | 38 |
5 files changed, 82 insertions, 15 deletions
diff --git a/Documentation/Smack.txt b/Documentation/Smack.txt index 989c2fcd8111..629c92e99783 100644 --- a/Documentation/Smack.txt +++ b/Documentation/Smack.txt | |||
| @@ -184,14 +184,16 @@ length. Single character labels using special characters, that being anything | |||
| 184 | other than a letter or digit, are reserved for use by the Smack development | 184 | other than a letter or digit, are reserved for use by the Smack development |
| 185 | team. Smack labels are unstructured, case sensitive, and the only operation | 185 | team. Smack labels are unstructured, case sensitive, and the only operation |
| 186 | ever performed on them is comparison for equality. Smack labels cannot | 186 | ever performed on them is comparison for equality. Smack labels cannot |
| 187 | contain unprintable characters or the "/" (slash) character. | 187 | contain unprintable characters or the "/" (slash) character. Smack labels |
| 188 | cannot begin with a '-', which is reserved for special options. | ||
| 188 | 189 | ||
| 189 | There are some predefined labels: | 190 | There are some predefined labels: |
| 190 | 191 | ||
| 191 | _ Pronounced "floor", a single underscore character. | 192 | _ Pronounced "floor", a single underscore character. |
| 192 | ^ Pronounced "hat", a single circumflex character. | 193 | ^ Pronounced "hat", a single circumflex character. |
| 193 | * Pronounced "star", a single asterisk character. | 194 | * Pronounced "star", a single asterisk character. |
| 194 | ? Pronounced "huh", a single question mark character. | 195 | ? Pronounced "huh", a single question mark character. |
| 196 | @ Pronounced "Internet", a single at sign character. | ||
| 195 | 197 | ||
| 196 | Every task on a Smack system is assigned a label. System tasks, such as | 198 | Every task on a Smack system is assigned a label. System tasks, such as |
| 197 | init(8) and systems daemons, are run with the floor ("_") label. User tasks | 199 | init(8) and systems daemons, are run with the floor ("_") label. User tasks |
| @@ -412,6 +414,36 @@ sockets. | |||
| 412 | A privileged program may set this to match the label of another | 414 | A privileged program may set this to match the label of another |
| 413 | task with which it hopes to communicate. | 415 | task with which it hopes to communicate. |
| 414 | 416 | ||
| 417 | Smack Netlabel Exceptions | ||
| 418 | |||
| 419 | You will often find that your labeled application has to talk to the outside, | ||
| 420 | unlabeled world. To do this there's a special file /smack/netlabel where you can | ||
| 421 | add some exceptions in the form of : | ||
| 422 | @IP1 LABEL1 or | ||
| 423 | @IP2/MASK LABEL2 | ||
| 424 | |||
| 425 | It means that your application will have unlabeled access to @IP1 if it has | ||
| 426 | write access on LABEL1, and access to the subnet @IP2/MASK if it has write | ||
| 427 | access on LABEL2. | ||
| 428 | |||
| 429 | Entries in the /smack/netlabel file are matched by longest mask first, like in | ||
| 430 | classless IPv4 routing. | ||
| 431 | |||
| 432 | A special label '@' and an option '-CIPSO' can be used there : | ||
| 433 | @ means Internet, any application with any label has access to it | ||
| 434 | -CIPSO means standard CIPSO networking | ||
| 435 | |||
| 436 | If you don't know what CIPSO is and don't plan to use it, you can just do : | ||
| 437 | echo 127.0.0.1 -CIPSO > /smack/netlabel | ||
| 438 | echo 0.0.0.0/0 @ > /smack/netlabel | ||
| 439 | |||
| 440 | If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled | ||
| 441 | Internet access, you can have : | ||
| 442 | echo 127.0.0.1 -CIPSO > /smack/netlabel | ||
| 443 | echo 192.168.0.0/16 -CIPSO > /smack/netlabel | ||
| 444 | echo 0.0.0.0/0 @ > /smack/netlabel | ||
| 445 | |||
| 446 | |||
| 415 | Writing Applications for Smack | 447 | Writing Applications for Smack |
| 416 | 448 | ||
| 417 | There are three sorts of applications that will run on a Smack system. How an | 449 | There are three sorts of applications that will run on a Smack system. How an |
diff --git a/security/smack/smack.h b/security/smack/smack.h index 5e5a3bcb599a..42ef313f9856 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
| @@ -132,6 +132,8 @@ struct smack_known { | |||
| 132 | #define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN | 132 | #define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN |
| 133 | #define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT | 133 | #define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT |
| 134 | 134 | ||
| 135 | #define SMACK_CIPSO_OPTION "-CIPSO" | ||
| 136 | |||
| 135 | /* | 137 | /* |
| 136 | * How communications on this socket are treated. | 138 | * How communications on this socket are treated. |
| 137 | * Usually it's determined by the underlying netlabel code | 139 | * Usually it's determined by the underlying netlabel code |
| @@ -199,6 +201,7 @@ u32 smack_to_secid(const char *); | |||
| 199 | extern int smack_cipso_direct; | 201 | extern int smack_cipso_direct; |
| 200 | extern char *smack_net_ambient; | 202 | extern char *smack_net_ambient; |
| 201 | extern char *smack_onlycap; | 203 | extern char *smack_onlycap; |
| 204 | extern const char *smack_cipso_option; | ||
| 202 | 205 | ||
| 203 | extern struct smack_known smack_known_floor; | 206 | extern struct smack_known smack_known_floor; |
| 204 | extern struct smack_known smack_known_hat; | 207 | extern struct smack_known smack_known_hat; |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 58564195bb09..ac0a2707f6d4 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
| @@ -261,6 +261,9 @@ char *smk_import(const char *string, int len) | |||
| 261 | { | 261 | { |
| 262 | struct smack_known *skp; | 262 | struct smack_known *skp; |
| 263 | 263 | ||
| 264 | /* labels cannot begin with a '-' */ | ||
| 265 | if (string[0] == '-') | ||
| 266 | return NULL; | ||
| 264 | skp = smk_import_entry(string, len); | 267 | skp = smk_import_entry(string, len); |
| 265 | if (skp == NULL) | 268 | if (skp == NULL) |
| 266 | return NULL; | 269 | return NULL; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 8ed502c2ad45..921514902eca 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -609,6 +609,9 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 609 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { | 609 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { |
| 610 | if (!capable(CAP_MAC_ADMIN)) | 610 | if (!capable(CAP_MAC_ADMIN)) |
| 611 | rc = -EPERM; | 611 | rc = -EPERM; |
| 612 | /* a label cannot be void and cannot begin with '-' */ | ||
| 613 | if (size == 0 || (size > 0 && ((char *)value)[0] == '-')) | ||
| 614 | rc = -EINVAL; | ||
| 612 | } else | 615 | } else |
| 613 | rc = cap_inode_setxattr(dentry, name, value, size, flags); | 616 | rc = cap_inode_setxattr(dentry, name, value, size, flags); |
| 614 | 617 | ||
| @@ -1323,8 +1326,12 @@ static char *smack_host_label(struct sockaddr_in *sip) | |||
| 1323 | * so we have found the most specific match | 1326 | * so we have found the most specific match |
| 1324 | */ | 1327 | */ |
| 1325 | if ((&snp->smk_host.sin_addr)->s_addr == | 1328 | if ((&snp->smk_host.sin_addr)->s_addr == |
| 1326 | (siap->s_addr & (&snp->smk_mask)->s_addr)) | 1329 | (siap->s_addr & (&snp->smk_mask)->s_addr)) { |
| 1330 | /* we have found the special CIPSO option */ | ||
| 1331 | if (snp->smk_label == smack_cipso_option) | ||
| 1332 | return NULL; | ||
| 1327 | return snp->smk_label; | 1333 | return snp->smk_label; |
| 1334 | } | ||
| 1328 | 1335 | ||
| 1329 | return NULL; | 1336 | return NULL; |
| 1330 | } | 1337 | } |
| @@ -1486,7 +1493,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
| 1486 | struct socket *sock; | 1493 | struct socket *sock; |
| 1487 | int rc = 0; | 1494 | int rc = 0; |
| 1488 | 1495 | ||
| 1489 | if (value == NULL || size > SMK_LABELLEN) | 1496 | if (value == NULL || size > SMK_LABELLEN || size == 0) |
| 1490 | return -EACCES; | 1497 | return -EACCES; |
| 1491 | 1498 | ||
| 1492 | sp = smk_import(value, size); | 1499 | sp = smk_import(value, size); |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 856c8a287523..e03a7e19c73b 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -86,6 +86,9 @@ LIST_HEAD(smack_rule_list); | |||
| 86 | 86 | ||
| 87 | static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; | 87 | static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; |
| 88 | 88 | ||
| 89 | const char *smack_cipso_option = SMACK_CIPSO_OPTION; | ||
| 90 | |||
| 91 | |||
| 89 | #define SEQ_READ_FINISHED 1 | 92 | #define SEQ_READ_FINISHED 1 |
| 90 | 93 | ||
| 91 | /* | 94 | /* |
| @@ -565,6 +568,11 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf, | |||
| 565 | goto unlockedout; | 568 | goto unlockedout; |
| 566 | } | 569 | } |
| 567 | 570 | ||
| 571 | /* labels cannot begin with a '-' */ | ||
| 572 | if (data[0] == '-') { | ||
| 573 | rc = -EINVAL; | ||
| 574 | goto unlockedout; | ||
| 575 | } | ||
| 568 | data[count] = '\0'; | 576 | data[count] = '\0'; |
| 569 | rule = data; | 577 | rule = data; |
| 570 | /* | 578 | /* |
| @@ -808,9 +816,18 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
| 808 | if (m > BEBITS) | 816 | if (m > BEBITS) |
| 809 | return -EINVAL; | 817 | return -EINVAL; |
| 810 | 818 | ||
| 811 | sp = smk_import(smack, 0); | 819 | /* if smack begins with '-', its an option, don't import it */ |
| 812 | if (sp == NULL) | 820 | if (smack[0] != '-') { |
| 813 | return -EINVAL; | 821 | sp = smk_import(smack, 0); |
| 822 | if (sp == NULL) | ||
| 823 | return -EINVAL; | ||
| 824 | } else { | ||
| 825 | /* check known options */ | ||
| 826 | if (strcmp(smack, smack_cipso_option) == 0) | ||
| 827 | sp = (char *)smack_cipso_option; | ||
| 828 | else | ||
| 829 | return -EINVAL; | ||
| 830 | } | ||
| 814 | 831 | ||
| 815 | for (temp_mask = 0; m > 0; m--) { | 832 | for (temp_mask = 0; m > 0; m--) { |
| 816 | temp_mask |= mask_bits; | 833 | temp_mask |= mask_bits; |
| @@ -849,18 +866,23 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
| 849 | smk_netlbladdr_insert(skp); | 866 | smk_netlbladdr_insert(skp); |
| 850 | } | 867 | } |
| 851 | } else { | 868 | } else { |
| 852 | rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, | 869 | /* we delete the unlabeled entry, only if the previous label |
| 853 | &skp->smk_host.sin_addr, &skp->smk_mask, | 870 | * wasnt the special CIPSO option */ |
| 854 | PF_INET, &audit_info); | 871 | if (skp->smk_label != smack_cipso_option) |
| 872 | rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, | ||
| 873 | &skp->smk_host.sin_addr, &skp->smk_mask, | ||
| 874 | PF_INET, &audit_info); | ||
| 875 | else | ||
| 876 | rc = 0; | ||
| 855 | skp->smk_label = sp; | 877 | skp->smk_label = sp; |
| 856 | } | 878 | } |
| 857 | 879 | ||
| 858 | /* | 880 | /* |
| 859 | * Now tell netlabel about the single label nature of | 881 | * Now tell netlabel about the single label nature of |
| 860 | * this host so that incoming packets get labeled. | 882 | * this host so that incoming packets get labeled. |
| 883 | * but only if we didn't get the special CIPSO option | ||
| 861 | */ | 884 | */ |
| 862 | 885 | if (rc == 0 && sp != smack_cipso_option) | |
| 863 | if (rc == 0) | ||
| 864 | rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, | 886 | rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, |
| 865 | &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET, | 887 | &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET, |
| 866 | smack_to_secid(skp->smk_label), &audit_info); | 888 | smack_to_secid(skp->smk_label), &audit_info); |
