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