aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c76
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
132struct smack_parsed_rule { 132struct 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
139static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 139static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
140 140
141const char *smack_cipso_option = SMACK_CIPSO_OPTION; 141struct 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)
1147static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, 1158static 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