Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
3 : : *
4 : : * This program is free software; you can redistribute it and/or modify
5 : : * it under the terms of the GNU General Public License as published by
6 : : * the Free Software Foundation, version 2.
7 : : *
8 : : * Authors:
9 : : * Casey Schaufler <casey@schaufler-ca.com>
10 : : * Ahmed S. Darwish <darwish.07@gmail.com>
11 : : *
12 : : * Special thanks to the authors of selinuxfs.
13 : : *
14 : : * Karl MacMillan <kmacmillan@tresys.com>
15 : : * James Morris <jmorris@redhat.com>
16 : : *
17 : : */
18 : :
19 : : #include <linux/kernel.h>
20 : : #include <linux/vmalloc.h>
21 : : #include <linux/security.h>
22 : : #include <linux/mutex.h>
23 : : #include <linux/slab.h>
24 : : #include <net/net_namespace.h>
25 : : #include <net/cipso_ipv4.h>
26 : : #include <linux/seq_file.h>
27 : : #include <linux/ctype.h>
28 : : #include <linux/audit.h>
29 : : #include <linux/magic.h>
30 : : #include "smack.h"
31 : :
32 : : /*
33 : : * smackfs pseudo filesystem.
34 : : */
35 : :
36 : : enum smk_inos {
37 : : SMK_ROOT_INO = 2,
38 : : SMK_LOAD = 3, /* load policy */
39 : : SMK_CIPSO = 4, /* load label -> CIPSO mapping */
40 : : SMK_DOI = 5, /* CIPSO DOI */
41 : : SMK_DIRECT = 6, /* CIPSO level indicating direct label */
42 : : SMK_AMBIENT = 7, /* internet ambient label */
43 : : SMK_NETLBLADDR = 8, /* single label hosts */
44 : : SMK_ONLYCAP = 9, /* the only "capable" label */
45 : : SMK_LOGGING = 10, /* logging */
46 : : SMK_LOAD_SELF = 11, /* task specific rules */
47 : : SMK_ACCESSES = 12, /* access policy */
48 : : SMK_MAPPED = 13, /* CIPSO level indicating mapped label */
49 : : SMK_LOAD2 = 14, /* load policy with long labels */
50 : : SMK_LOAD_SELF2 = 15, /* load task specific rules with long labels */
51 : : SMK_ACCESS2 = 16, /* make an access check with long labels */
52 : : SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */
53 : : SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */
54 : : SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
55 : : };
56 : :
57 : : /*
58 : : * List locks
59 : : */
60 : : static DEFINE_MUTEX(smack_cipso_lock);
61 : : static DEFINE_MUTEX(smack_ambient_lock);
62 : : static DEFINE_MUTEX(smk_netlbladdr_lock);
63 : :
64 : : /*
65 : : * This is the "ambient" label for network traffic.
66 : : * If it isn't somehow marked, use this.
67 : : * It can be reset via smackfs/ambient
68 : : */
69 : : struct smack_known *smack_net_ambient;
70 : :
71 : : /*
72 : : * This is the level in a CIPSO header that indicates a
73 : : * smack label is contained directly in the category set.
74 : : * It can be reset via smackfs/direct
75 : : */
76 : : int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
77 : :
78 : : /*
79 : : * This is the level in a CIPSO header that indicates a
80 : : * secid is contained directly in the category set.
81 : : * It can be reset via smackfs/mapped
82 : : */
83 : : int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
84 : :
85 : : /*
86 : : * Unless a process is running with this label even
87 : : * having CAP_MAC_OVERRIDE isn't enough to grant
88 : : * privilege to violate MAC policy. If no label is
89 : : * designated (the NULL case) capabilities apply to
90 : : * everyone. It is expected that the hat (^) label
91 : : * will be used if any label is used.
92 : : */
93 : : char *smack_onlycap;
94 : :
95 : : /*
96 : : * Certain IP addresses may be designated as single label hosts.
97 : : * Packets are sent there unlabeled, but only from tasks that
98 : : * can write to the specified label.
99 : : */
100 : :
101 : : LIST_HEAD(smk_netlbladdr_list);
102 : :
103 : : /*
104 : : * Rule lists are maintained for each label.
105 : : * This master list is just for reading /smack/load and /smack/load2.
106 : : */
107 : : struct smack_master_list {
108 : : struct list_head list;
109 : : struct smack_rule *smk_rule;
110 : : };
111 : :
112 : : LIST_HEAD(smack_rule_list);
113 : :
114 : : struct smack_parsed_rule {
115 : : struct smack_known *smk_subject;
116 : : char *smk_object;
117 : : int smk_access1;
118 : : int smk_access2;
119 : : };
120 : :
121 : : static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
122 : :
123 : : const char *smack_cipso_option = SMACK_CIPSO_OPTION;
124 : :
125 : : /*
126 : : * Values for parsing cipso rules
127 : : * SMK_DIGITLEN: Length of a digit field in a rule.
128 : : * SMK_CIPSOMIN: Minimum possible cipso rule length.
129 : : * SMK_CIPSOMAX: Maximum possible cipso rule length.
130 : : */
131 : : #define SMK_DIGITLEN 4
132 : : #define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN)
133 : : #define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN)
134 : :
135 : : /*
136 : : * Values for parsing MAC rules
137 : : * SMK_ACCESS: Maximum possible combination of access permissions
138 : : * SMK_ACCESSLEN: Maximum length for a rule access field
139 : : * SMK_LOADLEN: Smack rule length
140 : : */
141 : : #define SMK_OACCESS "rwxa"
142 : : #define SMK_ACCESS "rwxatl"
143 : : #define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1)
144 : : #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
145 : : #define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
146 : : #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
147 : :
148 : : /*
149 : : * Stricly for CIPSO level manipulation.
150 : : * Set the category bit number in a smack label sized buffer.
151 : : */
152 : : static inline void smack_catset_bit(unsigned int cat, char *catsetp)
153 : : {
154 [ # # ]: 0 : if (cat == 0 || cat > (SMK_CIPSOLEN * 8))
155 : : return;
156 : :
157 : 0 : catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8);
158 : : }
159 : :
160 : : /**
161 : : * smk_netlabel_audit_set - fill a netlbl_audit struct
162 : : * @nap: structure to fill
163 : : */
164 : 0 : static void smk_netlabel_audit_set(struct netlbl_audit *nap)
165 : : {
166 : : struct smack_known *skp = smk_of_current();
167 : :
168 : 0 : nap->loginuid = audit_get_loginuid(current);
169 : 0 : nap->sessionid = audit_get_sessionid(current);
170 : 0 : nap->secid = skp->smk_secid;
171 : 0 : }
172 : :
173 : : /*
174 : : * Value for parsing single label host rules
175 : : * "1.2.3.4 X"
176 : : */
177 : : #define SMK_NETLBLADDRMIN 9
178 : :
179 : : /**
180 : : * smk_set_access - add a rule to the rule list or replace an old rule
181 : : * @srp: the rule to add or replace
182 : : * @rule_list: the list of rules
183 : : * @rule_lock: the rule list lock
184 : : * @global: if non-zero, indicates a global rule
185 : : *
186 : : * Looks through the current subject/object/access list for
187 : : * the subject/object pair and replaces the access that was
188 : : * there. If the pair isn't found add it with the specified
189 : : * access.
190 : : *
191 : : * Returns 0 if nothing goes wrong or -ENOMEM if it fails
192 : : * during the allocation of the new pair to add.
193 : : */
194 : 0 : static int smk_set_access(struct smack_parsed_rule *srp,
195 : : struct list_head *rule_list,
196 : : struct mutex *rule_lock, int global)
197 : : {
198 : : struct smack_rule *sp;
199 : : struct smack_master_list *smlp;
200 : : int found = 0;
201 : : int rc = 0;
202 : :
203 : 0 : mutex_lock(rule_lock);
204 : :
205 : : /*
206 : : * Because the object label is less likely to match
207 : : * than the subject label check it first
208 : : */
209 [ # # ]: 0 : list_for_each_entry_rcu(sp, rule_list, list) {
210 [ # # ][ # # ]: 0 : if (sp->smk_object == srp->smk_object &&
211 : 0 : sp->smk_subject == srp->smk_subject) {
212 : : found = 1;
213 : 0 : sp->smk_access |= srp->smk_access1;
214 : 0 : sp->smk_access &= ~srp->smk_access2;
215 : 0 : break;
216 : : }
217 : : }
218 : :
219 [ # # ]: 0 : if (found == 0) {
220 : : sp = kzalloc(sizeof(*sp), GFP_KERNEL);
221 [ # # ]: 0 : if (sp == NULL) {
222 : : rc = -ENOMEM;
223 : : goto out;
224 : : }
225 : :
226 : 0 : sp->smk_subject = srp->smk_subject;
227 : 0 : sp->smk_object = srp->smk_object;
228 : 0 : sp->smk_access = srp->smk_access1 & ~srp->smk_access2;
229 : :
230 : 0 : list_add_rcu(&sp->list, rule_list);
231 : : /*
232 : : * If this is a global as opposed to self and a new rule
233 : : * it needs to get added for reporting.
234 : : */
235 [ # # ]: 0 : if (global) {
236 : : smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
237 [ # # ]: 0 : if (smlp != NULL) {
238 : 0 : smlp->smk_rule = sp;
239 : 0 : list_add_rcu(&smlp->list, &smack_rule_list);
240 : : } else
241 : : rc = -ENOMEM;
242 : : }
243 : : }
244 : :
245 : : out:
246 : 0 : mutex_unlock(rule_lock);
247 : 0 : return rc;
248 : : }
249 : :
250 : : /**
251 : : * smk_perm_from_str - parse smack accesses from a text string
252 : : * @string: a text string that contains a Smack accesses code
253 : : *
254 : : * Returns an integer with respective bits set for specified accesses.
255 : : */
256 : 0 : static int smk_perm_from_str(const char *string)
257 : : {
258 : : int perm = 0;
259 : : const char *cp;
260 : :
261 : 0 : for (cp = string; ; cp++)
262 [ # # # # : 0 : switch (*cp) {
# # # # ]
263 : : case '-':
264 : : break;
265 : : case 'r':
266 : : case 'R':
267 : 0 : perm |= MAY_READ;
268 : 0 : break;
269 : : case 'w':
270 : : case 'W':
271 : 0 : perm |= MAY_WRITE;
272 : 0 : break;
273 : : case 'x':
274 : : case 'X':
275 : 0 : perm |= MAY_EXEC;
276 : 0 : break;
277 : : case 'a':
278 : : case 'A':
279 : 0 : perm |= MAY_APPEND;
280 : 0 : break;
281 : : case 't':
282 : : case 'T':
283 : 0 : perm |= MAY_TRANSMUTE;
284 : 0 : break;
285 : : case 'l':
286 : : case 'L':
287 : 0 : perm |= MAY_LOCK;
288 : 0 : break;
289 : : default:
290 : 0 : return perm;
291 : : }
292 : 0 : }
293 : :
294 : : /**
295 : : * smk_fill_rule - Fill Smack rule from strings
296 : : * @subject: subject label string
297 : : * @object: object label string
298 : : * @access1: access string
299 : : * @access2: string with permissions to be removed
300 : : * @rule: Smack rule
301 : : * @import: if non-zero, import labels
302 : : * @len: label length limit
303 : : *
304 : : * Returns 0 on success, -1 on failure
305 : : */
306 : 0 : static int smk_fill_rule(const char *subject, const char *object,
307 : : const char *access1, const char *access2,
308 : : struct smack_parsed_rule *rule, int import,
309 : : int len)
310 : : {
311 : : const char *cp;
312 : : struct smack_known *skp;
313 : :
314 [ # # ]: 0 : if (import) {
315 : 0 : rule->smk_subject = smk_import_entry(subject, len);
316 [ # # ]: 0 : if (rule->smk_subject == NULL)
317 : : return -1;
318 : :
319 : 0 : rule->smk_object = smk_import(object, len);
320 [ # # ]: 0 : if (rule->smk_object == NULL)
321 : : return -1;
322 : : } else {
323 : 0 : cp = smk_parse_smack(subject, len);
324 [ # # ]: 0 : if (cp == NULL)
325 : : return -1;
326 : 0 : skp = smk_find_entry(cp);
327 : 0 : kfree(cp);
328 [ # # ]: 0 : if (skp == NULL)
329 : : return -1;
330 : 0 : rule->smk_subject = skp;
331 : :
332 : 0 : cp = smk_parse_smack(object, len);
333 [ # # ]: 0 : if (cp == NULL)
334 : : return -1;
335 : 0 : skp = smk_find_entry(cp);
336 : 0 : kfree(cp);
337 [ # # ]: 0 : if (skp == NULL)
338 : : return -1;
339 : 0 : rule->smk_object = skp->smk_known;
340 : : }
341 : :
342 : 0 : rule->smk_access1 = smk_perm_from_str(access1);
343 [ # # ]: 0 : if (access2)
344 : 0 : rule->smk_access2 = smk_perm_from_str(access2);
345 : : else
346 : 0 : rule->smk_access2 = ~rule->smk_access1;
347 : :
348 : : return 0;
349 : : }
350 : :
351 : : /**
352 : : * smk_parse_rule - parse Smack rule from load string
353 : : * @data: string to be parsed whose size is SMK_LOADLEN
354 : : * @rule: Smack rule
355 : : * @import: if non-zero, import labels
356 : : *
357 : : * Returns 0 on success, -1 on errors.
358 : : */
359 : 0 : static int smk_parse_rule(const char *data, struct smack_parsed_rule *rule,
360 : : int import)
361 : : {
362 : : int rc;
363 : :
364 : 0 : rc = smk_fill_rule(data, data + SMK_LABELLEN,
365 : : data + SMK_LABELLEN + SMK_LABELLEN, NULL, rule,
366 : : import, SMK_LABELLEN);
367 : 0 : return rc;
368 : : }
369 : :
370 : : /**
371 : : * smk_parse_long_rule - parse Smack rule from rule string
372 : : * @data: string to be parsed, null terminated
373 : : * @rule: Will be filled with Smack parsed rule
374 : : * @import: if non-zero, import labels
375 : : * @tokens: numer of substrings expected in data
376 : : *
377 : : * Returns number of processed bytes on success, -1 on failure.
378 : : */
379 : 0 : static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
380 : : int import, int tokens)
381 : : {
382 : : ssize_t cnt = 0;
383 : : char *tok[4];
384 : : int i;
385 : :
386 : : /*
387 : : * Parsing the rule in-place, filling all white-spaces with '\0'
388 : : */
389 [ # # ]: 0 : for (i = 0; i < tokens; ++i) {
390 [ # # ]: 0 : while (isspace(data[cnt]))
391 : 0 : data[cnt++] = '\0';
392 : :
393 [ # # ]: 0 : if (data[cnt] == '\0')
394 : : /* Unexpected end of data */
395 : : return -1;
396 : :
397 : 0 : tok[i] = data + cnt;
398 : :
399 [ # # ][ # # ]: 0 : while (data[cnt] && !isspace(data[cnt]))
400 : 0 : ++cnt;
401 : : }
402 [ # # ]: 0 : while (isspace(data[cnt]))
403 : 0 : data[cnt++] = '\0';
404 : :
405 [ # # ]: 0 : while (i < 4)
406 : 0 : tok[i++] = NULL;
407 : :
408 [ # # ]: 0 : if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0))
409 : : return -1;
410 : :
411 : 0 : return cnt;
412 : : }
413 : :
414 : : #define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */
415 : : #define SMK_LONG_FMT 1 /* Variable long label format */
416 : : #define SMK_CHANGE_FMT 2 /* Rule modification format */
417 : : /**
418 : : * smk_write_rules_list - write() for any /smack rule file
419 : : * @file: file pointer, not actually used
420 : : * @buf: where to get the data from
421 : : * @count: bytes sent
422 : : * @ppos: where to start - must be 0
423 : : * @rule_list: the list of rules to write to
424 : : * @rule_lock: lock for the rule list
425 : : * @format: /smack/load or /smack/load2 or /smack/change-rule format.
426 : : *
427 : : * Get one smack access rule from above.
428 : : * The format for SMK_LONG_FMT is:
429 : : * "subject<whitespace>object<whitespace>access[<whitespace>...]"
430 : : * The format for SMK_FIXED24_FMT is exactly:
431 : : * "subject object rwxat"
432 : : * The format for SMK_CHANGE_FMT is:
433 : : * "subject<whitespace>object<whitespace>
434 : : * acc_enable<whitespace>acc_disable[<whitespace>...]"
435 : : */
436 : 0 : static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
437 : : size_t count, loff_t *ppos,
438 : : struct list_head *rule_list,
439 : : struct mutex *rule_lock, int format)
440 : : {
441 : : struct smack_parsed_rule rule;
442 : : char *data;
443 : : int rc;
444 : : int trunc = 0;
445 : : int tokens;
446 : : ssize_t cnt = 0;
447 : :
448 : : /*
449 : : * No partial writes.
450 : : * Enough data must be present.
451 : : */
452 [ # # ]: 0 : if (*ppos != 0)
453 : : return -EINVAL;
454 : :
455 [ # # ]: 0 : if (format == SMK_FIXED24_FMT) {
456 : : /*
457 : : * Minor hack for backward compatibility
458 : : */
459 [ # # ]: 0 : if (count < SMK_OLOADLEN || count > SMK_LOADLEN)
460 : : return -EINVAL;
461 : : } else {
462 [ # # ]: 0 : if (count >= PAGE_SIZE) {
463 : : count = PAGE_SIZE - 1;
464 : : trunc = 1;
465 : : }
466 : : }
467 : :
468 : 0 : data = kmalloc(count + 1, GFP_KERNEL);
469 [ # # ]: 0 : if (data == NULL)
470 : : return -ENOMEM;
471 : :
472 [ # # ]: 0 : if (copy_from_user(data, buf, count) != 0) {
473 : : rc = -EFAULT;
474 : : goto out;
475 : : }
476 : :
477 : : /*
478 : : * In case of parsing only part of user buf,
479 : : * avoid having partial rule at the data buffer
480 : : */
481 [ # # ]: 0 : if (trunc) {
482 [ # # ][ # # ]: 0 : while (count > 0 && (data[count - 1] != '\n'))
483 : : --count;
484 [ # # ]: 0 : if (count == 0) {
485 : : rc = -EINVAL;
486 : : goto out;
487 : : }
488 : : }
489 : :
490 : 0 : data[count] = '\0';
491 [ # # ]: 0 : tokens = (format == SMK_CHANGE_FMT ? 4 : 3);
492 [ # # ]: 0 : while (cnt < count) {
493 [ # # ]: 0 : if (format == SMK_FIXED24_FMT) {
494 : 0 : rc = smk_parse_rule(data, &rule, 1);
495 [ # # ]: 0 : if (rc != 0) {
496 : : rc = -EINVAL;
497 : : goto out;
498 : : }
499 : 0 : cnt = count;
500 : : } else {
501 : 0 : rc = smk_parse_long_rule(data + cnt, &rule, 1, tokens);
502 [ # # ]: 0 : if (rc <= 0) {
503 : : rc = -EINVAL;
504 : : goto out;
505 : : }
506 : 0 : cnt += rc;
507 : : }
508 : :
509 [ # # ]: 0 : if (rule_list == NULL)
510 : 0 : rc = smk_set_access(&rule, &rule.smk_subject->smk_rules,
511 : : &rule.smk_subject->smk_rules_lock, 1);
512 : : else
513 : 0 : rc = smk_set_access(&rule, rule_list, rule_lock, 0);
514 : :
515 [ # # ]: 0 : if (rc)
516 : : goto out;
517 : : }
518 : :
519 : : rc = cnt;
520 : : out:
521 : 0 : kfree(data);
522 : : return rc;
523 : : }
524 : :
525 : : /*
526 : : * Core logic for smackfs seq list operations.
527 : : */
528 : :
529 : : static void *smk_seq_start(struct seq_file *s, loff_t *pos,
530 : : struct list_head *head)
531 : : {
532 : : struct list_head *list;
533 : :
534 : : /*
535 : : * This is 0 the first time through.
536 : : */
537 [ # # ][ # # ]: 0 : if (s->index == 0)
[ # # ][ # # ]
[ # # ]
538 : 0 : s->private = head;
539 : :
540 [ # # ][ # # ]: 0 : if (s->private == NULL)
[ # # ][ # # ]
[ # # ]
541 : : return NULL;
542 : :
543 : : list = s->private;
544 [ # # ][ # # ]: 0 : if (list_empty(list))
[ # # ][ # # ]
[ # # ]
545 : : return NULL;
546 : :
547 [ # # ][ # # ]: 0 : if (s->index == 0)
[ # # ][ # # ]
[ # # ]
548 : : return list->next;
549 : : return list;
550 : : }
551 : :
552 : : static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos,
553 : : struct list_head *head)
554 : : {
555 : 0 : struct list_head *list = v;
556 : :
557 [ # # ][ # # ]: 0 : if (list_is_last(list, head)) {
[ # # ][ # # ]
[ # # ]
558 : 0 : s->private = NULL;
559 : : return NULL;
560 : : }
561 : 0 : s->private = list->next;
562 : 0 : return list->next;
563 : : }
564 : :
565 : 0 : static void smk_seq_stop(struct seq_file *s, void *v)
566 : : {
567 : : /* No-op */
568 : 0 : }
569 : :
570 : 0 : static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
571 : : {
572 : : /*
573 : : * Don't show any rules with label names too long for
574 : : * interface file (/smack/load or /smack/load2)
575 : : * because you should expect to be able to write
576 : : * anything you read back.
577 : : */
578 [ # # ][ # # ]: 0 : if (strlen(srp->smk_subject->smk_known) >= max ||
579 : 0 : strlen(srp->smk_object) >= max)
580 : : return;
581 : :
582 [ # # ]: 0 : if (srp->smk_access == 0)
583 : : return;
584 : :
585 : 0 : seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object);
586 : :
587 : 0 : seq_putc(s, ' ');
588 : :
589 [ # # ]: 0 : if (srp->smk_access & MAY_READ)
590 : 0 : seq_putc(s, 'r');
591 [ # # ]: 0 : if (srp->smk_access & MAY_WRITE)
592 : 0 : seq_putc(s, 'w');
593 [ # # ]: 0 : if (srp->smk_access & MAY_EXEC)
594 : 0 : seq_putc(s, 'x');
595 [ # # ]: 0 : if (srp->smk_access & MAY_APPEND)
596 : 0 : seq_putc(s, 'a');
597 [ # # ]: 0 : if (srp->smk_access & MAY_TRANSMUTE)
598 : 0 : seq_putc(s, 't');
599 [ # # ]: 0 : if (srp->smk_access & MAY_LOCK)
600 : 0 : seq_putc(s, 'l');
601 : :
602 : 0 : seq_putc(s, '\n');
603 : : }
604 : :
605 : : /*
606 : : * Seq_file read operations for /smack/load
607 : : */
608 : :
609 : 0 : static void *load2_seq_start(struct seq_file *s, loff_t *pos)
610 : : {
611 : 0 : return smk_seq_start(s, pos, &smack_rule_list);
612 : : }
613 : :
614 : 0 : static void *load2_seq_next(struct seq_file *s, void *v, loff_t *pos)
615 : : {
616 : 0 : return smk_seq_next(s, v, pos, &smack_rule_list);
617 : : }
618 : :
619 : 0 : static int load_seq_show(struct seq_file *s, void *v)
620 : : {
621 : : struct list_head *list = v;
622 : : struct smack_master_list *smlp =
623 : : list_entry(list, struct smack_master_list, list);
624 : :
625 : 0 : smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN);
626 : :
627 : 0 : return 0;
628 : : }
629 : :
630 : : static const struct seq_operations load_seq_ops = {
631 : : .start = load2_seq_start,
632 : : .next = load2_seq_next,
633 : : .show = load_seq_show,
634 : : .stop = smk_seq_stop,
635 : : };
636 : :
637 : : /**
638 : : * smk_open_load - open() for /smack/load
639 : : * @inode: inode structure representing file
640 : : * @file: "load" file pointer
641 : : *
642 : : * For reading, use load_seq_* seq_file reading operations.
643 : : */
644 : 0 : static int smk_open_load(struct inode *inode, struct file *file)
645 : : {
646 : 0 : return seq_open(file, &load_seq_ops);
647 : : }
648 : :
649 : : /**
650 : : * smk_write_load - write() for /smack/load
651 : : * @file: file pointer, not actually used
652 : : * @buf: where to get the data from
653 : : * @count: bytes sent
654 : : * @ppos: where to start - must be 0
655 : : *
656 : : */
657 : 0 : static ssize_t smk_write_load(struct file *file, const char __user *buf,
658 : 0 : size_t count, loff_t *ppos)
659 : : {
660 : : /*
661 : : * Must have privilege.
662 : : * No partial writes.
663 : : * Enough data must be present.
664 : : */
665 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
666 : : return -EPERM;
667 : :
668 : 0 : return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
669 : : SMK_FIXED24_FMT);
670 : : }
671 : :
672 : : static const struct file_operations smk_load_ops = {
673 : : .open = smk_open_load,
674 : : .read = seq_read,
675 : : .llseek = seq_lseek,
676 : : .write = smk_write_load,
677 : : .release = seq_release,
678 : : };
679 : :
680 : : /**
681 : : * smk_cipso_doi - initialize the CIPSO domain
682 : : */
683 : 0 : static void smk_cipso_doi(void)
684 : : {
685 : : int rc;
686 : : struct cipso_v4_doi *doip;
687 : : struct netlbl_audit nai;
688 : :
689 : 0 : smk_netlabel_audit_set(&nai);
690 : :
691 : 0 : rc = netlbl_cfg_map_del(NULL, PF_INET, NULL, NULL, &nai);
692 [ # # ]: 0 : if (rc != 0)
693 : 0 : printk(KERN_WARNING "%s:%d remove rc = %d\n",
694 : : __func__, __LINE__, rc);
695 : :
696 : : doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL);
697 [ # # ]: 0 : if (doip == NULL)
698 : 0 : panic("smack: Failed to initialize cipso DOI.\n");
699 : 0 : doip->map.std = NULL;
700 : 0 : doip->doi = smk_cipso_doi_value;
701 : 0 : doip->type = CIPSO_V4_MAP_PASS;
702 : 0 : doip->tags[0] = CIPSO_V4_TAG_RBITMAP;
703 [ # # ]: 0 : for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
704 : 0 : doip->tags[rc] = CIPSO_V4_TAG_INVALID;
705 : :
706 : 0 : rc = netlbl_cfg_cipsov4_add(doip, &nai);
707 [ # # ]: 0 : if (rc != 0) {
708 : 0 : printk(KERN_WARNING "%s:%d cipso add rc = %d\n",
709 : : __func__, __LINE__, rc);
710 : 0 : kfree(doip);
711 : 0 : return;
712 : : }
713 : 0 : rc = netlbl_cfg_cipsov4_map_add(doip->doi, NULL, NULL, NULL, &nai);
714 [ # # ]: 0 : if (rc != 0) {
715 : 0 : printk(KERN_WARNING "%s:%d map add rc = %d\n",
716 : : __func__, __LINE__, rc);
717 : 0 : kfree(doip);
718 : 0 : return;
719 : : }
720 : : }
721 : :
722 : : /**
723 : : * smk_unlbl_ambient - initialize the unlabeled domain
724 : : * @oldambient: previous domain string
725 : : */
726 : 0 : static void smk_unlbl_ambient(char *oldambient)
727 : : {
728 : : int rc;
729 : : struct netlbl_audit nai;
730 : :
731 : 0 : smk_netlabel_audit_set(&nai);
732 : :
733 [ # # ]: 0 : if (oldambient != NULL) {
734 : 0 : rc = netlbl_cfg_map_del(oldambient, PF_INET, NULL, NULL, &nai);
735 [ # # ]: 0 : if (rc != 0)
736 : 0 : printk(KERN_WARNING "%s:%d remove rc = %d\n",
737 : : __func__, __LINE__, rc);
738 : : }
739 [ # # ]: 0 : if (smack_net_ambient == NULL)
740 : 0 : smack_net_ambient = &smack_known_floor;
741 : :
742 : 0 : rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
743 : : NULL, NULL, &nai);
744 [ # # ]: 0 : if (rc != 0)
745 : 0 : printk(KERN_WARNING "%s:%d add rc = %d\n",
746 : : __func__, __LINE__, rc);
747 : 0 : }
748 : :
749 : : /*
750 : : * Seq_file read operations for /smack/cipso
751 : : */
752 : :
753 : 0 : static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
754 : : {
755 : 0 : return smk_seq_start(s, pos, &smack_known_list);
756 : : }
757 : :
758 : 0 : static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
759 : : {
760 : 0 : return smk_seq_next(s, v, pos, &smack_known_list);
761 : : }
762 : :
763 : : /*
764 : : * Print cipso labels in format:
765 : : * label level[/cat[,cat]]
766 : : */
767 : 0 : static int cipso_seq_show(struct seq_file *s, void *v)
768 : : {
769 : : struct list_head *list = v;
770 : : struct smack_known *skp =
771 : : list_entry(list, struct smack_known, list);
772 : 0 : struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
773 : : char sep = '/';
774 : : int i;
775 : :
776 : : /*
777 : : * Don't show a label that could not have been set using
778 : : * /smack/cipso. This is in support of the notion that
779 : : * anything read from /smack/cipso ought to be writeable
780 : : * to /smack/cipso.
781 : : *
782 : : * /smack/cipso2 should be used instead.
783 : : */
784 [ # # ]: 0 : if (strlen(skp->smk_known) >= SMK_LABELLEN)
785 : : return 0;
786 : :
787 : 0 : seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
788 : :
789 [ # # ]: 0 : for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0;
790 : 0 : i = netlbl_secattr_catmap_walk(cmp, i + 1)) {
791 : 0 : seq_printf(s, "%c%d", sep, i);
792 : : sep = ',';
793 : : }
794 : :
795 : 0 : seq_putc(s, '\n');
796 : :
797 : 0 : return 0;
798 : : }
799 : :
800 : : static const struct seq_operations cipso_seq_ops = {
801 : : .start = cipso_seq_start,
802 : : .next = cipso_seq_next,
803 : : .show = cipso_seq_show,
804 : : .stop = smk_seq_stop,
805 : : };
806 : :
807 : : /**
808 : : * smk_open_cipso - open() for /smack/cipso
809 : : * @inode: inode structure representing file
810 : : * @file: "cipso" file pointer
811 : : *
812 : : * Connect our cipso_seq_* operations with /smack/cipso
813 : : * file_operations
814 : : */
815 : 0 : static int smk_open_cipso(struct inode *inode, struct file *file)
816 : : {
817 : 0 : return seq_open(file, &cipso_seq_ops);
818 : : }
819 : :
820 : : /**
821 : : * smk_set_cipso - do the work for write() for cipso and cipso2
822 : : * @file: file pointer, not actually used
823 : : * @buf: where to get the data from
824 : : * @count: bytes sent
825 : : * @ppos: where to start
826 : : * @format: /smack/cipso or /smack/cipso2
827 : : *
828 : : * Accepts only one cipso rule per write call.
829 : : * Returns number of bytes written or error code, as appropriate
830 : : */
831 : 0 : static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
832 : : size_t count, loff_t *ppos, int format)
833 : : {
834 : : struct smack_known *skp;
835 : : struct netlbl_lsm_secattr ncats;
836 : : char mapcatset[SMK_CIPSOLEN];
837 : : int maplevel;
838 : : unsigned int cat;
839 : : int catlen;
840 : : ssize_t rc = -EINVAL;
841 : : char *data = NULL;
842 : : char *rule;
843 : : int ret;
844 : : int i;
845 : :
846 : : /*
847 : : * Must have privilege.
848 : : * No partial writes.
849 : : * Enough data must be present.
850 : : */
851 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
852 : : return -EPERM;
853 [ # # ]: 0 : if (*ppos != 0)
854 : : return -EINVAL;
855 [ # # ][ # # ]: 0 : if (format == SMK_FIXED24_FMT &&
856 : 0 : (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
857 : : return -EINVAL;
858 : :
859 : 0 : data = kzalloc(count + 1, GFP_KERNEL);
860 [ # # ]: 0 : if (data == NULL)
861 : : return -ENOMEM;
862 : :
863 [ # # ]: 0 : if (copy_from_user(data, buf, count) != 0) {
864 : : rc = -EFAULT;
865 : : goto unlockedout;
866 : : }
867 : :
868 : 0 : data[count] = '\0';
869 : : rule = data;
870 : : /*
871 : : * Only allow one writer at a time. Writes should be
872 : : * quite rare and small in any case.
873 : : */
874 : 0 : mutex_lock(&smack_cipso_lock);
875 : :
876 : 0 : skp = smk_import_entry(rule, 0);
877 [ # # ]: 0 : if (skp == NULL)
878 : : goto out;
879 : :
880 [ # # ]: 0 : if (format == SMK_FIXED24_FMT)
881 : 0 : rule += SMK_LABELLEN;
882 : : else
883 : 0 : rule += strlen(skp->smk_known) + 1;
884 : :
885 : 0 : ret = sscanf(rule, "%d", &maplevel);
886 [ # # ][ # # ]: 0 : if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
887 : : goto out;
888 : :
889 : 0 : rule += SMK_DIGITLEN;
890 : 0 : ret = sscanf(rule, "%d", &catlen);
891 [ # # ][ # # ]: 0 : if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
892 : : goto out;
893 : :
894 [ # # ][ # # ]: 0 : if (format == SMK_FIXED24_FMT &&
895 : 0 : count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
896 : : goto out;
897 : :
898 : 0 : memset(mapcatset, 0, sizeof(mapcatset));
899 : :
900 [ # # ]: 0 : for (i = 0; i < catlen; i++) {
901 : 0 : rule += SMK_DIGITLEN;
902 : 0 : ret = sscanf(rule, "%u", &cat);
903 [ # # ][ # # ]: 0 : if (ret != 1 || cat > SMACK_CIPSO_MAXCATNUM)
904 : : goto out;
905 : :
906 : : smack_catset_bit(cat, mapcatset);
907 : : }
908 : :
909 : 0 : rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
910 [ # # ]: 0 : if (rc >= 0) {
911 : 0 : netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat);
912 : 0 : skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
913 : 0 : skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
914 : 0 : rc = count;
915 : : }
916 : :
917 : : out:
918 : 0 : mutex_unlock(&smack_cipso_lock);
919 : : unlockedout:
920 : 0 : kfree(data);
921 : : return rc;
922 : : }
923 : :
924 : : /**
925 : : * smk_write_cipso - write() for /smack/cipso
926 : : * @file: file pointer, not actually used
927 : : * @buf: where to get the data from
928 : : * @count: bytes sent
929 : : * @ppos: where to start
930 : : *
931 : : * Accepts only one cipso rule per write call.
932 : : * Returns number of bytes written or error code, as appropriate
933 : : */
934 : 0 : static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
935 : : size_t count, loff_t *ppos)
936 : : {
937 : 0 : return smk_set_cipso(file, buf, count, ppos, SMK_FIXED24_FMT);
938 : : }
939 : :
940 : : static const struct file_operations smk_cipso_ops = {
941 : : .open = smk_open_cipso,
942 : : .read = seq_read,
943 : : .llseek = seq_lseek,
944 : : .write = smk_write_cipso,
945 : : .release = seq_release,
946 : : };
947 : :
948 : : /*
949 : : * Seq_file read operations for /smack/cipso2
950 : : */
951 : :
952 : : /*
953 : : * Print cipso labels in format:
954 : : * label level[/cat[,cat]]
955 : : */
956 : 0 : static int cipso2_seq_show(struct seq_file *s, void *v)
957 : : {
958 : : struct list_head *list = v;
959 : : struct smack_known *skp =
960 : : list_entry(list, struct smack_known, list);
961 : 0 : struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
962 : : char sep = '/';
963 : : int i;
964 : :
965 : 0 : seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
966 : :
967 [ # # ]: 0 : for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0;
968 : 0 : i = netlbl_secattr_catmap_walk(cmp, i + 1)) {
969 : 0 : seq_printf(s, "%c%d", sep, i);
970 : : sep = ',';
971 : : }
972 : :
973 : 0 : seq_putc(s, '\n');
974 : :
975 : 0 : return 0;
976 : : }
977 : :
978 : : static const struct seq_operations cipso2_seq_ops = {
979 : : .start = cipso_seq_start,
980 : : .next = cipso_seq_next,
981 : : .show = cipso2_seq_show,
982 : : .stop = smk_seq_stop,
983 : : };
984 : :
985 : : /**
986 : : * smk_open_cipso2 - open() for /smack/cipso2
987 : : * @inode: inode structure representing file
988 : : * @file: "cipso2" file pointer
989 : : *
990 : : * Connect our cipso_seq_* operations with /smack/cipso2
991 : : * file_operations
992 : : */
993 : 0 : static int smk_open_cipso2(struct inode *inode, struct file *file)
994 : : {
995 : 0 : return seq_open(file, &cipso2_seq_ops);
996 : : }
997 : :
998 : : /**
999 : : * smk_write_cipso2 - write() for /smack/cipso2
1000 : : * @file: file pointer, not actually used
1001 : : * @buf: where to get the data from
1002 : : * @count: bytes sent
1003 : : * @ppos: where to start
1004 : : *
1005 : : * Accepts only one cipso rule per write call.
1006 : : * Returns number of bytes written or error code, as appropriate
1007 : : */
1008 : 0 : static ssize_t smk_write_cipso2(struct file *file, const char __user *buf,
1009 : : size_t count, loff_t *ppos)
1010 : : {
1011 : 0 : return smk_set_cipso(file, buf, count, ppos, SMK_LONG_FMT);
1012 : : }
1013 : :
1014 : : static const struct file_operations smk_cipso2_ops = {
1015 : : .open = smk_open_cipso2,
1016 : : .read = seq_read,
1017 : : .llseek = seq_lseek,
1018 : : .write = smk_write_cipso2,
1019 : : .release = seq_release,
1020 : : };
1021 : :
1022 : : /*
1023 : : * Seq_file read operations for /smack/netlabel
1024 : : */
1025 : :
1026 : 0 : static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos)
1027 : : {
1028 : 0 : return smk_seq_start(s, pos, &smk_netlbladdr_list);
1029 : : }
1030 : :
1031 : 0 : static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
1032 : : {
1033 : 0 : return smk_seq_next(s, v, pos, &smk_netlbladdr_list);
1034 : : }
1035 : : #define BEBITS (sizeof(__be32) * 8)
1036 : :
1037 : : /*
1038 : : * Print host/label pairs
1039 : : */
1040 : 0 : static int netlbladdr_seq_show(struct seq_file *s, void *v)
1041 : : {
1042 : : struct list_head *list = v;
1043 : : struct smk_netlbladdr *skp =
1044 : : list_entry(list, struct smk_netlbladdr, list);
1045 : : unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr;
1046 : : int maskn;
1047 [ # # ]: 0 : u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
1048 : :
1049 [ # # ]: 0 : for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++);
1050 : :
1051 : 0 : seq_printf(s, "%u.%u.%u.%u/%d %s\n",
1052 : 0 : hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label);
1053 : :
1054 : 0 : return 0;
1055 : : }
1056 : :
1057 : : static const struct seq_operations netlbladdr_seq_ops = {
1058 : : .start = netlbladdr_seq_start,
1059 : : .next = netlbladdr_seq_next,
1060 : : .show = netlbladdr_seq_show,
1061 : : .stop = smk_seq_stop,
1062 : : };
1063 : :
1064 : : /**
1065 : : * smk_open_netlbladdr - open() for /smack/netlabel
1066 : : * @inode: inode structure representing file
1067 : : * @file: "netlabel" file pointer
1068 : : *
1069 : : * Connect our netlbladdr_seq_* operations with /smack/netlabel
1070 : : * file_operations
1071 : : */
1072 : 0 : static int smk_open_netlbladdr(struct inode *inode, struct file *file)
1073 : : {
1074 : 0 : return seq_open(file, &netlbladdr_seq_ops);
1075 : : }
1076 : :
1077 : : /**
1078 : : * smk_netlbladdr_insert
1079 : : * @new : netlabel to insert
1080 : : *
1081 : : * This helper insert netlabel in the smack_netlbladdrs list
1082 : : * sorted by netmask length (longest to smallest)
1083 : : * locked by &smk_netlbladdr_lock in smk_write_netlbladdr
1084 : : *
1085 : : */
1086 : 0 : static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
1087 : : {
1088 : : struct smk_netlbladdr *m, *m_next;
1089 : :
1090 [ # # ]: 0 : if (list_empty(&smk_netlbladdr_list)) {
1091 : 0 : list_add_rcu(&new->list, &smk_netlbladdr_list);
1092 : : return;
1093 : : }
1094 : :
1095 : 0 : m = list_entry_rcu(smk_netlbladdr_list.next,
1096 : : struct smk_netlbladdr, list);
1097 : :
1098 : : /* the comparison '>' is a bit hacky, but works */
1099 [ # # ]: 0 : if (new->smk_mask.s_addr > m->smk_mask.s_addr) {
1100 : 0 : list_add_rcu(&new->list, &smk_netlbladdr_list);
1101 : : return;
1102 : : }
1103 : :
1104 [ # # ]: 0 : list_for_each_entry_rcu(m, &smk_netlbladdr_list, list) {
1105 [ # # ]: 0 : if (list_is_last(&m->list, &smk_netlbladdr_list)) {
1106 : 0 : list_add_rcu(&new->list, &m->list);
1107 : : return;
1108 : : }
1109 : 0 : m_next = list_entry_rcu(m->list.next,
1110 : : struct smk_netlbladdr, list);
1111 [ # # ]: 0 : if (new->smk_mask.s_addr > m_next->smk_mask.s_addr) {
1112 : 0 : list_add_rcu(&new->list, &m->list);
1113 : : return;
1114 : : }
1115 : : }
1116 : : }
1117 : :
1118 : :
1119 : : /**
1120 : : * smk_write_netlbladdr - write() for /smack/netlabel
1121 : : * @file: file pointer, not actually used
1122 : : * @buf: where to get the data from
1123 : : * @count: bytes sent
1124 : : * @ppos: where to start
1125 : : *
1126 : : * Accepts only one netlbladdr per write call.
1127 : : * Returns number of bytes written or error code, as appropriate
1128 : : */
1129 : 0 : static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1130 : : size_t count, loff_t *ppos)
1131 : : {
1132 : : struct smk_netlbladdr *skp;
1133 : : struct sockaddr_in newname;
1134 : : char *smack;
1135 : : char *sp;
1136 : : char *data;
1137 : : char *host = (char *)&newname.sin_addr.s_addr;
1138 : : int rc;
1139 : : struct netlbl_audit audit_info;
1140 : : struct in_addr mask;
1141 : : unsigned int m;
1142 : : int found;
1143 : : u32 mask_bits = (1<<31);
1144 : : __be32 nsa;
1145 : : u32 temp_mask;
1146 : :
1147 : : /*
1148 : : * Must have privilege.
1149 : : * No partial writes.
1150 : : * Enough data must be present.
1151 : : * "<addr/mask, as a.b.c.d/e><space><label>"
1152 : : * "<addr, as a.b.c.d><space><label>"
1153 : : */
1154 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
1155 : : return -EPERM;
1156 [ # # ]: 0 : if (*ppos != 0)
1157 : : return -EINVAL;
1158 [ # # ]: 0 : if (count < SMK_NETLBLADDRMIN)
1159 : : return -EINVAL;
1160 : :
1161 : 0 : data = kzalloc(count + 1, GFP_KERNEL);
1162 [ # # ]: 0 : if (data == NULL)
1163 : : return -ENOMEM;
1164 : :
1165 [ # # ]: 0 : if (copy_from_user(data, buf, count) != 0) {
1166 : : rc = -EFAULT;
1167 : : goto free_data_out;
1168 : : }
1169 : :
1170 : : smack = kzalloc(count + 1, GFP_KERNEL);
1171 [ # # ]: 0 : if (smack == NULL) {
1172 : : rc = -ENOMEM;
1173 : : goto free_data_out;
1174 : : }
1175 : :
1176 : 0 : data[count] = '\0';
1177 : :
1178 : 0 : rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s",
1179 : : &host[0], &host[1], &host[2], &host[3], &m, smack);
1180 [ # # ]: 0 : if (rc != 6) {
1181 : 0 : rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
1182 : : &host[0], &host[1], &host[2], &host[3], smack);
1183 [ # # ]: 0 : if (rc != 5) {
1184 : : rc = -EINVAL;
1185 : : goto free_out;
1186 : : }
1187 : 0 : m = BEBITS;
1188 : : }
1189 [ # # ]: 0 : if (m > BEBITS) {
1190 : : rc = -EINVAL;
1191 : : goto free_out;
1192 : : }
1193 : :
1194 : : /*
1195 : : * If smack begins with '-', it is an option, don't import it
1196 : : */
1197 [ # # ]: 0 : if (smack[0] != '-') {
1198 : 0 : sp = smk_import(smack, 0);
1199 [ # # ]: 0 : if (sp == NULL) {
1200 : : rc = -EINVAL;
1201 : : goto free_out;
1202 : : }
1203 : : } else {
1204 : : /* check known options */
1205 [ # # ]: 0 : if (strcmp(smack, smack_cipso_option) == 0)
1206 : : sp = (char *)smack_cipso_option;
1207 : : else {
1208 : : rc = -EINVAL;
1209 : : goto free_out;
1210 : : }
1211 : : }
1212 : :
1213 [ # # ]: 0 : for (temp_mask = 0; m > 0; m--) {
1214 : 0 : temp_mask |= mask_bits;
1215 : 0 : mask_bits >>= 1;
1216 : : }
1217 [ # # ]: 0 : mask.s_addr = cpu_to_be32(temp_mask);
1218 : :
1219 : 0 : newname.sin_addr.s_addr &= mask.s_addr;
1220 : : /*
1221 : : * Only allow one writer at a time. Writes should be
1222 : : * quite rare and small in any case.
1223 : : */
1224 : 0 : mutex_lock(&smk_netlbladdr_lock);
1225 : :
1226 : 0 : nsa = newname.sin_addr.s_addr;
1227 : : /* try to find if the prefix is already in the list */
1228 : : found = 0;
1229 [ # # ]: 0 : list_for_each_entry_rcu(skp, &smk_netlbladdr_list, list) {
1230 [ # # ][ # # ]: 0 : if (skp->smk_host.sin_addr.s_addr == nsa &&
1231 : 0 : skp->smk_mask.s_addr == mask.s_addr) {
1232 : : found = 1;
1233 : : break;
1234 : : }
1235 : : }
1236 : 0 : smk_netlabel_audit_set(&audit_info);
1237 : :
1238 [ # # ]: 0 : if (found == 0) {
1239 : : skp = kzalloc(sizeof(*skp), GFP_KERNEL);
1240 [ # # ]: 0 : if (skp == NULL)
1241 : : rc = -ENOMEM;
1242 : : else {
1243 : : rc = 0;
1244 : 0 : skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr;
1245 : 0 : skp->smk_mask.s_addr = mask.s_addr;
1246 : 0 : skp->smk_label = sp;
1247 : 0 : smk_netlbladdr_insert(skp);
1248 : : }
1249 : : } else {
1250 : : /* we delete the unlabeled entry, only if the previous label
1251 : : * wasn't the special CIPSO option */
1252 [ # # ]: 0 : if (skp->smk_label != smack_cipso_option)
1253 : 0 : rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
1254 : 0 : &skp->smk_host.sin_addr, &skp->smk_mask,
1255 : : PF_INET, &audit_info);
1256 : : else
1257 : : rc = 0;
1258 : 0 : skp->smk_label = sp;
1259 : : }
1260 : :
1261 : : /*
1262 : : * Now tell netlabel about the single label nature of
1263 : : * this host so that incoming packets get labeled.
1264 : : * but only if we didn't get the special CIPSO option
1265 : : */
1266 [ # # ][ # # ]: 0 : if (rc == 0 && sp != smack_cipso_option)
1267 : 0 : rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
1268 : 0 : &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET,
1269 : 0 : smack_to_secid(skp->smk_label), &audit_info);
1270 : :
1271 [ # # ]: 0 : if (rc == 0)
1272 : 0 : rc = count;
1273 : :
1274 : 0 : mutex_unlock(&smk_netlbladdr_lock);
1275 : :
1276 : : free_out:
1277 : 0 : kfree(smack);
1278 : : free_data_out:
1279 : 0 : kfree(data);
1280 : :
1281 : 0 : return rc;
1282 : : }
1283 : :
1284 : : static const struct file_operations smk_netlbladdr_ops = {
1285 : : .open = smk_open_netlbladdr,
1286 : : .read = seq_read,
1287 : : .llseek = seq_lseek,
1288 : : .write = smk_write_netlbladdr,
1289 : : .release = seq_release,
1290 : : };
1291 : :
1292 : : /**
1293 : : * smk_read_doi - read() for /smack/doi
1294 : : * @filp: file pointer, not actually used
1295 : : * @buf: where to put the result
1296 : : * @count: maximum to send along
1297 : : * @ppos: where to start
1298 : : *
1299 : : * Returns number of bytes read or error code, as appropriate
1300 : : */
1301 : 0 : static ssize_t smk_read_doi(struct file *filp, char __user *buf,
1302 : : size_t count, loff_t *ppos)
1303 : : {
1304 : : char temp[80];
1305 : : ssize_t rc;
1306 : :
1307 [ # # ]: 0 : if (*ppos != 0)
1308 : : return 0;
1309 : :
1310 : 0 : sprintf(temp, "%d", smk_cipso_doi_value);
1311 : 0 : rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1312 : :
1313 : 0 : return rc;
1314 : : }
1315 : :
1316 : : /**
1317 : : * smk_write_doi - write() for /smack/doi
1318 : : * @file: file pointer, not actually used
1319 : : * @buf: where to get the data from
1320 : : * @count: bytes sent
1321 : : * @ppos: where to start
1322 : : *
1323 : : * Returns number of bytes written or error code, as appropriate
1324 : : */
1325 : 0 : static ssize_t smk_write_doi(struct file *file, const char __user *buf,
1326 : : size_t count, loff_t *ppos)
1327 : : {
1328 : : char temp[80];
1329 : : int i;
1330 : :
1331 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
1332 : : return -EPERM;
1333 : :
1334 [ # # ]: 0 : if (count >= sizeof(temp) || count == 0)
1335 : : return -EINVAL;
1336 : :
1337 [ # # ]: 0 : if (copy_from_user(temp, buf, count) != 0)
1338 : : return -EFAULT;
1339 : :
1340 : 0 : temp[count] = '\0';
1341 : :
1342 [ # # ]: 0 : if (sscanf(temp, "%d", &i) != 1)
1343 : : return -EINVAL;
1344 : :
1345 : 0 : smk_cipso_doi_value = i;
1346 : :
1347 : 0 : smk_cipso_doi();
1348 : :
1349 : 0 : return count;
1350 : : }
1351 : :
1352 : : static const struct file_operations smk_doi_ops = {
1353 : : .read = smk_read_doi,
1354 : : .write = smk_write_doi,
1355 : : .llseek = default_llseek,
1356 : : };
1357 : :
1358 : : /**
1359 : : * smk_read_direct - read() for /smack/direct
1360 : : * @filp: file pointer, not actually used
1361 : : * @buf: where to put the result
1362 : : * @count: maximum to send along
1363 : : * @ppos: where to start
1364 : : *
1365 : : * Returns number of bytes read or error code, as appropriate
1366 : : */
1367 : 0 : static ssize_t smk_read_direct(struct file *filp, char __user *buf,
1368 : : size_t count, loff_t *ppos)
1369 : : {
1370 : : char temp[80];
1371 : : ssize_t rc;
1372 : :
1373 [ # # ]: 0 : if (*ppos != 0)
1374 : : return 0;
1375 : :
1376 : 0 : sprintf(temp, "%d", smack_cipso_direct);
1377 : 0 : rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1378 : :
1379 : 0 : return rc;
1380 : : }
1381 : :
1382 : : /**
1383 : : * smk_write_direct - write() for /smack/direct
1384 : : * @file: file pointer, not actually used
1385 : : * @buf: where to get the data from
1386 : : * @count: bytes sent
1387 : : * @ppos: where to start
1388 : : *
1389 : : * Returns number of bytes written or error code, as appropriate
1390 : : */
1391 : 0 : static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1392 : : size_t count, loff_t *ppos)
1393 : : {
1394 : : struct smack_known *skp;
1395 : : char temp[80];
1396 : : int i;
1397 : :
1398 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
1399 : : return -EPERM;
1400 : :
1401 [ # # ]: 0 : if (count >= sizeof(temp) || count == 0)
1402 : : return -EINVAL;
1403 : :
1404 [ # # ]: 0 : if (copy_from_user(temp, buf, count) != 0)
1405 : : return -EFAULT;
1406 : :
1407 : 0 : temp[count] = '\0';
1408 : :
1409 [ # # ]: 0 : if (sscanf(temp, "%d", &i) != 1)
1410 : : return -EINVAL;
1411 : :
1412 : : /*
1413 : : * Don't do anything if the value hasn't actually changed.
1414 : : * If it is changing reset the level on entries that were
1415 : : * set up to be direct when they were created.
1416 : : */
1417 [ # # ]: 0 : if (smack_cipso_direct != i) {
1418 : 0 : mutex_lock(&smack_known_lock);
1419 [ # # ]: 0 : list_for_each_entry_rcu(skp, &smack_known_list, list)
1420 [ # # ]: 0 : if (skp->smk_netlabel.attr.mls.lvl ==
1421 : : smack_cipso_direct)
1422 : 0 : skp->smk_netlabel.attr.mls.lvl = i;
1423 : 0 : smack_cipso_direct = i;
1424 : 0 : mutex_unlock(&smack_known_lock);
1425 : : }
1426 : :
1427 : 0 : return count;
1428 : : }
1429 : :
1430 : : static const struct file_operations smk_direct_ops = {
1431 : : .read = smk_read_direct,
1432 : : .write = smk_write_direct,
1433 : : .llseek = default_llseek,
1434 : : };
1435 : :
1436 : : /**
1437 : : * smk_read_mapped - read() for /smack/mapped
1438 : : * @filp: file pointer, not actually used
1439 : : * @buf: where to put the result
1440 : : * @count: maximum to send along
1441 : : * @ppos: where to start
1442 : : *
1443 : : * Returns number of bytes read or error code, as appropriate
1444 : : */
1445 : 0 : static ssize_t smk_read_mapped(struct file *filp, char __user *buf,
1446 : : size_t count, loff_t *ppos)
1447 : : {
1448 : : char temp[80];
1449 : : ssize_t rc;
1450 : :
1451 [ # # ]: 0 : if (*ppos != 0)
1452 : : return 0;
1453 : :
1454 : 0 : sprintf(temp, "%d", smack_cipso_mapped);
1455 : 0 : rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1456 : :
1457 : 0 : return rc;
1458 : : }
1459 : :
1460 : : /**
1461 : : * smk_write_mapped - write() for /smack/mapped
1462 : : * @file: file pointer, not actually used
1463 : : * @buf: where to get the data from
1464 : : * @count: bytes sent
1465 : : * @ppos: where to start
1466 : : *
1467 : : * Returns number of bytes written or error code, as appropriate
1468 : : */
1469 : 0 : static ssize_t smk_write_mapped(struct file *file, const char __user *buf,
1470 : : size_t count, loff_t *ppos)
1471 : : {
1472 : : struct smack_known *skp;
1473 : : char temp[80];
1474 : : int i;
1475 : :
1476 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
1477 : : return -EPERM;
1478 : :
1479 [ # # ]: 0 : if (count >= sizeof(temp) || count == 0)
1480 : : return -EINVAL;
1481 : :
1482 [ # # ]: 0 : if (copy_from_user(temp, buf, count) != 0)
1483 : : return -EFAULT;
1484 : :
1485 : 0 : temp[count] = '\0';
1486 : :
1487 [ # # ]: 0 : if (sscanf(temp, "%d", &i) != 1)
1488 : : return -EINVAL;
1489 : :
1490 : : /*
1491 : : * Don't do anything if the value hasn't actually changed.
1492 : : * If it is changing reset the level on entries that were
1493 : : * set up to be mapped when they were created.
1494 : : */
1495 [ # # ]: 0 : if (smack_cipso_mapped != i) {
1496 : 0 : mutex_lock(&smack_known_lock);
1497 [ # # ]: 0 : list_for_each_entry_rcu(skp, &smack_known_list, list)
1498 [ # # ]: 0 : if (skp->smk_netlabel.attr.mls.lvl ==
1499 : : smack_cipso_mapped)
1500 : 0 : skp->smk_netlabel.attr.mls.lvl = i;
1501 : 0 : smack_cipso_mapped = i;
1502 : 0 : mutex_unlock(&smack_known_lock);
1503 : : }
1504 : :
1505 : 0 : return count;
1506 : : }
1507 : :
1508 : : static const struct file_operations smk_mapped_ops = {
1509 : : .read = smk_read_mapped,
1510 : : .write = smk_write_mapped,
1511 : : .llseek = default_llseek,
1512 : : };
1513 : :
1514 : : /**
1515 : : * smk_read_ambient - read() for /smack/ambient
1516 : : * @filp: file pointer, not actually used
1517 : : * @buf: where to put the result
1518 : : * @cn: maximum to send along
1519 : : * @ppos: where to start
1520 : : *
1521 : : * Returns number of bytes read or error code, as appropriate
1522 : : */
1523 : 0 : static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1524 : : size_t cn, loff_t *ppos)
1525 : : {
1526 : : ssize_t rc;
1527 : : int asize;
1528 : :
1529 [ # # ]: 0 : if (*ppos != 0)
1530 : : return 0;
1531 : : /*
1532 : : * Being careful to avoid a problem in the case where
1533 : : * smack_net_ambient gets changed in midstream.
1534 : : */
1535 : 0 : mutex_lock(&smack_ambient_lock);
1536 : :
1537 : 0 : asize = strlen(smack_net_ambient->smk_known) + 1;
1538 : :
1539 [ # # ]: 0 : if (cn >= asize)
1540 : 0 : rc = simple_read_from_buffer(buf, cn, ppos,
1541 : : smack_net_ambient->smk_known,
1542 : : asize);
1543 : : else
1544 : : rc = -EINVAL;
1545 : :
1546 : 0 : mutex_unlock(&smack_ambient_lock);
1547 : :
1548 : 0 : return rc;
1549 : : }
1550 : :
1551 : : /**
1552 : : * smk_write_ambient - write() for /smack/ambient
1553 : : * @file: file pointer, not actually used
1554 : : * @buf: where to get the data from
1555 : : * @count: bytes sent
1556 : : * @ppos: where to start
1557 : : *
1558 : : * Returns number of bytes written or error code, as appropriate
1559 : : */
1560 : 0 : static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1561 : : size_t count, loff_t *ppos)
1562 : : {
1563 : : struct smack_known *skp;
1564 : : char *oldambient;
1565 : : char *data;
1566 : 0 : int rc = count;
1567 : :
1568 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
1569 : : return -EPERM;
1570 : :
1571 : 0 : data = kzalloc(count + 1, GFP_KERNEL);
1572 [ # # ]: 0 : if (data == NULL)
1573 : : return -ENOMEM;
1574 : :
1575 [ # # ]: 0 : if (copy_from_user(data, buf, count) != 0) {
1576 : : rc = -EFAULT;
1577 : : goto out;
1578 : : }
1579 : :
1580 : 0 : skp = smk_import_entry(data, count);
1581 [ # # ]: 0 : if (skp == NULL) {
1582 : : rc = -EINVAL;
1583 : : goto out;
1584 : : }
1585 : :
1586 : 0 : mutex_lock(&smack_ambient_lock);
1587 : :
1588 : 0 : oldambient = smack_net_ambient->smk_known;
1589 : 0 : smack_net_ambient = skp;
1590 : 0 : smk_unlbl_ambient(oldambient);
1591 : :
1592 : 0 : mutex_unlock(&smack_ambient_lock);
1593 : :
1594 : : out:
1595 : 0 : kfree(data);
1596 : 0 : return rc;
1597 : : }
1598 : :
1599 : : static const struct file_operations smk_ambient_ops = {
1600 : : .read = smk_read_ambient,
1601 : : .write = smk_write_ambient,
1602 : : .llseek = default_llseek,
1603 : : };
1604 : :
1605 : : /**
1606 : : * smk_read_onlycap - read() for /smack/onlycap
1607 : : * @filp: file pointer, not actually used
1608 : : * @buf: where to put the result
1609 : : * @cn: maximum to send along
1610 : : * @ppos: where to start
1611 : : *
1612 : : * Returns number of bytes read or error code, as appropriate
1613 : : */
1614 : 0 : static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1615 : : size_t cn, loff_t *ppos)
1616 : : {
1617 : : char *smack = "";
1618 : : ssize_t rc = -EINVAL;
1619 : : int asize;
1620 : :
1621 [ # # ]: 0 : if (*ppos != 0)
1622 : : return 0;
1623 : :
1624 [ # # ]: 0 : if (smack_onlycap != NULL)
1625 : : smack = smack_onlycap;
1626 : :
1627 : 0 : asize = strlen(smack) + 1;
1628 : :
1629 [ # # ]: 0 : if (cn >= asize)
1630 : 0 : rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
1631 : :
1632 : 0 : return rc;
1633 : : }
1634 : :
1635 : : /**
1636 : : * smk_write_onlycap - write() for /smack/onlycap
1637 : : * @file: file pointer, not actually used
1638 : : * @buf: where to get the data from
1639 : : * @count: bytes sent
1640 : : * @ppos: where to start
1641 : : *
1642 : : * Returns number of bytes written or error code, as appropriate
1643 : : */
1644 : 0 : static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1645 : : size_t count, loff_t *ppos)
1646 : : {
1647 : : char *data;
1648 : 0 : struct smack_known *skp = smk_of_task(current->cred->security);
1649 : 0 : int rc = count;
1650 : :
1651 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
1652 : : return -EPERM;
1653 : :
1654 : : /*
1655 : : * This can be done using smk_access() but is done
1656 : : * explicitly for clarity. The smk_access() implementation
1657 : : * would use smk_access(smack_onlycap, MAY_WRITE)
1658 : : */
1659 [ # # ][ # # ]: 0 : if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
1660 : : return -EPERM;
1661 : :
1662 : : data = kzalloc(count, GFP_KERNEL);
1663 [ # # ]: 0 : if (data == NULL)
1664 : : return -ENOMEM;
1665 : :
1666 : : /*
1667 : : * Should the null string be passed in unset the onlycap value.
1668 : : * This seems like something to be careful with as usually
1669 : : * smk_import only expects to return NULL for errors. It
1670 : : * is usually the case that a nullstring or "\n" would be
1671 : : * bad to pass to smk_import but in fact this is useful here.
1672 : : *
1673 : : * smk_import will also reject a label beginning with '-',
1674 : : * so "-usecapabilities" will also work.
1675 : : */
1676 [ # # ]: 0 : if (copy_from_user(data, buf, count) != 0)
1677 : : rc = -EFAULT;
1678 : : else
1679 : 0 : smack_onlycap = smk_import(data, count);
1680 : :
1681 : 0 : kfree(data);
1682 : 0 : return rc;
1683 : : }
1684 : :
1685 : : static const struct file_operations smk_onlycap_ops = {
1686 : : .read = smk_read_onlycap,
1687 : : .write = smk_write_onlycap,
1688 : : .llseek = default_llseek,
1689 : : };
1690 : :
1691 : : /**
1692 : : * smk_read_logging - read() for /smack/logging
1693 : : * @filp: file pointer, not actually used
1694 : : * @buf: where to put the result
1695 : : * @cn: maximum to send along
1696 : : * @ppos: where to start
1697 : : *
1698 : : * Returns number of bytes read or error code, as appropriate
1699 : : */
1700 : 0 : static ssize_t smk_read_logging(struct file *filp, char __user *buf,
1701 : : size_t count, loff_t *ppos)
1702 : : {
1703 : : char temp[32];
1704 : : ssize_t rc;
1705 : :
1706 [ # # ]: 0 : if (*ppos != 0)
1707 : : return 0;
1708 : :
1709 : 0 : sprintf(temp, "%d\n", log_policy);
1710 : 0 : rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1711 : 0 : return rc;
1712 : : }
1713 : :
1714 : : /**
1715 : : * smk_write_logging - write() for /smack/logging
1716 : : * @file: file pointer, not actually used
1717 : : * @buf: where to get the data from
1718 : : * @count: bytes sent
1719 : : * @ppos: where to start
1720 : : *
1721 : : * Returns number of bytes written or error code, as appropriate
1722 : : */
1723 : 0 : static ssize_t smk_write_logging(struct file *file, const char __user *buf,
1724 : : size_t count, loff_t *ppos)
1725 : : {
1726 : : char temp[32];
1727 : : int i;
1728 : :
1729 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
1730 : : return -EPERM;
1731 : :
1732 [ # # ]: 0 : if (count >= sizeof(temp) || count == 0)
1733 : : return -EINVAL;
1734 : :
1735 [ # # ]: 0 : if (copy_from_user(temp, buf, count) != 0)
1736 : : return -EFAULT;
1737 : :
1738 : 0 : temp[count] = '\0';
1739 : :
1740 [ # # ]: 0 : if (sscanf(temp, "%d", &i) != 1)
1741 : : return -EINVAL;
1742 [ # # ]: 0 : if (i < 0 || i > 3)
1743 : : return -EINVAL;
1744 : 0 : log_policy = i;
1745 : 0 : return count;
1746 : : }
1747 : :
1748 : :
1749 : :
1750 : : static const struct file_operations smk_logging_ops = {
1751 : : .read = smk_read_logging,
1752 : : .write = smk_write_logging,
1753 : : .llseek = default_llseek,
1754 : : };
1755 : :
1756 : : /*
1757 : : * Seq_file read operations for /smack/load-self
1758 : : */
1759 : :
1760 : 0 : static void *load_self_seq_start(struct seq_file *s, loff_t *pos)
1761 : : {
1762 : 0 : struct task_smack *tsp = current_security();
1763 : :
1764 : 0 : return smk_seq_start(s, pos, &tsp->smk_rules);
1765 : : }
1766 : :
1767 : 0 : static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos)
1768 : : {
1769 : 0 : struct task_smack *tsp = current_security();
1770 : :
1771 : 0 : return smk_seq_next(s, v, pos, &tsp->smk_rules);
1772 : : }
1773 : :
1774 : 0 : static int load_self_seq_show(struct seq_file *s, void *v)
1775 : : {
1776 : : struct list_head *list = v;
1777 : : struct smack_rule *srp =
1778 : : list_entry(list, struct smack_rule, list);
1779 : :
1780 : 0 : smk_rule_show(s, srp, SMK_LABELLEN);
1781 : :
1782 : 0 : return 0;
1783 : : }
1784 : :
1785 : : static const struct seq_operations load_self_seq_ops = {
1786 : : .start = load_self_seq_start,
1787 : : .next = load_self_seq_next,
1788 : : .show = load_self_seq_show,
1789 : : .stop = smk_seq_stop,
1790 : : };
1791 : :
1792 : :
1793 : : /**
1794 : : * smk_open_load_self - open() for /smack/load-self2
1795 : : * @inode: inode structure representing file
1796 : : * @file: "load" file pointer
1797 : : *
1798 : : * For reading, use load_seq_* seq_file reading operations.
1799 : : */
1800 : 0 : static int smk_open_load_self(struct inode *inode, struct file *file)
1801 : : {
1802 : 0 : return seq_open(file, &load_self_seq_ops);
1803 : : }
1804 : :
1805 : : /**
1806 : : * smk_write_load_self - write() for /smack/load-self
1807 : : * @file: file pointer, not actually used
1808 : : * @buf: where to get the data from
1809 : : * @count: bytes sent
1810 : : * @ppos: where to start - must be 0
1811 : : *
1812 : : */
1813 : 0 : static ssize_t smk_write_load_self(struct file *file, const char __user *buf,
1814 : 0 : size_t count, loff_t *ppos)
1815 : : {
1816 : 0 : struct task_smack *tsp = current_security();
1817 : :
1818 : 0 : return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules,
1819 : : &tsp->smk_rules_lock, SMK_FIXED24_FMT);
1820 : : }
1821 : :
1822 : : static const struct file_operations smk_load_self_ops = {
1823 : : .open = smk_open_load_self,
1824 : : .read = seq_read,
1825 : : .llseek = seq_lseek,
1826 : : .write = smk_write_load_self,
1827 : : .release = seq_release,
1828 : : };
1829 : :
1830 : : /**
1831 : : * smk_user_access - handle access check transaction
1832 : : * @file: file pointer
1833 : : * @buf: data from user space
1834 : : * @count: bytes sent
1835 : : * @ppos: where to start - must be 0
1836 : : */
1837 : 0 : static ssize_t smk_user_access(struct file *file, const char __user *buf,
1838 : : size_t count, loff_t *ppos, int format)
1839 : : {
1840 : : struct smack_parsed_rule rule;
1841 : : char *data;
1842 : : int res;
1843 : :
1844 : 0 : data = simple_transaction_get(file, buf, count);
1845 [ # # ]: 0 : if (IS_ERR(data))
1846 : : return PTR_ERR(data);
1847 : :
1848 [ # # ]: 0 : if (format == SMK_FIXED24_FMT) {
1849 [ # # ]: 0 : if (count < SMK_LOADLEN)
1850 : : return -EINVAL;
1851 : 0 : res = smk_parse_rule(data, &rule, 0);
1852 : : } else {
1853 : : /*
1854 : : * simple_transaction_get() returns null-terminated data
1855 : : */
1856 : 0 : res = smk_parse_long_rule(data, &rule, 0, 3);
1857 : : }
1858 : :
1859 [ # # ]: 0 : if (res < 0)
1860 : : return -EINVAL;
1861 : :
1862 : 0 : res = smk_access(rule.smk_subject, rule.smk_object,
1863 : : rule.smk_access1, NULL);
1864 [ # # ]: 0 : data[0] = res == 0 ? '1' : '0';
1865 : 0 : data[1] = '\0';
1866 : :
1867 : 0 : simple_transaction_set(file, 2);
1868 : :
1869 [ # # ]: 0 : if (format == SMK_FIXED24_FMT)
1870 : : return SMK_LOADLEN;
1871 : 0 : return count;
1872 : : }
1873 : :
1874 : : /**
1875 : : * smk_write_access - handle access check transaction
1876 : : * @file: file pointer
1877 : : * @buf: data from user space
1878 : : * @count: bytes sent
1879 : : * @ppos: where to start - must be 0
1880 : : */
1881 : 0 : static ssize_t smk_write_access(struct file *file, const char __user *buf,
1882 : : size_t count, loff_t *ppos)
1883 : : {
1884 : 0 : return smk_user_access(file, buf, count, ppos, SMK_FIXED24_FMT);
1885 : : }
1886 : :
1887 : : static const struct file_operations smk_access_ops = {
1888 : : .write = smk_write_access,
1889 : : .read = simple_transaction_read,
1890 : : .release = simple_transaction_release,
1891 : : .llseek = generic_file_llseek,
1892 : : };
1893 : :
1894 : :
1895 : : /*
1896 : : * Seq_file read operations for /smack/load2
1897 : : */
1898 : :
1899 : 0 : static int load2_seq_show(struct seq_file *s, void *v)
1900 : : {
1901 : : struct list_head *list = v;
1902 : : struct smack_master_list *smlp =
1903 : : list_entry(list, struct smack_master_list, list);
1904 : :
1905 : 0 : smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL);
1906 : :
1907 : 0 : return 0;
1908 : : }
1909 : :
1910 : : static const struct seq_operations load2_seq_ops = {
1911 : : .start = load2_seq_start,
1912 : : .next = load2_seq_next,
1913 : : .show = load2_seq_show,
1914 : : .stop = smk_seq_stop,
1915 : : };
1916 : :
1917 : : /**
1918 : : * smk_open_load2 - open() for /smack/load2
1919 : : * @inode: inode structure representing file
1920 : : * @file: "load2" file pointer
1921 : : *
1922 : : * For reading, use load2_seq_* seq_file reading operations.
1923 : : */
1924 : 0 : static int smk_open_load2(struct inode *inode, struct file *file)
1925 : : {
1926 : 0 : return seq_open(file, &load2_seq_ops);
1927 : : }
1928 : :
1929 : : /**
1930 : : * smk_write_load2 - write() for /smack/load2
1931 : : * @file: file pointer, not actually used
1932 : : * @buf: where to get the data from
1933 : : * @count: bytes sent
1934 : : * @ppos: where to start - must be 0
1935 : : *
1936 : : */
1937 : 0 : static ssize_t smk_write_load2(struct file *file, const char __user *buf,
1938 : 0 : size_t count, loff_t *ppos)
1939 : : {
1940 : : /*
1941 : : * Must have privilege.
1942 : : */
1943 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
1944 : : return -EPERM;
1945 : :
1946 : 0 : return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
1947 : : SMK_LONG_FMT);
1948 : : }
1949 : :
1950 : : static const struct file_operations smk_load2_ops = {
1951 : : .open = smk_open_load2,
1952 : : .read = seq_read,
1953 : : .llseek = seq_lseek,
1954 : : .write = smk_write_load2,
1955 : : .release = seq_release,
1956 : : };
1957 : :
1958 : : /*
1959 : : * Seq_file read operations for /smack/load-self2
1960 : : */
1961 : :
1962 : 0 : static void *load_self2_seq_start(struct seq_file *s, loff_t *pos)
1963 : : {
1964 : 0 : struct task_smack *tsp = current_security();
1965 : :
1966 : 0 : return smk_seq_start(s, pos, &tsp->smk_rules);
1967 : : }
1968 : :
1969 : 0 : static void *load_self2_seq_next(struct seq_file *s, void *v, loff_t *pos)
1970 : : {
1971 : 0 : struct task_smack *tsp = current_security();
1972 : :
1973 : 0 : return smk_seq_next(s, v, pos, &tsp->smk_rules);
1974 : : }
1975 : :
1976 : 0 : static int load_self2_seq_show(struct seq_file *s, void *v)
1977 : : {
1978 : : struct list_head *list = v;
1979 : : struct smack_rule *srp =
1980 : : list_entry(list, struct smack_rule, list);
1981 : :
1982 : 0 : smk_rule_show(s, srp, SMK_LONGLABEL);
1983 : :
1984 : 0 : return 0;
1985 : : }
1986 : :
1987 : : static const struct seq_operations load_self2_seq_ops = {
1988 : : .start = load_self2_seq_start,
1989 : : .next = load_self2_seq_next,
1990 : : .show = load_self2_seq_show,
1991 : : .stop = smk_seq_stop,
1992 : : };
1993 : :
1994 : : /**
1995 : : * smk_open_load_self2 - open() for /smack/load-self2
1996 : : * @inode: inode structure representing file
1997 : : * @file: "load" file pointer
1998 : : *
1999 : : * For reading, use load_seq_* seq_file reading operations.
2000 : : */
2001 : 0 : static int smk_open_load_self2(struct inode *inode, struct file *file)
2002 : : {
2003 : 0 : return seq_open(file, &load_self2_seq_ops);
2004 : : }
2005 : :
2006 : : /**
2007 : : * smk_write_load_self2 - write() for /smack/load-self2
2008 : : * @file: file pointer, not actually used
2009 : : * @buf: where to get the data from
2010 : : * @count: bytes sent
2011 : : * @ppos: where to start - must be 0
2012 : : *
2013 : : */
2014 : 0 : static ssize_t smk_write_load_self2(struct file *file, const char __user *buf,
2015 : 0 : size_t count, loff_t *ppos)
2016 : : {
2017 : 0 : struct task_smack *tsp = current_security();
2018 : :
2019 : 0 : return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules,
2020 : : &tsp->smk_rules_lock, SMK_LONG_FMT);
2021 : : }
2022 : :
2023 : : static const struct file_operations smk_load_self2_ops = {
2024 : : .open = smk_open_load_self2,
2025 : : .read = seq_read,
2026 : : .llseek = seq_lseek,
2027 : : .write = smk_write_load_self2,
2028 : : .release = seq_release,
2029 : : };
2030 : :
2031 : : /**
2032 : : * smk_write_access2 - handle access check transaction
2033 : : * @file: file pointer
2034 : : * @buf: data from user space
2035 : : * @count: bytes sent
2036 : : * @ppos: where to start - must be 0
2037 : : */
2038 : 0 : static ssize_t smk_write_access2(struct file *file, const char __user *buf,
2039 : : size_t count, loff_t *ppos)
2040 : : {
2041 : 0 : return smk_user_access(file, buf, count, ppos, SMK_LONG_FMT);
2042 : : }
2043 : :
2044 : : static const struct file_operations smk_access2_ops = {
2045 : : .write = smk_write_access2,
2046 : : .read = simple_transaction_read,
2047 : : .release = simple_transaction_release,
2048 : : .llseek = generic_file_llseek,
2049 : : };
2050 : :
2051 : : /**
2052 : : * smk_write_revoke_subj - write() for /smack/revoke-subject
2053 : : * @file: file pointer
2054 : : * @buf: data from user space
2055 : : * @count: bytes sent
2056 : : * @ppos: where to start - must be 0
2057 : : */
2058 : 0 : static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf,
2059 : : size_t count, loff_t *ppos)
2060 : : {
2061 : : char *data = NULL;
2062 : : const char *cp = NULL;
2063 : : struct smack_known *skp;
2064 : : struct smack_rule *sp;
2065 : : struct list_head *rule_list;
2066 : : struct mutex *rule_lock;
2067 : 0 : int rc = count;
2068 : :
2069 [ # # ]: 0 : if (*ppos != 0)
2070 : : return -EINVAL;
2071 : :
2072 [ # # ]: 0 : if (!smack_privileged(CAP_MAC_ADMIN))
2073 : : return -EPERM;
2074 : :
2075 [ # # ]: 0 : if (count == 0 || count > SMK_LONGLABEL)
2076 : : return -EINVAL;
2077 : :
2078 : : data = kzalloc(count, GFP_KERNEL);
2079 [ # # ]: 0 : if (data == NULL)
2080 : : return -ENOMEM;
2081 : :
2082 [ # # ]: 0 : if (copy_from_user(data, buf, count) != 0) {
2083 : : rc = -EFAULT;
2084 : : goto free_out;
2085 : : }
2086 : :
2087 : 0 : cp = smk_parse_smack(data, count);
2088 [ # # ]: 0 : if (cp == NULL) {
2089 : : rc = -EINVAL;
2090 : : goto free_out;
2091 : : }
2092 : :
2093 : 0 : skp = smk_find_entry(cp);
2094 [ # # ]: 0 : if (skp == NULL)
2095 : : goto free_out;
2096 : :
2097 : 0 : rule_list = &skp->smk_rules;
2098 : 0 : rule_lock = &skp->smk_rules_lock;
2099 : :
2100 : 0 : mutex_lock(rule_lock);
2101 : :
2102 [ # # ]: 0 : list_for_each_entry_rcu(sp, rule_list, list)
2103 : 0 : sp->smk_access = 0;
2104 : :
2105 : 0 : mutex_unlock(rule_lock);
2106 : :
2107 : : free_out:
2108 : 0 : kfree(data);
2109 : 0 : kfree(cp);
2110 : 0 : return rc;
2111 : : }
2112 : :
2113 : : static const struct file_operations smk_revoke_subj_ops = {
2114 : : .write = smk_write_revoke_subj,
2115 : : .read = simple_transaction_read,
2116 : : .release = simple_transaction_release,
2117 : : .llseek = generic_file_llseek,
2118 : : };
2119 : :
2120 : : static struct kset *smackfs_kset;
2121 : : /**
2122 : : * smk_init_sysfs - initialize /sys/fs/smackfs
2123 : : *
2124 : : */
2125 : 0 : static int smk_init_sysfs(void)
2126 : : {
2127 : 0 : smackfs_kset = kset_create_and_add("smackfs", NULL, fs_kobj);
2128 [ # # ]: 0 : if (!smackfs_kset)
2129 : : return -ENOMEM;
2130 : 0 : return 0;
2131 : : }
2132 : :
2133 : : /**
2134 : : * smk_write_change_rule - write() for /smack/change-rule
2135 : : * @file: file pointer
2136 : : * @buf: data from user space
2137 : : * @count: bytes sent
2138 : : * @ppos: where to start - must be 0
2139 : : */
2140 : 0 : static ssize_t smk_write_change_rule(struct file *file, const char __user *buf,
2141 : 0 : size_t count, loff_t *ppos)
2142 : : {
2143 : : /*
2144 : : * Must have privilege.
2145 : : */
2146 [ # # ]: 0 : if (!capable(CAP_MAC_ADMIN))
2147 : : return -EPERM;
2148 : :
2149 : 0 : return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
2150 : : SMK_CHANGE_FMT);
2151 : : }
2152 : :
2153 : : static const struct file_operations smk_change_rule_ops = {
2154 : : .write = smk_write_change_rule,
2155 : : .read = simple_transaction_read,
2156 : : .release = simple_transaction_release,
2157 : : .llseek = generic_file_llseek,
2158 : : };
2159 : :
2160 : : /**
2161 : : * smk_fill_super - fill the /smackfs superblock
2162 : : * @sb: the empty superblock
2163 : : * @data: unused
2164 : : * @silent: unused
2165 : : *
2166 : : * Fill in the well known entries for /smack
2167 : : *
2168 : : * Returns 0 on success, an error code on failure
2169 : : */
2170 : 0 : static int smk_fill_super(struct super_block *sb, void *data, int silent)
2171 : : {
2172 : : int rc;
2173 : : struct inode *root_inode;
2174 : :
2175 : : static struct tree_descr smack_files[] = {
2176 : : [SMK_LOAD] = {
2177 : : "load", &smk_load_ops, S_IRUGO|S_IWUSR},
2178 : : [SMK_CIPSO] = {
2179 : : "cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR},
2180 : : [SMK_DOI] = {
2181 : : "doi", &smk_doi_ops, S_IRUGO|S_IWUSR},
2182 : : [SMK_DIRECT] = {
2183 : : "direct", &smk_direct_ops, S_IRUGO|S_IWUSR},
2184 : : [SMK_AMBIENT] = {
2185 : : "ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
2186 : : [SMK_NETLBLADDR] = {
2187 : : "netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR},
2188 : : [SMK_ONLYCAP] = {
2189 : : "onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
2190 : : [SMK_LOGGING] = {
2191 : : "logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
2192 : : [SMK_LOAD_SELF] = {
2193 : : "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
2194 : : [SMK_ACCESSES] = {
2195 : : "access", &smk_access_ops, S_IRUGO|S_IWUGO},
2196 : : [SMK_MAPPED] = {
2197 : : "mapped", &smk_mapped_ops, S_IRUGO|S_IWUSR},
2198 : : [SMK_LOAD2] = {
2199 : : "load2", &smk_load2_ops, S_IRUGO|S_IWUSR},
2200 : : [SMK_LOAD_SELF2] = {
2201 : : "load-self2", &smk_load_self2_ops, S_IRUGO|S_IWUGO},
2202 : : [SMK_ACCESS2] = {
2203 : : "access2", &smk_access2_ops, S_IRUGO|S_IWUGO},
2204 : : [SMK_CIPSO2] = {
2205 : : "cipso2", &smk_cipso2_ops, S_IRUGO|S_IWUSR},
2206 : : [SMK_REVOKE_SUBJ] = {
2207 : : "revoke-subject", &smk_revoke_subj_ops,
2208 : : S_IRUGO|S_IWUSR},
2209 : : [SMK_CHANGE_RULE] = {
2210 : : "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
2211 : : /* last one */
2212 : : {""}
2213 : : };
2214 : :
2215 : 0 : rc = simple_fill_super(sb, SMACK_MAGIC, smack_files);
2216 [ # # ]: 0 : if (rc != 0) {
2217 : 0 : printk(KERN_ERR "%s failed %d while creating inodes\n",
2218 : : __func__, rc);
2219 : 0 : return rc;
2220 : : }
2221 : :
2222 : : root_inode = sb->s_root->d_inode;
2223 : :
2224 : : return 0;
2225 : : }
2226 : :
2227 : : /**
2228 : : * smk_mount - get the smackfs superblock
2229 : : * @fs_type: passed along without comment
2230 : : * @flags: passed along without comment
2231 : : * @dev_name: passed along without comment
2232 : : * @data: passed along without comment
2233 : : *
2234 : : * Just passes everything along.
2235 : : *
2236 : : * Returns what the lower level code does.
2237 : : */
2238 : 0 : static struct dentry *smk_mount(struct file_system_type *fs_type,
2239 : : int flags, const char *dev_name, void *data)
2240 : : {
2241 : 0 : return mount_single(fs_type, flags, data, smk_fill_super);
2242 : : }
2243 : :
2244 : : static struct file_system_type smk_fs_type = {
2245 : : .name = "smackfs",
2246 : : .mount = smk_mount,
2247 : : .kill_sb = kill_litter_super,
2248 : : };
2249 : :
2250 : : static struct vfsmount *smackfs_mount;
2251 : :
2252 : 0 : static int __init smk_preset_netlabel(struct smack_known *skp)
2253 : : {
2254 : 0 : skp->smk_netlabel.domain = skp->smk_known;
2255 : 0 : skp->smk_netlabel.flags =
2256 : : NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
2257 : 0 : return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
2258 : 0 : &skp->smk_netlabel, strlen(skp->smk_known));
2259 : : }
2260 : :
2261 : : /**
2262 : : * init_smk_fs - get the smackfs superblock
2263 : : *
2264 : : * register the smackfs
2265 : : *
2266 : : * Do not register smackfs if Smack wasn't enabled
2267 : : * on boot. We can not put this method normally under the
2268 : : * smack_init() code path since the security subsystem get
2269 : : * initialized before the vfs caches.
2270 : : *
2271 : : * Returns true if we were not chosen on boot or if
2272 : : * we were chosen and filesystem registration succeeded.
2273 : : */
2274 : 0 : static int __init init_smk_fs(void)
2275 : : {
2276 : : int err;
2277 : : int rc;
2278 : :
2279 [ # # ]: 0 : if (!security_module_enable(&smack_ops))
2280 : : return 0;
2281 : :
2282 : 0 : err = smk_init_sysfs();
2283 [ # # ]: 0 : if (err)
2284 : 0 : printk(KERN_ERR "smackfs: sysfs mountpoint problem.\n");
2285 : :
2286 : 0 : err = register_filesystem(&smk_fs_type);
2287 [ # # ]: 0 : if (!err) {
2288 : 0 : smackfs_mount = kern_mount(&smk_fs_type);
2289 [ # # ]: 0 : if (IS_ERR(smackfs_mount)) {
2290 : 0 : printk(KERN_ERR "smackfs: could not mount!\n");
2291 : 0 : err = PTR_ERR(smackfs_mount);
2292 : 0 : smackfs_mount = NULL;
2293 : : }
2294 : : }
2295 : :
2296 : 0 : smk_cipso_doi();
2297 : 0 : smk_unlbl_ambient(NULL);
2298 : :
2299 : 0 : rc = smk_preset_netlabel(&smack_known_floor);
2300 [ # # ]: 0 : if (err == 0 && rc < 0)
2301 : : err = rc;
2302 : 0 : rc = smk_preset_netlabel(&smack_known_hat);
2303 [ # # ]: 0 : if (err == 0 && rc < 0)
2304 : : err = rc;
2305 : 0 : rc = smk_preset_netlabel(&smack_known_huh);
2306 [ # # ]: 0 : if (err == 0 && rc < 0)
2307 : : err = rc;
2308 : 0 : rc = smk_preset_netlabel(&smack_known_invalid);
2309 [ # # ]: 0 : if (err == 0 && rc < 0)
2310 : : err = rc;
2311 : 0 : rc = smk_preset_netlabel(&smack_known_star);
2312 [ # # ]: 0 : if (err == 0 && rc < 0)
2313 : : err = rc;
2314 : 0 : rc = smk_preset_netlabel(&smack_known_web);
2315 [ # # ]: 0 : if (err == 0 && rc < 0)
2316 : : err = rc;
2317 : :
2318 : 0 : return err;
2319 : : }
2320 : :
2321 : : __initcall(init_smk_fs);
|