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.c993
1 files changed, 761 insertions, 232 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 038811cb7e6..1810c9a4ed4 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -22,7 +22,6 @@
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/netlabel.h>
26#include <net/cipso_ipv4.h> 25#include <net/cipso_ipv4.h>
27#include <linux/seq_file.h> 26#include <linux/seq_file.h>
28#include <linux/ctype.h> 27#include <linux/ctype.h>
@@ -45,6 +44,11 @@ enum smk_inos {
45 SMK_LOGGING = 10, /* logging */ 44 SMK_LOGGING = 10, /* logging */
46 SMK_LOAD_SELF = 11, /* task specific rules */ 45 SMK_LOAD_SELF = 11, /* task specific rules */
47 SMK_ACCESSES = 12, /* access policy */ 46 SMK_ACCESSES = 12, /* access policy */
47 SMK_MAPPED = 13, /* CIPSO level indicating mapped label */
48 SMK_LOAD2 = 14, /* load policy with long labels */
49 SMK_LOAD_SELF2 = 15, /* load task specific rules with long labels */
50 SMK_ACCESS2 = 16, /* make an access check with long labels */
51 SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */
48}; 52};
49 53
50/* 54/*
@@ -60,7 +64,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
60 * If it isn't somehow marked, use this. 64 * If it isn't somehow marked, use this.
61 * It can be reset via smackfs/ambient 65 * It can be reset via smackfs/ambient
62 */ 66 */
63char *smack_net_ambient = smack_known_floor.smk_known; 67char *smack_net_ambient;
64 68
65/* 69/*
66 * This is the level in a CIPSO header that indicates a 70 * This is the level in a CIPSO header that indicates a
@@ -70,6 +74,13 @@ char *smack_net_ambient = smack_known_floor.smk_known;
70int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; 74int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
71 75
72/* 76/*
77 * This is the level in a CIPSO header that indicates a
78 * secid is contained directly in the category set.
79 * It can be reset via smackfs/mapped
80 */
81int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
82
83/*
73 * Unless a process is running with this label even 84 * Unless a process is running with this label even
74 * having CAP_MAC_OVERRIDE isn't enough to grant 85 * having CAP_MAC_OVERRIDE isn't enough to grant
75 * privilege to violate MAC policy. If no label is 86 * privilege to violate MAC policy. If no label is
@@ -89,7 +100,7 @@ LIST_HEAD(smk_netlbladdr_list);
89 100
90/* 101/*
91 * Rule lists are maintained for each label. 102 * Rule lists are maintained for each label.
92 * This master list is just for reading /smack/load. 103 * This master list is just for reading /smack/load and /smack/load2.
93 */ 104 */
94struct smack_master_list { 105struct smack_master_list {
95 struct list_head list; 106 struct list_head list;
@@ -125,6 +136,18 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION;
125#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN) 136#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
126#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) 137#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
127 138
139/*
140 * Stricly for CIPSO level manipulation.
141 * Set the category bit number in a smack label sized buffer.
142 */
143static inline void smack_catset_bit(unsigned int cat, char *catsetp)
144{
145 if (cat == 0 || cat > (SMK_CIPSOLEN * 8))
146 return;
147
148 catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8);
149}
150
128/** 151/**
129 * smk_netlabel_audit_set - fill a netlbl_audit struct 152 * smk_netlabel_audit_set - fill a netlbl_audit struct
130 * @nap: structure to fill 153 * @nap: structure to fill
@@ -137,12 +160,10 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
137} 160}
138 161
139/* 162/*
140 * Values for parsing single label host rules 163 * Value for parsing single label host rules
141 * "1.2.3.4 X" 164 * "1.2.3.4 X"
142 * "192.168.138.129/32 abcdefghijklmnopqrstuvw"
143 */ 165 */
144#define SMK_NETLBLADDRMIN 9 166#define SMK_NETLBLADDRMIN 9
145#define SMK_NETLBLADDRMAX 42
146 167
147/** 168/**
148 * smk_set_access - add a rule to the rule list 169 * smk_set_access - add a rule to the rule list
@@ -188,33 +209,47 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
188} 209}
189 210
190/** 211/**
191 * smk_parse_rule - parse Smack rule from load string 212 * smk_fill_rule - Fill Smack rule from strings
192 * @data: string to be parsed whose size is SMK_LOADLEN 213 * @subject: subject label string
214 * @object: object label string
215 * @access: access string
193 * @rule: Smack rule 216 * @rule: Smack rule
194 * @import: if non-zero, import labels 217 * @import: if non-zero, import labels
218 *
219 * Returns 0 on success, -1 on failure
195 */ 220 */
196static int smk_parse_rule(const char *data, struct smack_rule *rule, int import) 221static int smk_fill_rule(const char *subject, const char *object,
222 const char *access, struct smack_rule *rule,
223 int import)
197{ 224{
198 char smack[SMK_LABELLEN]; 225 int rc = -1;
226 int done;
227 const char *cp;
199 struct smack_known *skp; 228 struct smack_known *skp;
200 229
201 if (import) { 230 if (import) {
202 rule->smk_subject = smk_import(data, 0); 231 rule->smk_subject = smk_import(subject, 0);
203 if (rule->smk_subject == NULL) 232 if (rule->smk_subject == NULL)
204 return -1; 233 return -1;
205 234
206 rule->smk_object = smk_import(data + SMK_LABELLEN, 0); 235 rule->smk_object = smk_import(object, 0);
207 if (rule->smk_object == NULL) 236 if (rule->smk_object == NULL)
208 return -1; 237 return -1;
209 } else { 238 } else {
210 smk_parse_smack(data, 0, smack); 239 cp = smk_parse_smack(subject, 0);
211 skp = smk_find_entry(smack); 240 if (cp == NULL)
241 return -1;
242 skp = smk_find_entry(cp);
243 kfree(cp);
212 if (skp == NULL) 244 if (skp == NULL)
213 return -1; 245 return -1;
214 rule->smk_subject = skp->smk_known; 246 rule->smk_subject = skp->smk_known;
215 247
216 smk_parse_smack(data + SMK_LABELLEN, 0, smack); 248 cp = smk_parse_smack(object, 0);
217 skp = smk_find_entry(smack); 249 if (cp == NULL)
250 return -1;
251 skp = smk_find_entry(cp);
252 kfree(cp);
218 if (skp == NULL) 253 if (skp == NULL)
219 return -1; 254 return -1;
220 rule->smk_object = skp->smk_known; 255 rule->smk_object = skp->smk_known;
@@ -222,90 +257,127 @@ static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
222 257
223 rule->smk_access = 0; 258 rule->smk_access = 0;
224 259
225 switch (data[SMK_LABELLEN + SMK_LABELLEN]) { 260 for (cp = access, done = 0; *cp && !done; cp++) {
226 case '-': 261 switch (*cp) {
227 break; 262 case '-':
228 case 'r': 263 break;
229 case 'R': 264 case 'r':
230 rule->smk_access |= MAY_READ; 265 case 'R':
231 break; 266 rule->smk_access |= MAY_READ;
232 default: 267 break;
233 return -1; 268 case 'w':
269 case 'W':
270 rule->smk_access |= MAY_WRITE;
271 break;
272 case 'x':
273 case 'X':
274 rule->smk_access |= MAY_EXEC;
275 break;
276 case 'a':
277 case 'A':
278 rule->smk_access |= MAY_APPEND;
279 break;
280 case 't':
281 case 'T':
282 rule->smk_access |= MAY_TRANSMUTE;
283 break;
284 default:
285 done = 1;
286 break;
287 }
234 } 288 }
289 rc = 0;
235 290
236 switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) { 291 return rc;
237 case '-': 292}
238 break;
239 case 'w':
240 case 'W':
241 rule->smk_access |= MAY_WRITE;
242 break;
243 default:
244 return -1;
245 }
246 293
247 switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) { 294/**
248 case '-': 295 * smk_parse_rule - parse Smack rule from load string
249 break; 296 * @data: string to be parsed whose size is SMK_LOADLEN
250 case 'x': 297 * @rule: Smack rule
251 case 'X': 298 * @import: if non-zero, import labels
252 rule->smk_access |= MAY_EXEC; 299 *
253 break; 300 * Returns 0 on success, -1 on errors.
254 default: 301 */
255 return -1; 302static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
256 } 303{
304 int rc;
257 305
258 switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) { 306 rc = smk_fill_rule(data, data + SMK_LABELLEN,
259 case '-': 307 data + SMK_LABELLEN + SMK_LABELLEN, rule, import);
260 break; 308 return rc;
261 case 'a': 309}
262 case 'A':
263 rule->smk_access |= MAY_APPEND;
264 break;
265 default:
266 return -1;
267 }
268 310
269 switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) { 311/**
270 case '-': 312 * smk_parse_long_rule - parse Smack rule from rule string
271 break; 313 * @data: string to be parsed, null terminated
272 case 't': 314 * @rule: Smack rule
273 case 'T': 315 * @import: if non-zero, import labels
274 rule->smk_access |= MAY_TRANSMUTE; 316 *
275 break; 317 * Returns 0 on success, -1 on failure
276 default: 318 */
277 return -1; 319static int smk_parse_long_rule(const char *data, struct smack_rule *rule,
278 } 320 int import)
321{
322 char *subject;
323 char *object;
324 char *access;
325 int datalen;
326 int rc = -1;
279 327
280 return 0; 328 /*
329 * This is probably inefficient, but safe.
330 */
331 datalen = strlen(data);
332 subject = kzalloc(datalen, GFP_KERNEL);
333 if (subject == NULL)
334 return -1;
335 object = kzalloc(datalen, GFP_KERNEL);
336 if (object == NULL)
337 goto free_out_s;
338 access = kzalloc(datalen, GFP_KERNEL);
339 if (access == NULL)
340 goto free_out_o;
341
342 if (sscanf(data, "%s %s %s", subject, object, access) == 3)
343 rc = smk_fill_rule(subject, object, access, rule, import);
344
345 kfree(access);
346free_out_o:
347 kfree(object);
348free_out_s:
349 kfree(subject);
350 return rc;
281} 351}
282 352
353#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */
354#define SMK_LONG_FMT 1 /* Variable long label format */
283/** 355/**
284 * smk_write_load_list - write() for any /smack/load 356 * smk_write_rules_list - write() for any /smack rule file
285 * @file: file pointer, not actually used 357 * @file: file pointer, not actually used
286 * @buf: where to get the data from 358 * @buf: where to get the data from
287 * @count: bytes sent 359 * @count: bytes sent
288 * @ppos: where to start - must be 0 360 * @ppos: where to start - must be 0
289 * @rule_list: the list of rules to write to 361 * @rule_list: the list of rules to write to
290 * @rule_lock: lock for the rule list 362 * @rule_lock: lock for the rule list
363 * @format: /smack/load or /smack/load2 format.
291 * 364 *
292 * Get one smack access rule from above. 365 * Get one smack access rule from above.
293 * The format is exactly: 366 * The format for SMK_LONG_FMT is:
294 * char subject[SMK_LABELLEN] 367 * "subject<whitespace>object<whitespace>access[<whitespace>...]"
295 * char object[SMK_LABELLEN] 368 * The format for SMK_FIXED24_FMT is exactly:
296 * char access[SMK_ACCESSLEN] 369 * "subject object rwxat"
297 *
298 * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
299 */ 370 */
300static ssize_t smk_write_load_list(struct file *file, const char __user *buf, 371static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
301 size_t count, loff_t *ppos, 372 size_t count, loff_t *ppos,
302 struct list_head *rule_list, 373 struct list_head *rule_list,
303 struct mutex *rule_lock) 374 struct mutex *rule_lock, int format)
304{ 375{
305 struct smack_master_list *smlp; 376 struct smack_master_list *smlp;
306 struct smack_known *skp; 377 struct smack_known *skp;
307 struct smack_rule *rule; 378 struct smack_rule *rule;
308 char *data; 379 char *data;
380 int datalen;
309 int rc = -EINVAL; 381 int rc = -EINVAL;
310 int load = 0; 382 int load = 0;
311 383
@@ -315,13 +387,18 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
315 */ 387 */
316 if (*ppos != 0) 388 if (*ppos != 0)
317 return -EINVAL; 389 return -EINVAL;
318 /*
319 * Minor hack for backward compatibility
320 */
321 if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN)
322 return -EINVAL;
323 390
324 data = kzalloc(SMK_LOADLEN, GFP_KERNEL); 391 if (format == SMK_FIXED24_FMT) {
392 /*
393 * Minor hack for backward compatibility
394 */
395 if (count != SMK_OLOADLEN && count != SMK_LOADLEN)
396 return -EINVAL;
397 datalen = SMK_LOADLEN;
398 } else
399 datalen = count + 1;
400
401 data = kzalloc(datalen, GFP_KERNEL);
325 if (data == NULL) 402 if (data == NULL)
326 return -ENOMEM; 403 return -ENOMEM;
327 404
@@ -330,20 +407,29 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
330 goto out; 407 goto out;
331 } 408 }
332 409
333 /*
334 * More on the minor hack for backward compatibility
335 */
336 if (count == (SMK_OLOADLEN))
337 data[SMK_OLOADLEN] = '-';
338
339 rule = kzalloc(sizeof(*rule), GFP_KERNEL); 410 rule = kzalloc(sizeof(*rule), GFP_KERNEL);
340 if (rule == NULL) { 411 if (rule == NULL) {
341 rc = -ENOMEM; 412 rc = -ENOMEM;
342 goto out; 413 goto out;
343 } 414 }
344 415
345 if (smk_parse_rule(data, rule, 1)) 416 if (format == SMK_LONG_FMT) {
346 goto out_free_rule; 417 /*
418 * Be sure the data string is terminated.
419 */
420 data[count] = '\0';
421 if (smk_parse_long_rule(data, rule, 1))
422 goto out_free_rule;
423 } else {
424 /*
425 * More on the minor hack for backward compatibility
426 */
427 if (count == (SMK_OLOADLEN))
428 data[SMK_OLOADLEN] = '-';
429 if (smk_parse_rule(data, rule, 1))
430 goto out_free_rule;
431 }
432
347 433
348 if (rule_list == NULL) { 434 if (rule_list == NULL) {
349 load = 1; 435 load = 1;
@@ -354,18 +440,20 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
354 440
355 rc = count; 441 rc = count;
356 /* 442 /*
357 * If this is "load" as opposed to "load-self" and a new rule 443 * If this is a global as opposed to self and a new rule
358 * it needs to get added for reporting. 444 * it needs to get added for reporting.
359 * smk_set_access returns true if there was already a rule 445 * smk_set_access returns true if there was already a rule
360 * for the subject/object pair, and false if it was new. 446 * for the subject/object pair, and false if it was new.
361 */ 447 */
362 if (load && !smk_set_access(rule, rule_list, rule_lock)) { 448 if (!smk_set_access(rule, rule_list, rule_lock)) {
363 smlp = kzalloc(sizeof(*smlp), GFP_KERNEL); 449 if (load) {
364 if (smlp != NULL) { 450 smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
365 smlp->smk_rule = rule; 451 if (smlp != NULL) {
366 list_add_rcu(&smlp->list, &smack_rule_list); 452 smlp->smk_rule = rule;
367 } else 453 list_add_rcu(&smlp->list, &smack_rule_list);
368 rc = -ENOMEM; 454 } else
455 rc = -ENOMEM;
456 }
369 goto out; 457 goto out;
370 } 458 }
371 459
@@ -421,29 +509,18 @@ static void smk_seq_stop(struct seq_file *s, void *v)
421 /* No-op */ 509 /* No-op */
422} 510}
423 511
424/* 512static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
425 * Seq_file read operations for /smack/load
426 */
427
428static void *load_seq_start(struct seq_file *s, loff_t *pos)
429{
430 return smk_seq_start(s, pos, &smack_rule_list);
431}
432
433static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
434{ 513{
435 return smk_seq_next(s, v, pos, &smack_rule_list); 514 /*
436} 515 * Don't show any rules with label names too long for
437 516 * interface file (/smack/load or /smack/load2)
438static int load_seq_show(struct seq_file *s, void *v) 517 * because you should expect to be able to write
439{ 518 * anything you read back.
440 struct list_head *list = v; 519 */
441 struct smack_master_list *smlp = 520 if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max)
442 list_entry(list, struct smack_master_list, list); 521 return;
443 struct smack_rule *srp = smlp->smk_rule;
444 522
445 seq_printf(s, "%s %s", (char *)srp->smk_subject, 523 seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object);
446 (char *)srp->smk_object);
447 524
448 seq_putc(s, ' '); 525 seq_putc(s, ' ');
449 526
@@ -461,13 +538,36 @@ static int load_seq_show(struct seq_file *s, void *v)
461 seq_putc(s, '-'); 538 seq_putc(s, '-');
462 539
463 seq_putc(s, '\n'); 540 seq_putc(s, '\n');
541}
542
543/*
544 * Seq_file read operations for /smack/load
545 */
546
547static void *load2_seq_start(struct seq_file *s, loff_t *pos)
548{
549 return smk_seq_start(s, pos, &smack_rule_list);
550}
551
552static void *load2_seq_next(struct seq_file *s, void *v, loff_t *pos)
553{
554 return smk_seq_next(s, v, pos, &smack_rule_list);
555}
556
557static int load_seq_show(struct seq_file *s, void *v)
558{
559 struct list_head *list = v;
560 struct smack_master_list *smlp =
561 list_entry(list, struct smack_master_list, list);
562
563 smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN);
464 564
465 return 0; 565 return 0;
466} 566}
467 567
468static const struct seq_operations load_seq_ops = { 568static const struct seq_operations load_seq_ops = {
469 .start = load_seq_start, 569 .start = load2_seq_start,
470 .next = load_seq_next, 570 .next = load2_seq_next,
471 .show = load_seq_show, 571 .show = load_seq_show,
472 .stop = smk_seq_stop, 572 .stop = smk_seq_stop,
473}; 573};
@@ -504,7 +604,8 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
504 if (!capable(CAP_MAC_ADMIN)) 604 if (!capable(CAP_MAC_ADMIN))
505 return -EPERM; 605 return -EPERM;
506 606
507 return smk_write_load_list(file, buf, count, ppos, NULL, NULL); 607 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
608 SMK_FIXED24_FMT);
508} 609}
509 610
510static const struct file_operations smk_load_ops = { 611static const struct file_operations smk_load_ops = {
@@ -574,6 +675,8 @@ static void smk_unlbl_ambient(char *oldambient)
574 printk(KERN_WARNING "%s:%d remove rc = %d\n", 675 printk(KERN_WARNING "%s:%d remove rc = %d\n",
575 __func__, __LINE__, rc); 676 __func__, __LINE__, rc);
576 } 677 }
678 if (smack_net_ambient == NULL)
679 smack_net_ambient = smack_known_floor.smk_known;
577 680
578 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, 681 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET,
579 NULL, NULL, &nai); 682 NULL, NULL, &nai);
@@ -605,27 +708,28 @@ static int cipso_seq_show(struct seq_file *s, void *v)
605 struct list_head *list = v; 708 struct list_head *list = v;
606 struct smack_known *skp = 709 struct smack_known *skp =
607 list_entry(list, struct smack_known, list); 710 list_entry(list, struct smack_known, list);
608 struct smack_cipso *scp = skp->smk_cipso; 711 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
609 char *cbp;
610 char sep = '/'; 712 char sep = '/';
611 int cat = 1;
612 int i; 713 int i;
613 unsigned char m;
614 714
615 if (scp == NULL) 715 /*
716 * Don't show a label that could not have been set using
717 * /smack/cipso. This is in support of the notion that
718 * anything read from /smack/cipso ought to be writeable
719 * to /smack/cipso.
720 *
721 * /smack/cipso2 should be used instead.
722 */
723 if (strlen(skp->smk_known) >= SMK_LABELLEN)
616 return 0; 724 return 0;
617 725
618 seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level); 726 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
619 727
620 cbp = scp->smk_catset; 728 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0;
621 for (i = 0; i < SMK_LABELLEN; i++) 729 i = netlbl_secattr_catmap_walk(cmp, i + 1)) {
622 for (m = 0x80; m != 0; m >>= 1) { 730 seq_printf(s, "%c%d", sep, i);
623 if (m & cbp[i]) { 731 sep = ',';
624 seq_printf(s, "%c%d", sep, cat); 732 }
625 sep = ',';
626 }
627 cat++;
628 }
629 733
630 seq_putc(s, '\n'); 734 seq_putc(s, '\n');
631 735
@@ -653,23 +757,24 @@ static int smk_open_cipso(struct inode *inode, struct file *file)
653} 757}
654 758
655/** 759/**
656 * smk_write_cipso - write() for /smack/cipso 760 * smk_set_cipso - do the work for write() for cipso and cipso2
657 * @file: file pointer, not actually used 761 * @file: file pointer, not actually used
658 * @buf: where to get the data from 762 * @buf: where to get the data from
659 * @count: bytes sent 763 * @count: bytes sent
660 * @ppos: where to start 764 * @ppos: where to start
765 * @format: /smack/cipso or /smack/cipso2
661 * 766 *
662 * Accepts only one cipso rule per write call. 767 * Accepts only one cipso rule per write call.
663 * Returns number of bytes written or error code, as appropriate 768 * Returns number of bytes written or error code, as appropriate
664 */ 769 */
665static ssize_t smk_write_cipso(struct file *file, const char __user *buf, 770static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
666 size_t count, loff_t *ppos) 771 size_t count, loff_t *ppos, int format)
667{ 772{
668 struct smack_known *skp; 773 struct smack_known *skp;
669 struct smack_cipso *scp = NULL; 774 struct netlbl_lsm_secattr ncats;
670 char mapcatset[SMK_LABELLEN]; 775 char mapcatset[SMK_CIPSOLEN];
671 int maplevel; 776 int maplevel;
672 int cat; 777 unsigned int cat;
673 int catlen; 778 int catlen;
674 ssize_t rc = -EINVAL; 779 ssize_t rc = -EINVAL;
675 char *data = NULL; 780 char *data = NULL;
@@ -686,7 +791,8 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
686 return -EPERM; 791 return -EPERM;
687 if (*ppos != 0) 792 if (*ppos != 0)
688 return -EINVAL; 793 return -EINVAL;
689 if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX) 794 if (format == SMK_FIXED24_FMT &&
795 (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
690 return -EINVAL; 796 return -EINVAL;
691 797
692 data = kzalloc(count + 1, GFP_KERNEL); 798 data = kzalloc(count + 1, GFP_KERNEL);
@@ -698,11 +804,6 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
698 goto unlockedout; 804 goto unlockedout;
699 } 805 }
700 806
701 /* labels cannot begin with a '-' */
702 if (data[0] == '-') {
703 rc = -EINVAL;
704 goto unlockedout;
705 }
706 data[count] = '\0'; 807 data[count] = '\0';
707 rule = data; 808 rule = data;
708 /* 809 /*
@@ -715,7 +816,11 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
715 if (skp == NULL) 816 if (skp == NULL)
716 goto out; 817 goto out;
717 818
718 rule += SMK_LABELLEN; 819 if (format == SMK_FIXED24_FMT)
820 rule += SMK_LABELLEN;
821 else
822 rule += strlen(skp->smk_known);
823
719 ret = sscanf(rule, "%d", &maplevel); 824 ret = sscanf(rule, "%d", &maplevel);
720 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) 825 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
721 goto out; 826 goto out;
@@ -725,41 +830,29 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
725 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) 830 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
726 goto out; 831 goto out;
727 832
728 if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) 833 if (format == SMK_FIXED24_FMT &&
834 count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
729 goto out; 835 goto out;
730 836
731 memset(mapcatset, 0, sizeof(mapcatset)); 837 memset(mapcatset, 0, sizeof(mapcatset));
732 838
733 for (i = 0; i < catlen; i++) { 839 for (i = 0; i < catlen; i++) {
734 rule += SMK_DIGITLEN; 840 rule += SMK_DIGITLEN;
735 ret = sscanf(rule, "%d", &cat); 841 ret = sscanf(rule, "%u", &cat);
736 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL) 842 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
737 goto out; 843 goto out;
738 844
739 smack_catset_bit(cat, mapcatset); 845 smack_catset_bit(cat, mapcatset);
740 } 846 }
741 847
742 if (skp->smk_cipso == NULL) { 848 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
743 scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL); 849 if (rc >= 0) {
744 if (scp == NULL) { 850 netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat);
745 rc = -ENOMEM; 851 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
746 goto out; 852 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
747 } 853 rc = count;
748 } 854 }
749 855
750 spin_lock_bh(&skp->smk_cipsolock);
751
752 if (scp == NULL)
753 scp = skp->smk_cipso;
754 else
755 skp->smk_cipso = scp;
756
757 scp->smk_level = maplevel;
758 memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset));
759
760 spin_unlock_bh(&skp->smk_cipsolock);
761
762 rc = count;
763out: 856out:
764 mutex_unlock(&smack_cipso_lock); 857 mutex_unlock(&smack_cipso_lock);
765unlockedout: 858unlockedout:
@@ -767,6 +860,22 @@ unlockedout:
767 return rc; 860 return rc;
768} 861}
769 862
863/**
864 * smk_write_cipso - write() for /smack/cipso
865 * @file: file pointer, not actually used
866 * @buf: where to get the data from
867 * @count: bytes sent
868 * @ppos: where to start
869 *
870 * Accepts only one cipso rule per write call.
871 * Returns number of bytes written or error code, as appropriate
872 */
873static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
874 size_t count, loff_t *ppos)
875{
876 return smk_set_cipso(file, buf, count, ppos, SMK_FIXED24_FMT);
877}
878
770static const struct file_operations smk_cipso_ops = { 879static const struct file_operations smk_cipso_ops = {
771 .open = smk_open_cipso, 880 .open = smk_open_cipso,
772 .read = seq_read, 881 .read = seq_read,
@@ -776,6 +885,80 @@ static const struct file_operations smk_cipso_ops = {
776}; 885};
777 886
778/* 887/*
888 * Seq_file read operations for /smack/cipso2
889 */
890
891/*
892 * Print cipso labels in format:
893 * label level[/cat[,cat]]
894 */
895static int cipso2_seq_show(struct seq_file *s, void *v)
896{
897 struct list_head *list = v;
898 struct smack_known *skp =
899 list_entry(list, struct smack_known, list);
900 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
901 char sep = '/';
902 int i;
903
904 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
905
906 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0;
907 i = netlbl_secattr_catmap_walk(cmp, i + 1)) {
908 seq_printf(s, "%c%d", sep, i);
909 sep = ',';
910 }
911
912 seq_putc(s, '\n');
913
914 return 0;
915}
916
917static const struct seq_operations cipso2_seq_ops = {
918 .start = cipso_seq_start,
919 .next = cipso_seq_next,
920 .show = cipso2_seq_show,
921 .stop = smk_seq_stop,
922};
923
924/**
925 * smk_open_cipso2 - open() for /smack/cipso2
926 * @inode: inode structure representing file
927 * @file: "cipso2" file pointer
928 *
929 * Connect our cipso_seq_* operations with /smack/cipso2
930 * file_operations
931 */
932static int smk_open_cipso2(struct inode *inode, struct file *file)
933{
934 return seq_open(file, &cipso2_seq_ops);
935}
936
937/**
938 * smk_write_cipso2 - write() for /smack/cipso2
939 * @file: file pointer, not actually used
940 * @buf: where to get the data from
941 * @count: bytes sent
942 * @ppos: where to start
943 *
944 * Accepts only one cipso rule per write call.
945 * Returns number of bytes written or error code, as appropriate
946 */
947static ssize_t smk_write_cipso2(struct file *file, const char __user *buf,
948 size_t count, loff_t *ppos)
949{
950 return smk_set_cipso(file, buf, count, ppos, SMK_LONG_FMT);
951}
952
953static const struct file_operations smk_cipso2_ops = {
954 .open = smk_open_cipso2,
955 .read = seq_read,
956 .llseek = seq_lseek,
957 .write = smk_write_cipso2,
958 .release = seq_release,
959};
960
961/*
779 * Seq_file read operations for /smack/netlabel 962 * Seq_file read operations for /smack/netlabel
780 */ 963 */
781 964
@@ -887,9 +1070,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
887{ 1070{
888 struct smk_netlbladdr *skp; 1071 struct smk_netlbladdr *skp;
889 struct sockaddr_in newname; 1072 struct sockaddr_in newname;
890 char smack[SMK_LABELLEN]; 1073 char *smack;
891 char *sp; 1074 char *sp;
892 char data[SMK_NETLBLADDRMAX + 1]; 1075 char *data;
893 char *host = (char *)&newname.sin_addr.s_addr; 1076 char *host = (char *)&newname.sin_addr.s_addr;
894 int rc; 1077 int rc;
895 struct netlbl_audit audit_info; 1078 struct netlbl_audit audit_info;
@@ -911,10 +1094,23 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
911 return -EPERM; 1094 return -EPERM;
912 if (*ppos != 0) 1095 if (*ppos != 0)
913 return -EINVAL; 1096 return -EINVAL;
914 if (count < SMK_NETLBLADDRMIN || count > SMK_NETLBLADDRMAX) 1097 if (count < SMK_NETLBLADDRMIN)
915 return -EINVAL; 1098 return -EINVAL;
916 if (copy_from_user(data, buf, count) != 0) 1099
917 return -EFAULT; 1100 data = kzalloc(count + 1, GFP_KERNEL);
1101 if (data == NULL)
1102 return -ENOMEM;
1103
1104 if (copy_from_user(data, buf, count) != 0) {
1105 rc = -EFAULT;
1106 goto free_data_out;
1107 }
1108
1109 smack = kzalloc(count + 1, GFP_KERNEL);
1110 if (smack == NULL) {
1111 rc = -ENOMEM;
1112 goto free_data_out;
1113 }
918 1114
919 data[count] = '\0'; 1115 data[count] = '\0';
920 1116
@@ -923,24 +1119,34 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
923 if (rc != 6) { 1119 if (rc != 6) {
924 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", 1120 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
925 &host[0], &host[1], &host[2], &host[3], smack); 1121 &host[0], &host[1], &host[2], &host[3], smack);
926 if (rc != 5) 1122 if (rc != 5) {
927 return -EINVAL; 1123 rc = -EINVAL;
1124 goto free_out;
1125 }
928 m = BEBITS; 1126 m = BEBITS;
929 } 1127 }
930 if (m > BEBITS) 1128 if (m > BEBITS) {
931 return -EINVAL; 1129 rc = -EINVAL;
1130 goto free_out;
1131 }
932 1132
933 /* if smack begins with '-', its an option, don't import it */ 1133 /*
1134 * If smack begins with '-', it is an option, don't import it
1135 */
934 if (smack[0] != '-') { 1136 if (smack[0] != '-') {
935 sp = smk_import(smack, 0); 1137 sp = smk_import(smack, 0);
936 if (sp == NULL) 1138 if (sp == NULL) {
937 return -EINVAL; 1139 rc = -EINVAL;
1140 goto free_out;
1141 }
938 } else { 1142 } else {
939 /* check known options */ 1143 /* check known options */
940 if (strcmp(smack, smack_cipso_option) == 0) 1144 if (strcmp(smack, smack_cipso_option) == 0)
941 sp = (char *)smack_cipso_option; 1145 sp = (char *)smack_cipso_option;
942 else 1146 else {
943 return -EINVAL; 1147 rc = -EINVAL;
1148 goto free_out;
1149 }
944 } 1150 }
945 1151
946 for (temp_mask = 0; m > 0; m--) { 1152 for (temp_mask = 0; m > 0; m--) {
@@ -1006,6 +1212,11 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1006 1212
1007 mutex_unlock(&smk_netlbladdr_lock); 1213 mutex_unlock(&smk_netlbladdr_lock);
1008 1214
1215free_out:
1216 kfree(smack);
1217free_data_out:
1218 kfree(data);
1219
1009 return rc; 1220 return rc;
1010} 1221}
1011 1222
@@ -1119,6 +1330,7 @@ static ssize_t smk_read_direct(struct file *filp, char __user *buf,
1119static ssize_t smk_write_direct(struct file *file, const char __user *buf, 1330static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1120 size_t count, loff_t *ppos) 1331 size_t count, loff_t *ppos)
1121{ 1332{
1333 struct smack_known *skp;
1122 char temp[80]; 1334 char temp[80];
1123 int i; 1335 int i;
1124 1336
@@ -1136,7 +1348,20 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1136 if (sscanf(temp, "%d", &i) != 1) 1348 if (sscanf(temp, "%d", &i) != 1)
1137 return -EINVAL; 1349 return -EINVAL;
1138 1350
1139 smack_cipso_direct = i; 1351 /*
1352 * Don't do anything if the value hasn't actually changed.
1353 * If it is changing reset the level on entries that were
1354 * set up to be direct when they were created.
1355 */
1356 if (smack_cipso_direct != i) {
1357 mutex_lock(&smack_known_lock);
1358 list_for_each_entry_rcu(skp, &smack_known_list, list)
1359 if (skp->smk_netlabel.attr.mls.lvl ==
1360 smack_cipso_direct)
1361 skp->smk_netlabel.attr.mls.lvl = i;
1362 smack_cipso_direct = i;
1363 mutex_unlock(&smack_known_lock);
1364 }
1140 1365
1141 return count; 1366 return count;
1142} 1367}
@@ -1148,6 +1373,84 @@ static const struct file_operations smk_direct_ops = {
1148}; 1373};
1149 1374
1150/** 1375/**
1376 * smk_read_mapped - read() for /smack/mapped
1377 * @filp: file pointer, not actually used
1378 * @buf: where to put the result
1379 * @count: maximum to send along
1380 * @ppos: where to start
1381 *
1382 * Returns number of bytes read or error code, as appropriate
1383 */
1384static ssize_t smk_read_mapped(struct file *filp, char __user *buf,
1385 size_t count, loff_t *ppos)
1386{
1387 char temp[80];
1388 ssize_t rc;
1389
1390 if (*ppos != 0)
1391 return 0;
1392
1393 sprintf(temp, "%d", smack_cipso_mapped);
1394 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1395
1396 return rc;
1397}
1398
1399/**
1400 * smk_write_mapped - write() for /smack/mapped
1401 * @file: file pointer, not actually used
1402 * @buf: where to get the data from
1403 * @count: bytes sent
1404 * @ppos: where to start
1405 *
1406 * Returns number of bytes written or error code, as appropriate
1407 */
1408static ssize_t smk_write_mapped(struct file *file, const char __user *buf,
1409 size_t count, loff_t *ppos)
1410{
1411 struct smack_known *skp;
1412 char temp[80];
1413 int i;
1414
1415 if (!capable(CAP_MAC_ADMIN))
1416 return -EPERM;
1417
1418 if (count >= sizeof(temp) || count == 0)
1419 return -EINVAL;
1420
1421 if (copy_from_user(temp, buf, count) != 0)
1422 return -EFAULT;
1423
1424 temp[count] = '\0';
1425
1426 if (sscanf(temp, "%d", &i) != 1)
1427 return -EINVAL;
1428
1429 /*
1430 * Don't do anything if the value hasn't actually changed.
1431 * If it is changing reset the level on entries that were
1432 * set up to be mapped when they were created.
1433 */
1434 if (smack_cipso_mapped != i) {
1435 mutex_lock(&smack_known_lock);
1436 list_for_each_entry_rcu(skp, &smack_known_list, list)
1437 if (skp->smk_netlabel.attr.mls.lvl ==
1438 smack_cipso_mapped)
1439 skp->smk_netlabel.attr.mls.lvl = i;
1440 smack_cipso_mapped = i;
1441 mutex_unlock(&smack_known_lock);
1442 }
1443
1444 return count;
1445}
1446
1447static const struct file_operations smk_mapped_ops = {
1448 .read = smk_read_mapped,
1449 .write = smk_write_mapped,
1450 .llseek = default_llseek,
1451};
1452
1453/**
1151 * smk_read_ambient - read() for /smack/ambient 1454 * smk_read_ambient - read() for /smack/ambient
1152 * @filp: file pointer, not actually used 1455 * @filp: file pointer, not actually used
1153 * @buf: where to put the result 1456 * @buf: where to put the result
@@ -1195,22 +1498,28 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1195static ssize_t smk_write_ambient(struct file *file, const char __user *buf, 1498static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1196 size_t count, loff_t *ppos) 1499 size_t count, loff_t *ppos)
1197{ 1500{
1198 char in[SMK_LABELLEN];
1199 char *oldambient; 1501 char *oldambient;
1200 char *smack; 1502 char *smack = NULL;
1503 char *data;
1504 int rc = count;
1201 1505
1202 if (!capable(CAP_MAC_ADMIN)) 1506 if (!capable(CAP_MAC_ADMIN))
1203 return -EPERM; 1507 return -EPERM;
1204 1508
1205 if (count >= SMK_LABELLEN) 1509 data = kzalloc(count + 1, GFP_KERNEL);
1206 return -EINVAL; 1510 if (data == NULL)
1511 return -ENOMEM;
1207 1512
1208 if (copy_from_user(in, buf, count) != 0) 1513 if (copy_from_user(data, buf, count) != 0) {
1209 return -EFAULT; 1514 rc = -EFAULT;
1515 goto out;
1516 }
1210 1517
1211 smack = smk_import(in, count); 1518 smack = smk_import(data, count);
1212 if (smack == NULL) 1519 if (smack == NULL) {
1213 return -EINVAL; 1520 rc = -EINVAL;
1521 goto out;
1522 }
1214 1523
1215 mutex_lock(&smack_ambient_lock); 1524 mutex_lock(&smack_ambient_lock);
1216 1525
@@ -1220,7 +1529,9 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1220 1529
1221 mutex_unlock(&smack_ambient_lock); 1530 mutex_unlock(&smack_ambient_lock);
1222 1531
1223 return count; 1532out:
1533 kfree(data);
1534 return rc;
1224} 1535}
1225 1536
1226static const struct file_operations smk_ambient_ops = { 1537static const struct file_operations smk_ambient_ops = {
@@ -1271,8 +1582,9 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1271static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, 1582static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1272 size_t count, loff_t *ppos) 1583 size_t count, loff_t *ppos)
1273{ 1584{
1274 char in[SMK_LABELLEN]; 1585 char *data;
1275 char *sp = smk_of_task(current->cred->security); 1586 char *sp = smk_of_task(current->cred->security);
1587 int rc = count;
1276 1588
1277 if (!capable(CAP_MAC_ADMIN)) 1589 if (!capable(CAP_MAC_ADMIN))
1278 return -EPERM; 1590 return -EPERM;
@@ -1285,11 +1597,9 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1285 if (smack_onlycap != NULL && smack_onlycap != sp) 1597 if (smack_onlycap != NULL && smack_onlycap != sp)
1286 return -EPERM; 1598 return -EPERM;
1287 1599
1288 if (count >= SMK_LABELLEN) 1600 data = kzalloc(count, GFP_KERNEL);
1289 return -EINVAL; 1601 if (data == NULL)
1290 1602 return -ENOMEM;
1291 if (copy_from_user(in, buf, count) != 0)
1292 return -EFAULT;
1293 1603
1294 /* 1604 /*
1295 * Should the null string be passed in unset the onlycap value. 1605 * Should the null string be passed in unset the onlycap value.
@@ -1297,10 +1607,17 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1297 * smk_import only expects to return NULL for errors. It 1607 * smk_import only expects to return NULL for errors. It
1298 * is usually the case that a nullstring or "\n" would be 1608 * is usually the case that a nullstring or "\n" would be
1299 * bad to pass to smk_import but in fact this is useful here. 1609 * bad to pass to smk_import but in fact this is useful here.
1610 *
1611 * smk_import will also reject a label beginning with '-',
1612 * so "-usecapabilities" will also work.
1300 */ 1613 */
1301 smack_onlycap = smk_import(in, count); 1614 if (copy_from_user(data, buf, count) != 0)
1615 rc = -EFAULT;
1616 else
1617 smack_onlycap = smk_import(data, count);
1302 1618
1303 return count; 1619 kfree(data);
1620 return rc;
1304} 1621}
1305 1622
1306static const struct file_operations smk_onlycap_ops = { 1623static const struct file_operations smk_onlycap_ops = {
@@ -1398,25 +1715,7 @@ static int load_self_seq_show(struct seq_file *s, void *v)
1398 struct smack_rule *srp = 1715 struct smack_rule *srp =
1399 list_entry(list, struct smack_rule, list); 1716 list_entry(list, struct smack_rule, list);
1400 1717
1401 seq_printf(s, "%s %s", (char *)srp->smk_subject, 1718 smk_rule_show(s, srp, SMK_LABELLEN);
1402 (char *)srp->smk_object);
1403
1404 seq_putc(s, ' ');
1405
1406 if (srp->smk_access & MAY_READ)
1407 seq_putc(s, 'r');
1408 if (srp->smk_access & MAY_WRITE)
1409 seq_putc(s, 'w');
1410 if (srp->smk_access & MAY_EXEC)
1411 seq_putc(s, 'x');
1412 if (srp->smk_access & MAY_APPEND)
1413 seq_putc(s, 'a');
1414 if (srp->smk_access & MAY_TRANSMUTE)
1415 seq_putc(s, 't');
1416 if (srp->smk_access == 0)
1417 seq_putc(s, '-');
1418
1419 seq_putc(s, '\n');
1420 1719
1421 return 0; 1720 return 0;
1422} 1721}
@@ -1430,7 +1729,7 @@ static const struct seq_operations load_self_seq_ops = {
1430 1729
1431 1730
1432/** 1731/**
1433 * smk_open_load_self - open() for /smack/load-self 1732 * smk_open_load_self - open() for /smack/load-self2
1434 * @inode: inode structure representing file 1733 * @inode: inode structure representing file
1435 * @file: "load" file pointer 1734 * @file: "load" file pointer
1436 * 1735 *
@@ -1454,8 +1753,8 @@ static ssize_t smk_write_load_self(struct file *file, const char __user *buf,
1454{ 1753{
1455 struct task_smack *tsp = current_security(); 1754 struct task_smack *tsp = current_security();
1456 1755
1457 return smk_write_load_list(file, buf, count, ppos, &tsp->smk_rules, 1756 return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules,
1458 &tsp->smk_rules_lock); 1757 &tsp->smk_rules_lock, SMK_FIXED24_FMT);
1459} 1758}
1460 1759
1461static const struct file_operations smk_load_self_ops = { 1760static const struct file_operations smk_load_self_ops = {
@@ -1467,24 +1766,42 @@ static const struct file_operations smk_load_self_ops = {
1467}; 1766};
1468 1767
1469/** 1768/**
1470 * smk_write_access - handle access check transaction 1769 * smk_user_access - handle access check transaction
1471 * @file: file pointer 1770 * @file: file pointer
1472 * @buf: data from user space 1771 * @buf: data from user space
1473 * @count: bytes sent 1772 * @count: bytes sent
1474 * @ppos: where to start - must be 0 1773 * @ppos: where to start - must be 0
1475 */ 1774 */
1476static ssize_t smk_write_access(struct file *file, const char __user *buf, 1775static ssize_t smk_user_access(struct file *file, const char __user *buf,
1477 size_t count, loff_t *ppos) 1776 size_t count, loff_t *ppos, int format)
1478{ 1777{
1479 struct smack_rule rule; 1778 struct smack_rule rule;
1480 char *data; 1779 char *data;
1780 char *cod;
1481 int res; 1781 int res;
1482 1782
1483 data = simple_transaction_get(file, buf, count); 1783 data = simple_transaction_get(file, buf, count);
1484 if (IS_ERR(data)) 1784 if (IS_ERR(data))
1485 return PTR_ERR(data); 1785 return PTR_ERR(data);
1486 1786
1487 if (count < SMK_LOADLEN || smk_parse_rule(data, &rule, 0)) 1787 if (format == SMK_FIXED24_FMT) {
1788 if (count < SMK_LOADLEN)
1789 return -EINVAL;
1790 res = smk_parse_rule(data, &rule, 0);
1791 } else {
1792 /*
1793 * Copy the data to make sure the string is terminated.
1794 */
1795 cod = kzalloc(count + 1, GFP_KERNEL);
1796 if (cod == NULL)
1797 return -ENOMEM;
1798 memcpy(cod, data, count);
1799 cod[count] = '\0';
1800 res = smk_parse_long_rule(cod, &rule, 0);
1801 kfree(cod);
1802 }
1803
1804 if (res)
1488 return -EINVAL; 1805 return -EINVAL;
1489 1806
1490 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access, 1807 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access,
@@ -1493,7 +1810,23 @@ static ssize_t smk_write_access(struct file *file, const char __user *buf,
1493 data[1] = '\0'; 1810 data[1] = '\0';
1494 1811
1495 simple_transaction_set(file, 2); 1812 simple_transaction_set(file, 2);
1496 return SMK_LOADLEN; 1813
1814 if (format == SMK_FIXED24_FMT)
1815 return SMK_LOADLEN;
1816 return count;
1817}
1818
1819/**
1820 * smk_write_access - handle access check transaction
1821 * @file: file pointer
1822 * @buf: data from user space
1823 * @count: bytes sent
1824 * @ppos: where to start - must be 0
1825 */
1826static ssize_t smk_write_access(struct file *file, const char __user *buf,
1827 size_t count, loff_t *ppos)
1828{
1829 return smk_user_access(file, buf, count, ppos, SMK_FIXED24_FMT);
1497} 1830}
1498 1831
1499static const struct file_operations smk_access_ops = { 1832static const struct file_operations smk_access_ops = {
@@ -1503,6 +1836,163 @@ static const struct file_operations smk_access_ops = {
1503 .llseek = generic_file_llseek, 1836 .llseek = generic_file_llseek,
1504}; 1837};
1505 1838
1839
1840/*
1841 * Seq_file read operations for /smack/load2
1842 */
1843
1844static int load2_seq_show(struct seq_file *s, void *v)
1845{
1846 struct list_head *list = v;
1847 struct smack_master_list *smlp =
1848 list_entry(list, struct smack_master_list, list);
1849
1850 smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL);
1851
1852 return 0;
1853}
1854
1855static const struct seq_operations load2_seq_ops = {
1856 .start = load2_seq_start,
1857 .next = load2_seq_next,
1858 .show = load2_seq_show,
1859 .stop = smk_seq_stop,
1860};
1861
1862/**
1863 * smk_open_load2 - open() for /smack/load2
1864 * @inode: inode structure representing file
1865 * @file: "load2" file pointer
1866 *
1867 * For reading, use load2_seq_* seq_file reading operations.
1868 */
1869static int smk_open_load2(struct inode *inode, struct file *file)
1870{
1871 return seq_open(file, &load2_seq_ops);
1872}
1873
1874/**
1875 * smk_write_load2 - write() for /smack/load2
1876 * @file: file pointer, not actually used
1877 * @buf: where to get the data from
1878 * @count: bytes sent
1879 * @ppos: where to start - must be 0
1880 *
1881 */
1882static ssize_t smk_write_load2(struct file *file, const char __user *buf,
1883 size_t count, loff_t *ppos)
1884{
1885 /*
1886 * Must have privilege.
1887 */
1888 if (!capable(CAP_MAC_ADMIN))
1889 return -EPERM;
1890
1891 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
1892 SMK_LONG_FMT);
1893}
1894
1895static const struct file_operations smk_load2_ops = {
1896 .open = smk_open_load2,
1897 .read = seq_read,
1898 .llseek = seq_lseek,
1899 .write = smk_write_load2,
1900 .release = seq_release,
1901};
1902
1903/*
1904 * Seq_file read operations for /smack/load-self2
1905 */
1906
1907static void *load_self2_seq_start(struct seq_file *s, loff_t *pos)
1908{
1909 struct task_smack *tsp = current_security();
1910
1911 return smk_seq_start(s, pos, &tsp->smk_rules);
1912}
1913
1914static void *load_self2_seq_next(struct seq_file *s, void *v, loff_t *pos)
1915{
1916 struct task_smack *tsp = current_security();
1917
1918 return smk_seq_next(s, v, pos, &tsp->smk_rules);
1919}
1920
1921static int load_self2_seq_show(struct seq_file *s, void *v)
1922{
1923 struct list_head *list = v;
1924 struct smack_rule *srp =
1925 list_entry(list, struct smack_rule, list);
1926
1927 smk_rule_show(s, srp, SMK_LONGLABEL);
1928
1929 return 0;
1930}
1931
1932static const struct seq_operations load_self2_seq_ops = {
1933 .start = load_self2_seq_start,
1934 .next = load_self2_seq_next,
1935 .show = load_self2_seq_show,
1936 .stop = smk_seq_stop,
1937};
1938
1939/**
1940 * smk_open_load_self2 - open() for /smack/load-self2
1941 * @inode: inode structure representing file
1942 * @file: "load" file pointer
1943 *
1944 * For reading, use load_seq_* seq_file reading operations.
1945 */
1946static int smk_open_load_self2(struct inode *inode, struct file *file)
1947{
1948 return seq_open(file, &load_self2_seq_ops);
1949}
1950
1951/**
1952 * smk_write_load_self2 - write() for /smack/load-self2
1953 * @file: file pointer, not actually used
1954 * @buf: where to get the data from
1955 * @count: bytes sent
1956 * @ppos: where to start - must be 0
1957 *
1958 */
1959static ssize_t smk_write_load_self2(struct file *file, const char __user *buf,
1960 size_t count, loff_t *ppos)
1961{
1962 struct task_smack *tsp = current_security();
1963
1964 return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules,
1965 &tsp->smk_rules_lock, SMK_LONG_FMT);
1966}
1967
1968static const struct file_operations smk_load_self2_ops = {
1969 .open = smk_open_load_self2,
1970 .read = seq_read,
1971 .llseek = seq_lseek,
1972 .write = smk_write_load_self2,
1973 .release = seq_release,
1974};
1975
1976/**
1977 * smk_write_access2 - handle access check transaction
1978 * @file: file pointer
1979 * @buf: data from user space
1980 * @count: bytes sent
1981 * @ppos: where to start - must be 0
1982 */
1983static ssize_t smk_write_access2(struct file *file, const char __user *buf,
1984 size_t count, loff_t *ppos)
1985{
1986 return smk_user_access(file, buf, count, ppos, SMK_LONG_FMT);
1987}
1988
1989static const struct file_operations smk_access2_ops = {
1990 .write = smk_write_access2,
1991 .read = simple_transaction_read,
1992 .release = simple_transaction_release,
1993 .llseek = generic_file_llseek,
1994};
1995
1506/** 1996/**
1507 * smk_fill_super - fill the /smackfs superblock 1997 * smk_fill_super - fill the /smackfs superblock
1508 * @sb: the empty superblock 1998 * @sb: the empty superblock
@@ -1539,6 +2029,16 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
1539 "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO}, 2029 "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
1540 [SMK_ACCESSES] = { 2030 [SMK_ACCESSES] = {
1541 "access", &smk_access_ops, S_IRUGO|S_IWUGO}, 2031 "access", &smk_access_ops, S_IRUGO|S_IWUGO},
2032 [SMK_MAPPED] = {
2033 "mapped", &smk_mapped_ops, S_IRUGO|S_IWUSR},
2034 [SMK_LOAD2] = {
2035 "load2", &smk_load2_ops, S_IRUGO|S_IWUSR},
2036 [SMK_LOAD_SELF2] = {
2037 "load-self2", &smk_load_self2_ops, S_IRUGO|S_IWUGO},
2038 [SMK_ACCESS2] = {
2039 "access2", &smk_access2_ops, S_IRUGO|S_IWUGO},
2040 [SMK_CIPSO2] = {
2041 "cipso2", &smk_cipso2_ops, S_IRUGO|S_IWUSR},
1542 /* last one */ 2042 /* last one */
1543 {""} 2043 {""}
1544 }; 2044 };
@@ -1581,6 +2081,15 @@ static struct file_system_type smk_fs_type = {
1581 2081
1582static struct vfsmount *smackfs_mount; 2082static struct vfsmount *smackfs_mount;
1583 2083
2084static int __init smk_preset_netlabel(struct smack_known *skp)
2085{
2086 skp->smk_netlabel.domain = skp->smk_known;
2087 skp->smk_netlabel.flags =
2088 NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
2089 return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
2090 &skp->smk_netlabel, strlen(skp->smk_known));
2091}
2092
1584/** 2093/**
1585 * init_smk_fs - get the smackfs superblock 2094 * init_smk_fs - get the smackfs superblock
1586 * 2095 *
@@ -1597,6 +2106,7 @@ static struct vfsmount *smackfs_mount;
1597static int __init init_smk_fs(void) 2106static int __init init_smk_fs(void)
1598{ 2107{
1599 int err; 2108 int err;
2109 int rc;
1600 2110
1601 if (!security_module_enable(&smack_ops)) 2111 if (!security_module_enable(&smack_ops))
1602 return 0; 2112 return 0;
@@ -1614,6 +2124,25 @@ static int __init init_smk_fs(void)
1614 smk_cipso_doi(); 2124 smk_cipso_doi();
1615 smk_unlbl_ambient(NULL); 2125 smk_unlbl_ambient(NULL);
1616 2126
2127 rc = smk_preset_netlabel(&smack_known_floor);
2128 if (err == 0 && rc < 0)
2129 err = rc;
2130 rc = smk_preset_netlabel(&smack_known_hat);
2131 if (err == 0 && rc < 0)
2132 err = rc;
2133 rc = smk_preset_netlabel(&smack_known_huh);
2134 if (err == 0 && rc < 0)
2135 err = rc;
2136 rc = smk_preset_netlabel(&smack_known_invalid);
2137 if (err == 0 && rc < 0)
2138 err = rc;
2139 rc = smk_preset_netlabel(&smack_known_star);
2140 if (err == 0 && rc < 0)
2141 err = rc;
2142 rc = smk_preset_netlabel(&smack_known_web);
2143 if (err == 0 && rc < 0)
2144 err = rc;
2145
1617 return err; 2146 return err;
1618} 2147}
1619 2148