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