diff options
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r-- | security/smack/smackfs.c | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 3c720ff10591..bce4e8f1b267 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -131,14 +131,17 @@ LIST_HEAD(smack_rule_list); | |||
131 | 131 | ||
132 | struct smack_parsed_rule { | 132 | struct smack_parsed_rule { |
133 | struct smack_known *smk_subject; | 133 | struct smack_known *smk_subject; |
134 | char *smk_object; | 134 | struct smack_known *smk_object; |
135 | int smk_access1; | 135 | int smk_access1; |
136 | int smk_access2; | 136 | int smk_access2; |
137 | }; | 137 | }; |
138 | 138 | ||
139 | static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; | 139 | static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; |
140 | 140 | ||
141 | const char *smack_cipso_option = SMACK_CIPSO_OPTION; | 141 | struct smack_known smack_cipso_option = { |
142 | .smk_known = SMACK_CIPSO_OPTION, | ||
143 | .smk_secid = 0, | ||
144 | }; | ||
142 | 145 | ||
143 | /* | 146 | /* |
144 | * Values for parsing cipso rules | 147 | * Values for parsing cipso rules |
@@ -304,6 +307,10 @@ static int smk_perm_from_str(const char *string) | |||
304 | case 'L': | 307 | case 'L': |
305 | perm |= MAY_LOCK; | 308 | perm |= MAY_LOCK; |
306 | break; | 309 | break; |
310 | case 'b': | ||
311 | case 'B': | ||
312 | perm |= MAY_BRINGUP; | ||
313 | break; | ||
307 | default: | 314 | default: |
308 | return perm; | 315 | return perm; |
309 | } | 316 | } |
@@ -335,7 +342,7 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
335 | if (rule->smk_subject == NULL) | 342 | if (rule->smk_subject == NULL) |
336 | return -EINVAL; | 343 | return -EINVAL; |
337 | 344 | ||
338 | rule->smk_object = smk_import(object, len); | 345 | rule->smk_object = smk_import_entry(object, len); |
339 | if (rule->smk_object == NULL) | 346 | if (rule->smk_object == NULL) |
340 | return -EINVAL; | 347 | return -EINVAL; |
341 | } else { | 348 | } else { |
@@ -355,7 +362,7 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
355 | kfree(cp); | 362 | kfree(cp); |
356 | if (skp == NULL) | 363 | if (skp == NULL) |
357 | return -ENOENT; | 364 | return -ENOENT; |
358 | rule->smk_object = skp->smk_known; | 365 | rule->smk_object = skp; |
359 | } | 366 | } |
360 | 367 | ||
361 | rule->smk_access1 = smk_perm_from_str(access1); | 368 | rule->smk_access1 = smk_perm_from_str(access1); |
@@ -594,13 +601,15 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) | |||
594 | * anything you read back. | 601 | * anything you read back. |
595 | */ | 602 | */ |
596 | if (strlen(srp->smk_subject->smk_known) >= max || | 603 | if (strlen(srp->smk_subject->smk_known) >= max || |
597 | strlen(srp->smk_object) >= max) | 604 | strlen(srp->smk_object->smk_known) >= max) |
598 | return; | 605 | return; |
599 | 606 | ||
600 | if (srp->smk_access == 0) | 607 | if (srp->smk_access == 0) |
601 | return; | 608 | return; |
602 | 609 | ||
603 | seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object); | 610 | seq_printf(s, "%s %s", |
611 | srp->smk_subject->smk_known, | ||
612 | srp->smk_object->smk_known); | ||
604 | 613 | ||
605 | seq_putc(s, ' '); | 614 | seq_putc(s, ' '); |
606 | 615 | ||
@@ -616,6 +625,8 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) | |||
616 | seq_putc(s, 't'); | 625 | seq_putc(s, 't'); |
617 | if (srp->smk_access & MAY_LOCK) | 626 | if (srp->smk_access & MAY_LOCK) |
618 | seq_putc(s, 'l'); | 627 | seq_putc(s, 'l'); |
628 | if (srp->smk_access & MAY_BRINGUP) | ||
629 | seq_putc(s, 'b'); | ||
619 | 630 | ||
620 | seq_putc(s, '\n'); | 631 | seq_putc(s, '\n'); |
621 | } | 632 | } |
@@ -1067,7 +1078,7 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v) | |||
1067 | for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++); | 1078 | for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++); |
1068 | 1079 | ||
1069 | seq_printf(s, "%u.%u.%u.%u/%d %s\n", | 1080 | seq_printf(s, "%u.%u.%u.%u/%d %s\n", |
1070 | hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label); | 1081 | hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label->smk_known); |
1071 | 1082 | ||
1072 | return 0; | 1083 | return 0; |
1073 | } | 1084 | } |
@@ -1147,10 +1158,10 @@ static void smk_netlbladdr_insert(struct smk_netlbladdr *new) | |||
1147 | static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | 1158 | static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, |
1148 | size_t count, loff_t *ppos) | 1159 | size_t count, loff_t *ppos) |
1149 | { | 1160 | { |
1150 | struct smk_netlbladdr *skp; | 1161 | struct smk_netlbladdr *snp; |
1151 | struct sockaddr_in newname; | 1162 | struct sockaddr_in newname; |
1152 | char *smack; | 1163 | char *smack; |
1153 | char *sp; | 1164 | struct smack_known *skp; |
1154 | char *data; | 1165 | char *data; |
1155 | char *host = (char *)&newname.sin_addr.s_addr; | 1166 | char *host = (char *)&newname.sin_addr.s_addr; |
1156 | int rc; | 1167 | int rc; |
@@ -1213,15 +1224,15 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
1213 | * If smack begins with '-', it is an option, don't import it | 1224 | * If smack begins with '-', it is an option, don't import it |
1214 | */ | 1225 | */ |
1215 | if (smack[0] != '-') { | 1226 | if (smack[0] != '-') { |
1216 | sp = smk_import(smack, 0); | 1227 | skp = smk_import_entry(smack, 0); |
1217 | if (sp == NULL) { | 1228 | if (skp == NULL) { |
1218 | rc = -EINVAL; | 1229 | rc = -EINVAL; |
1219 | goto free_out; | 1230 | goto free_out; |
1220 | } | 1231 | } |
1221 | } else { | 1232 | } else { |
1222 | /* check known options */ | 1233 | /* check known options */ |
1223 | if (strcmp(smack, smack_cipso_option) == 0) | 1234 | if (strcmp(smack, smack_cipso_option.smk_known) == 0) |
1224 | sp = (char *)smack_cipso_option; | 1235 | skp = &smack_cipso_option; |
1225 | else { | 1236 | else { |
1226 | rc = -EINVAL; | 1237 | rc = -EINVAL; |
1227 | goto free_out; | 1238 | goto free_out; |
@@ -1244,9 +1255,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
1244 | nsa = newname.sin_addr.s_addr; | 1255 | nsa = newname.sin_addr.s_addr; |
1245 | /* try to find if the prefix is already in the list */ | 1256 | /* try to find if the prefix is already in the list */ |
1246 | found = 0; | 1257 | found = 0; |
1247 | list_for_each_entry_rcu(skp, &smk_netlbladdr_list, list) { | 1258 | list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list) { |
1248 | if (skp->smk_host.sin_addr.s_addr == nsa && | 1259 | if (snp->smk_host.sin_addr.s_addr == nsa && |
1249 | skp->smk_mask.s_addr == mask.s_addr) { | 1260 | snp->smk_mask.s_addr == mask.s_addr) { |
1250 | found = 1; | 1261 | found = 1; |
1251 | break; | 1262 | break; |
1252 | } | 1263 | } |
@@ -1254,26 +1265,26 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
1254 | smk_netlabel_audit_set(&audit_info); | 1265 | smk_netlabel_audit_set(&audit_info); |
1255 | 1266 | ||
1256 | if (found == 0) { | 1267 | if (found == 0) { |
1257 | skp = kzalloc(sizeof(*skp), GFP_KERNEL); | 1268 | snp = kzalloc(sizeof(*snp), GFP_KERNEL); |
1258 | if (skp == NULL) | 1269 | if (snp == NULL) |
1259 | rc = -ENOMEM; | 1270 | rc = -ENOMEM; |
1260 | else { | 1271 | else { |
1261 | rc = 0; | 1272 | rc = 0; |
1262 | skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; | 1273 | snp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; |
1263 | skp->smk_mask.s_addr = mask.s_addr; | 1274 | snp->smk_mask.s_addr = mask.s_addr; |
1264 | skp->smk_label = sp; | 1275 | snp->smk_label = skp; |
1265 | smk_netlbladdr_insert(skp); | 1276 | smk_netlbladdr_insert(snp); |
1266 | } | 1277 | } |
1267 | } else { | 1278 | } else { |
1268 | /* we delete the unlabeled entry, only if the previous label | 1279 | /* we delete the unlabeled entry, only if the previous label |
1269 | * wasn't the special CIPSO option */ | 1280 | * wasn't the special CIPSO option */ |
1270 | if (skp->smk_label != smack_cipso_option) | 1281 | if (snp->smk_label != &smack_cipso_option) |
1271 | rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, | 1282 | rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, |
1272 | &skp->smk_host.sin_addr, &skp->smk_mask, | 1283 | &snp->smk_host.sin_addr, &snp->smk_mask, |
1273 | PF_INET, &audit_info); | 1284 | PF_INET, &audit_info); |
1274 | else | 1285 | else |
1275 | rc = 0; | 1286 | rc = 0; |
1276 | skp->smk_label = sp; | 1287 | snp->smk_label = skp; |
1277 | } | 1288 | } |
1278 | 1289 | ||
1279 | /* | 1290 | /* |
@@ -1281,10 +1292,10 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
1281 | * this host so that incoming packets get labeled. | 1292 | * this host so that incoming packets get labeled. |
1282 | * but only if we didn't get the special CIPSO option | 1293 | * but only if we didn't get the special CIPSO option |
1283 | */ | 1294 | */ |
1284 | if (rc == 0 && sp != smack_cipso_option) | 1295 | if (rc == 0 && skp != &smack_cipso_option) |
1285 | rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, | 1296 | rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, |
1286 | &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET, | 1297 | &snp->smk_host.sin_addr, &snp->smk_mask, PF_INET, |
1287 | smack_to_secid(skp->smk_label), &audit_info); | 1298 | snp->smk_label->smk_secid, &audit_info); |
1288 | 1299 | ||
1289 | if (rc == 0) | 1300 | if (rc == 0) |
1290 | rc = count; | 1301 | rc = count; |
@@ -1677,7 +1688,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, | |||
1677 | if (smack_onlycap != NULL && smack_onlycap != skp) | 1688 | if (smack_onlycap != NULL && smack_onlycap != skp) |
1678 | return -EPERM; | 1689 | return -EPERM; |
1679 | 1690 | ||
1680 | data = kzalloc(count, GFP_KERNEL); | 1691 | data = kzalloc(count + 1, GFP_KERNEL); |
1681 | if (data == NULL) | 1692 | if (data == NULL) |
1682 | return -ENOMEM; | 1693 | return -ENOMEM; |
1683 | 1694 | ||
@@ -1880,7 +1891,10 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, | |||
1880 | else if (res != -ENOENT) | 1891 | else if (res != -ENOENT) |
1881 | return -EINVAL; | 1892 | return -EINVAL; |
1882 | 1893 | ||
1883 | data[0] = res == 0 ? '1' : '0'; | 1894 | /* |
1895 | * smk_access() can return a value > 0 in the "bringup" case. | ||
1896 | */ | ||
1897 | data[0] = res >= 0 ? '1' : '0'; | ||
1884 | data[1] = '\0'; | 1898 | data[1] = '\0'; |
1885 | 1899 | ||
1886 | simple_transaction_set(file, 2); | 1900 | simple_transaction_set(file, 2); |
@@ -2228,7 +2242,7 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf, | |||
2228 | if (!smack_privileged(CAP_MAC_ADMIN)) | 2242 | if (!smack_privileged(CAP_MAC_ADMIN)) |
2229 | return -EPERM; | 2243 | return -EPERM; |
2230 | 2244 | ||
2231 | data = kzalloc(count, GFP_KERNEL); | 2245 | data = kzalloc(count + 1, GFP_KERNEL); |
2232 | if (data == NULL) | 2246 | if (data == NULL) |
2233 | return -ENOMEM; | 2247 | return -ENOMEM; |
2234 | 2248 | ||