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