]> err.no Git - linux-2.6/blob - security/smack/smackfs.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6
[linux-2.6] / security / smack / smackfs.c
1 /*
2  * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
3  *
4  *      This program is free software; you can redistribute it and/or modify
5  *      it under the terms of the GNU General Public License as published by
6  *      the Free Software Foundation, version 2.
7  *
8  * Authors:
9  *      Casey Schaufler <casey@schaufler-ca.com>
10  *      Ahmed S. Darwish <darwish.07@gmail.com>
11  *
12  * Special thanks to the authors of selinuxfs.
13  *
14  *      Karl MacMillan <kmacmillan@tresys.com>
15  *      James Morris <jmorris@redhat.com>
16  *
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/vmalloc.h>
21 #include <linux/security.h>
22 #include <linux/mutex.h>
23 #include <net/netlabel.h>
24 #include <net/cipso_ipv4.h>
25 #include <linux/seq_file.h>
26 #include <linux/ctype.h>
27 #include <linux/audit.h>
28 #include "smack.h"
29
30 /*
31  * smackfs pseudo filesystem.
32  */
33
34 enum smk_inos {
35         SMK_ROOT_INO    = 2,
36         SMK_LOAD        = 3,    /* load policy */
37         SMK_CIPSO       = 4,    /* load label -> CIPSO mapping */
38         SMK_DOI         = 5,    /* CIPSO DOI */
39         SMK_DIRECT      = 6,    /* CIPSO level indicating direct label */
40         SMK_AMBIENT     = 7,    /* internet ambient label */
41         SMK_NLTYPE      = 8,    /* label scheme to use by default */
42 };
43
44 /*
45  * List locks
46  */
47 static DEFINE_MUTEX(smack_list_lock);
48 static DEFINE_MUTEX(smack_cipso_lock);
49 static DEFINE_MUTEX(smack_ambient_lock);
50
51 /*
52  * This is the "ambient" label for network traffic.
53  * If it isn't somehow marked, use this.
54  * It can be reset via smackfs/ambient
55  */
56 char *smack_net_ambient = smack_known_floor.smk_known;
57
58 /*
59  * This is the default packet marking scheme for network traffic.
60  * It can be reset via smackfs/nltype
61  */
62 int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4;
63
64 /*
65  * This is the level in a CIPSO header that indicates a
66  * smack label is contained directly in the category set.
67  * It can be reset via smackfs/direct
68  */
69 int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
70
71 static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
72 struct smk_list_entry *smack_list;
73
74 #define SEQ_READ_FINISHED       1
75
76 /*
77  * Disable concurrent writing open() operations
78  */
79 static struct semaphore smack_write_sem;
80
81 /*
82  * Values for parsing cipso rules
83  * SMK_DIGITLEN: Length of a digit field in a rule.
84  * SMK_CIPSOMIN: Minimum possible cipso rule length.
85  * SMK_CIPSOMAX: Maximum possible cipso rule length.
86  */
87 #define SMK_DIGITLEN 4
88 #define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN)
89 #define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN)
90
91 /*
92  * Values for parsing MAC rules
93  * SMK_ACCESS: Maximum possible combination of access permissions
94  * SMK_ACCESSLEN: Maximum length for a rule access field
95  * SMK_LOADLEN: Smack rule length
96  */
97 #define SMK_ACCESS    "rwxa"
98 #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
99 #define SMK_LOADLEN   (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
100
101
102 /*
103  * Seq_file read operations for /smack/load
104  */
105
106 static void *load_seq_start(struct seq_file *s, loff_t *pos)
107 {
108         if (*pos == SEQ_READ_FINISHED)
109                 return NULL;
110
111         return smack_list;
112 }
113
114 static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
115 {
116         struct smk_list_entry *skp = ((struct smk_list_entry *) v)->smk_next;
117
118         if (skp == NULL)
119                 *pos = SEQ_READ_FINISHED;
120
121         return skp;
122 }
123
124 static int load_seq_show(struct seq_file *s, void *v)
125 {
126         struct smk_list_entry *slp = (struct smk_list_entry *) v;
127         struct smack_rule *srp = &slp->smk_rule;
128
129         seq_printf(s, "%s %s", (char *)srp->smk_subject,
130                    (char *)srp->smk_object);
131
132         seq_putc(s, ' ');
133
134         if (srp->smk_access & MAY_READ)
135                 seq_putc(s, 'r');
136         if (srp->smk_access & MAY_WRITE)
137                 seq_putc(s, 'w');
138         if (srp->smk_access & MAY_EXEC)
139                 seq_putc(s, 'x');
140         if (srp->smk_access & MAY_APPEND)
141                 seq_putc(s, 'a');
142         if (srp->smk_access == 0)
143                 seq_putc(s, '-');
144
145         seq_putc(s, '\n');
146
147         return 0;
148 }
149
150 static void load_seq_stop(struct seq_file *s, void *v)
151 {
152         /* No-op */
153 }
154
155 static struct seq_operations load_seq_ops = {
156         .start = load_seq_start,
157         .next  = load_seq_next,
158         .show  = load_seq_show,
159         .stop  = load_seq_stop,
160 };
161
162 /**
163  * smk_open_load - open() for /smack/load
164  * @inode: inode structure representing file
165  * @file: "load" file pointer
166  *
167  * For reading, use load_seq_* seq_file reading operations.
168  */
169 static int smk_open_load(struct inode *inode, struct file *file)
170 {
171         if ((file->f_flags & O_ACCMODE) == O_RDONLY)
172                 return seq_open(file, &load_seq_ops);
173
174         if (down_interruptible(&smack_write_sem))
175                 return -ERESTARTSYS;
176
177         return 0;
178 }
179
180 /**
181  * smk_release_load - release() for /smack/load
182  * @inode: inode structure representing file
183  * @file: "load" file pointer
184  *
185  * For a reading session, use the seq_file release
186  * implementation.
187  * Otherwise, we are at the end of a writing session so
188  * clean everything up.
189  */
190 static int smk_release_load(struct inode *inode, struct file *file)
191 {
192         if ((file->f_flags & O_ACCMODE) == O_RDONLY)
193                 return seq_release(inode, file);
194
195         up(&smack_write_sem);
196         return 0;
197 }
198
199 /**
200  * smk_set_access - add a rule to the rule list
201  * @srp: the new rule to add
202  *
203  * Looks through the current subject/object/access list for
204  * the subject/object pair and replaces the access that was
205  * there. If the pair isn't found add it with the specified
206  * access.
207  */
208 static void smk_set_access(struct smack_rule *srp)
209 {
210         struct smk_list_entry *sp;
211         struct smk_list_entry *newp;
212
213         mutex_lock(&smack_list_lock);
214
215         for (sp = smack_list; sp != NULL; sp = sp->smk_next)
216                 if (sp->smk_rule.smk_subject == srp->smk_subject &&
217                     sp->smk_rule.smk_object == srp->smk_object) {
218                         sp->smk_rule.smk_access = srp->smk_access;
219                         break;
220                 }
221
222         if (sp == NULL) {
223                 newp = kzalloc(sizeof(struct smk_list_entry), GFP_KERNEL);
224                 newp->smk_rule = *srp;
225                 newp->smk_next = smack_list;
226                 smack_list = newp;
227         }
228
229         mutex_unlock(&smack_list_lock);
230
231         return;
232 }
233
234 /**
235  * smk_write_load - write() for /smack/load
236  * @filp: file pointer, not actually used
237  * @buf: where to get the data from
238  * @count: bytes sent
239  * @ppos: where to start - must be 0
240  *
241  * Get one smack access rule from above.
242  * The format is exactly:
243  *     char subject[SMK_LABELLEN]
244  *     char object[SMK_LABELLEN]
245  *     char access[SMK_ACCESSLEN]
246  *
247  * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
248  */
249 static ssize_t smk_write_load(struct file *file, const char __user *buf,
250                               size_t count, loff_t *ppos)
251 {
252         struct smack_rule rule;
253         char *data;
254         int rc = -EINVAL;
255
256         /*
257          * Must have privilege.
258          * No partial writes.
259          * Enough data must be present.
260          */
261         if (!capable(CAP_MAC_ADMIN))
262                 return -EPERM;
263         if (*ppos != 0)
264                 return -EINVAL;
265         if (count != SMK_LOADLEN)
266                 return -EINVAL;
267
268         data = kzalloc(count, GFP_KERNEL);
269         if (data == NULL)
270                 return -ENOMEM;
271
272         if (copy_from_user(data, buf, count) != 0) {
273                 rc = -EFAULT;
274                 goto out;
275         }
276
277         rule.smk_subject = smk_import(data, 0);
278         if (rule.smk_subject == NULL)
279                 goto out;
280
281         rule.smk_object = smk_import(data + SMK_LABELLEN, 0);
282         if (rule.smk_object == NULL)
283                 goto out;
284
285         rule.smk_access = 0;
286
287         switch (data[SMK_LABELLEN + SMK_LABELLEN]) {
288         case '-':
289                 break;
290         case 'r':
291         case 'R':
292                 rule.smk_access |= MAY_READ;
293                 break;
294         default:
295                 goto out;
296         }
297
298         switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
299         case '-':
300                 break;
301         case 'w':
302         case 'W':
303                 rule.smk_access |= MAY_WRITE;
304                 break;
305         default:
306                 goto out;
307         }
308
309         switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
310         case '-':
311                 break;
312         case 'x':
313         case 'X':
314                 rule.smk_access |= MAY_EXEC;
315                 break;
316         default:
317                 goto out;
318         }
319
320         switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
321         case '-':
322                 break;
323         case 'a':
324         case 'A':
325                 rule.smk_access |= MAY_READ;
326                 break;
327         default:
328                 goto out;
329         }
330
331         smk_set_access(&rule);
332         rc = count;
333
334 out:
335         kfree(data);
336         return rc;
337 }
338
339 static const struct file_operations smk_load_ops = {
340         .open           = smk_open_load,
341         .read           = seq_read,
342         .llseek         = seq_lseek,
343         .write          = smk_write_load,
344         .release        = smk_release_load,
345 };
346
347 /**
348  * smk_cipso_doi - initialize the CIPSO domain
349  */
350 void smk_cipso_doi(void)
351 {
352         int rc;
353         struct cipso_v4_doi *doip;
354         struct netlbl_audit audit_info;
355
356         audit_info.loginuid = audit_get_loginuid(current);
357         audit_info.secid = smack_to_secid(current->security);
358
359         rc = netlbl_cfg_map_del(NULL, &audit_info);
360         if (rc != 0)
361                 printk(KERN_WARNING "%s:%d remove rc = %d\n",
362                        __func__, __LINE__, rc);
363
364         doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL);
365         if (doip == NULL)
366                 panic("smack:  Failed to initialize cipso DOI.\n");
367         doip->map.std = NULL;
368         doip->doi = smk_cipso_doi_value;
369         doip->type = CIPSO_V4_MAP_PASS;
370         doip->tags[0] = CIPSO_V4_TAG_RBITMAP;
371         for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
372                 doip->tags[rc] = CIPSO_V4_TAG_INVALID;
373
374         rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info);
375         if (rc != 0)
376                 printk(KERN_WARNING "%s:%d add rc = %d\n",
377                        __func__, __LINE__, rc);
378 }
379
380 /**
381  * smk_unlbl_ambient - initialize the unlabeled domain
382  */
383 void smk_unlbl_ambient(char *oldambient)
384 {
385         int rc;
386         struct netlbl_audit audit_info;
387
388         audit_info.loginuid = audit_get_loginuid(current);
389         audit_info.secid = smack_to_secid(current->security);
390
391         if (oldambient != NULL) {
392                 rc = netlbl_cfg_map_del(oldambient, &audit_info);
393                 if (rc != 0)
394                         printk(KERN_WARNING "%s:%d remove rc = %d\n",
395                                __func__, __LINE__, rc);
396         }
397
398         rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info);
399         if (rc != 0)
400                 printk(KERN_WARNING "%s:%d add rc = %d\n",
401                        __func__, __LINE__, rc);
402 }
403
404 /*
405  * Seq_file read operations for /smack/cipso
406  */
407
408 static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
409 {
410         if (*pos == SEQ_READ_FINISHED)
411                 return NULL;
412
413         return smack_known;
414 }
415
416 static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
417 {
418         struct smack_known *skp = ((struct smack_known *) v)->smk_next;
419
420         /*
421          * Omit labels with no associated cipso value
422          */
423         while (skp != NULL && !skp->smk_cipso)
424                 skp = skp->smk_next;
425
426         if (skp == NULL)
427                 *pos = SEQ_READ_FINISHED;
428
429         return skp;
430 }
431
432 /*
433  * Print cipso labels in format:
434  * label level[/cat[,cat]]
435  */
436 static int cipso_seq_show(struct seq_file *s, void *v)
437 {
438         struct smack_known *skp = (struct smack_known *) v;
439         struct smack_cipso *scp = skp->smk_cipso;
440         char *cbp;
441         char sep = '/';
442         int cat = 1;
443         int i;
444         unsigned char m;
445
446         if (scp == NULL)
447                 return 0;
448
449         seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level);
450
451         cbp = scp->smk_catset;
452         for (i = 0; i < SMK_LABELLEN; i++)
453                 for (m = 0x80; m != 0; m >>= 1) {
454                         if (m & cbp[i]) {
455                                 seq_printf(s, "%c%d", sep, cat);
456                                 sep = ',';
457                         }
458                         cat++;
459                 }
460
461         seq_putc(s, '\n');
462
463         return 0;
464 }
465
466 static void cipso_seq_stop(struct seq_file *s, void *v)
467 {
468         /* No-op */
469 }
470
471 static struct seq_operations cipso_seq_ops = {
472         .start = cipso_seq_start,
473         .stop  = cipso_seq_stop,
474         .next  = cipso_seq_next,
475         .show  = cipso_seq_show,
476 };
477
478 /**
479  * smk_open_cipso - open() for /smack/cipso
480  * @inode: inode structure representing file
481  * @file: "cipso" file pointer
482  *
483  * Connect our cipso_seq_* operations with /smack/cipso
484  * file_operations
485  */
486 static int smk_open_cipso(struct inode *inode, struct file *file)
487 {
488         return seq_open(file, &cipso_seq_ops);
489 }
490
491 /**
492  * smk_write_cipso - write() for /smack/cipso
493  * @filp: file pointer, not actually used
494  * @buf: where to get the data from
495  * @count: bytes sent
496  * @ppos: where to start
497  *
498  * Accepts only one cipso rule per write call.
499  * Returns number of bytes written or error code, as appropriate
500  */
501 static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
502                                size_t count, loff_t *ppos)
503 {
504         struct smack_known *skp;
505         struct smack_cipso *scp = NULL;
506         char mapcatset[SMK_LABELLEN];
507         int maplevel;
508         int cat;
509         int catlen;
510         ssize_t rc = -EINVAL;
511         char *data = NULL;
512         char *rule;
513         int ret;
514         int i;
515
516         /*
517          * Must have privilege.
518          * No partial writes.
519          * Enough data must be present.
520          */
521         if (!capable(CAP_MAC_ADMIN))
522                 return -EPERM;
523         if (*ppos != 0)
524                 return -EINVAL;
525         if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)
526                 return -EINVAL;
527
528         data = kzalloc(count + 1, GFP_KERNEL);
529         if (data == NULL)
530                 return -ENOMEM;
531
532         if (copy_from_user(data, buf, count) != 0) {
533                 rc = -EFAULT;
534                 goto unlockedout;
535         }
536
537         data[count] = '\0';
538         rule = data;
539         /*
540          * Only allow one writer at a time. Writes should be
541          * quite rare and small in any case.
542          */
543         mutex_lock(&smack_cipso_lock);
544
545         skp = smk_import_entry(rule, 0);
546         if (skp == NULL)
547                 goto out;
548
549         rule += SMK_LABELLEN;;
550         ret = sscanf(rule, "%d", &maplevel);
551         if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
552                 goto out;
553
554         rule += SMK_DIGITLEN;
555         ret = sscanf(rule, "%d", &catlen);
556         if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
557                 goto out;
558
559         if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
560                 goto out;
561
562         memset(mapcatset, 0, sizeof(mapcatset));
563
564         for (i = 0; i < catlen; i++) {
565                 rule += SMK_DIGITLEN;
566                 ret = sscanf(rule, "%d", &cat);
567                 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
568                         goto out;
569
570                 smack_catset_bit(cat, mapcatset);
571         }
572
573         if (skp->smk_cipso == NULL) {
574                 scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL);
575                 if (scp == NULL) {
576                         rc = -ENOMEM;
577                         goto out;
578                 }
579         }
580
581         spin_lock_bh(&skp->smk_cipsolock);
582
583         if (scp == NULL)
584                 scp = skp->smk_cipso;
585         else
586                 skp->smk_cipso = scp;
587
588         scp->smk_level = maplevel;
589         memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset));
590
591         spin_unlock_bh(&skp->smk_cipsolock);
592
593         rc = count;
594 out:
595         mutex_unlock(&smack_cipso_lock);
596 unlockedout:
597         kfree(data);
598         return rc;
599 }
600
601 static const struct file_operations smk_cipso_ops = {
602         .open           = smk_open_cipso,
603         .read           = seq_read,
604         .llseek         = seq_lseek,
605         .write          = smk_write_cipso,
606         .release        = seq_release,
607 };
608
609 /**
610  * smk_read_doi - read() for /smack/doi
611  * @filp: file pointer, not actually used
612  * @buf: where to put the result
613  * @count: maximum to send along
614  * @ppos: where to start
615  *
616  * Returns number of bytes read or error code, as appropriate
617  */
618 static ssize_t smk_read_doi(struct file *filp, char __user *buf,
619                             size_t count, loff_t *ppos)
620 {
621         char temp[80];
622         ssize_t rc;
623
624         if (*ppos != 0)
625                 return 0;
626
627         sprintf(temp, "%d", smk_cipso_doi_value);
628         rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
629
630         return rc;
631 }
632
633 /**
634  * smk_write_doi - write() for /smack/doi
635  * @filp: file pointer, not actually used
636  * @buf: where to get the data from
637  * @count: bytes sent
638  * @ppos: where to start
639  *
640  * Returns number of bytes written or error code, as appropriate
641  */
642 static ssize_t smk_write_doi(struct file *file, const char __user *buf,
643                              size_t count, loff_t *ppos)
644 {
645         char temp[80];
646         int i;
647
648         if (!capable(CAP_MAC_ADMIN))
649                 return -EPERM;
650
651         if (count >= sizeof(temp) || count == 0)
652                 return -EINVAL;
653
654         if (copy_from_user(temp, buf, count) != 0)
655                 return -EFAULT;
656
657         temp[count] = '\0';
658
659         if (sscanf(temp, "%d", &i) != 1)
660                 return -EINVAL;
661
662         smk_cipso_doi_value = i;
663
664         smk_cipso_doi();
665
666         return count;
667 }
668
669 static const struct file_operations smk_doi_ops = {
670         .read           = smk_read_doi,
671         .write          = smk_write_doi,
672 };
673
674 /**
675  * smk_read_direct - read() for /smack/direct
676  * @filp: file pointer, not actually used
677  * @buf: where to put the result
678  * @count: maximum to send along
679  * @ppos: where to start
680  *
681  * Returns number of bytes read or error code, as appropriate
682  */
683 static ssize_t smk_read_direct(struct file *filp, char __user *buf,
684                                size_t count, loff_t *ppos)
685 {
686         char temp[80];
687         ssize_t rc;
688
689         if (*ppos != 0)
690                 return 0;
691
692         sprintf(temp, "%d", smack_cipso_direct);
693         rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
694
695         return rc;
696 }
697
698 /**
699  * smk_write_direct - write() for /smack/direct
700  * @filp: file pointer, not actually used
701  * @buf: where to get the data from
702  * @count: bytes sent
703  * @ppos: where to start
704  *
705  * Returns number of bytes written or error code, as appropriate
706  */
707 static ssize_t smk_write_direct(struct file *file, const char __user *buf,
708                                 size_t count, loff_t *ppos)
709 {
710         char temp[80];
711         int i;
712
713         if (!capable(CAP_MAC_ADMIN))
714                 return -EPERM;
715
716         if (count >= sizeof(temp) || count == 0)
717                 return -EINVAL;
718
719         if (copy_from_user(temp, buf, count) != 0)
720                 return -EFAULT;
721
722         temp[count] = '\0';
723
724         if (sscanf(temp, "%d", &i) != 1)
725                 return -EINVAL;
726
727         smack_cipso_direct = i;
728
729         return count;
730 }
731
732 static const struct file_operations smk_direct_ops = {
733         .read           = smk_read_direct,
734         .write          = smk_write_direct,
735 };
736
737 /**
738  * smk_read_ambient - read() for /smack/ambient
739  * @filp: file pointer, not actually used
740  * @buf: where to put the result
741  * @cn: maximum to send along
742  * @ppos: where to start
743  *
744  * Returns number of bytes read or error code, as appropriate
745  */
746 static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
747                                 size_t cn, loff_t *ppos)
748 {
749         ssize_t rc;
750         int asize;
751
752         if (*ppos != 0)
753                 return 0;
754         /*
755          * Being careful to avoid a problem in the case where
756          * smack_net_ambient gets changed in midstream.
757          */
758         mutex_lock(&smack_ambient_lock);
759
760         asize = strlen(smack_net_ambient) + 1;
761
762         if (cn >= asize)
763                 rc = simple_read_from_buffer(buf, cn, ppos,
764                                              smack_net_ambient, asize);
765         else
766                 rc = -EINVAL;
767
768         mutex_unlock(&smack_ambient_lock);
769
770         return rc;
771 }
772
773 /**
774  * smk_write_ambient - write() for /smack/ambient
775  * @filp: file pointer, not actually used
776  * @buf: where to get the data from
777  * @count: bytes sent
778  * @ppos: where to start
779  *
780  * Returns number of bytes written or error code, as appropriate
781  */
782 static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
783                                  size_t count, loff_t *ppos)
784 {
785         char in[SMK_LABELLEN];
786         char *oldambient;
787         char *smack;
788
789         if (!capable(CAP_MAC_ADMIN))
790                 return -EPERM;
791
792         if (count >= SMK_LABELLEN)
793                 return -EINVAL;
794
795         if (copy_from_user(in, buf, count) != 0)
796                 return -EFAULT;
797
798         smack = smk_import(in, count);
799         if (smack == NULL)
800                 return -EINVAL;
801
802         mutex_lock(&smack_ambient_lock);
803
804         oldambient = smack_net_ambient;
805         smack_net_ambient = smack;
806         smk_unlbl_ambient(oldambient);
807
808         mutex_unlock(&smack_ambient_lock);
809
810         return count;
811 }
812
813 static const struct file_operations smk_ambient_ops = {
814         .read           = smk_read_ambient,
815         .write          = smk_write_ambient,
816 };
817
818 struct option_names {
819         int     o_number;
820         char    *o_name;
821         char    *o_alias;
822 };
823
824 static struct option_names netlbl_choices[] = {
825         { NETLBL_NLTYPE_RIPSO,
826                 NETLBL_NLTYPE_RIPSO_NAME,       "ripso" },
827         { NETLBL_NLTYPE_CIPSOV4,
828                 NETLBL_NLTYPE_CIPSOV4_NAME,     "cipsov4" },
829         { NETLBL_NLTYPE_CIPSOV4,
830                 NETLBL_NLTYPE_CIPSOV4_NAME,     "cipso" },
831         { NETLBL_NLTYPE_CIPSOV6,
832                 NETLBL_NLTYPE_CIPSOV6_NAME,     "cipsov6" },
833         { NETLBL_NLTYPE_UNLABELED,
834                 NETLBL_NLTYPE_UNLABELED_NAME,   "unlabeled" },
835 };
836
837 /**
838  * smk_read_nltype - read() for /smack/nltype
839  * @filp: file pointer, not actually used
840  * @buf: where to put the result
841  * @count: maximum to send along
842  * @ppos: where to start
843  *
844  * Returns number of bytes read or error code, as appropriate
845  */
846 static ssize_t smk_read_nltype(struct file *filp, char __user *buf,
847                                size_t count, loff_t *ppos)
848 {
849         char bound[40];
850         ssize_t rc;
851         int i;
852
853         if (count < SMK_LABELLEN)
854                 return -EINVAL;
855
856         if (*ppos != 0)
857                 return 0;
858
859         sprintf(bound, "unknown");
860
861         for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++)
862                 if (smack_net_nltype == netlbl_choices[i].o_number) {
863                         sprintf(bound, "%s", netlbl_choices[i].o_name);
864                         break;
865                 }
866
867         rc = simple_read_from_buffer(buf, count, ppos, bound, strlen(bound));
868
869         return rc;
870 }
871
872 /**
873  * smk_write_nltype - write() for /smack/nltype
874  * @filp: file pointer, not actually used
875  * @buf: where to get the data from
876  * @count: bytes sent
877  * @ppos: where to start
878  *
879  * Returns number of bytes written or error code, as appropriate
880  */
881 static ssize_t smk_write_nltype(struct file *file, const char __user *buf,
882                                 size_t count, loff_t *ppos)
883 {
884         char bound[40];
885         char *cp;
886         int i;
887
888         if (!capable(CAP_MAC_ADMIN))
889                 return -EPERM;
890
891         if (count >= 40)
892                 return -EINVAL;
893
894         if (copy_from_user(bound, buf, count) != 0)
895                 return -EFAULT;
896
897         bound[count] = '\0';
898         cp = strchr(bound, ' ');
899         if (cp != NULL)
900                 *cp = '\0';
901         cp = strchr(bound, '\n');
902         if (cp != NULL)
903                 *cp = '\0';
904
905         for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++)
906                 if (strcmp(bound, netlbl_choices[i].o_name) == 0 ||
907                     strcmp(bound, netlbl_choices[i].o_alias) == 0) {
908                         smack_net_nltype = netlbl_choices[i].o_number;
909                         return count;
910                 }
911         /*
912          * Not a valid choice.
913          */
914         return -EINVAL;
915 }
916
917 static const struct file_operations smk_nltype_ops = {
918         .read           = smk_read_nltype,
919         .write          = smk_write_nltype,
920 };
921
922 /**
923  * smk_fill_super - fill the /smackfs superblock
924  * @sb: the empty superblock
925  * @data: unused
926  * @silent: unused
927  *
928  * Fill in the well known entries for /smack
929  *
930  * Returns 0 on success, an error code on failure
931  */
932 static int smk_fill_super(struct super_block *sb, void *data, int silent)
933 {
934         int rc;
935         struct inode *root_inode;
936
937         static struct tree_descr smack_files[] = {
938                 [SMK_LOAD]      =
939                         {"load", &smk_load_ops, S_IRUGO|S_IWUSR},
940                 [SMK_CIPSO]     =
941                         {"cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR},
942                 [SMK_DOI]       =
943                         {"doi", &smk_doi_ops, S_IRUGO|S_IWUSR},
944                 [SMK_DIRECT]    =
945                         {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR},
946                 [SMK_AMBIENT]   =
947                         {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
948                 [SMK_NLTYPE]    =
949                         {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR},
950                 /* last one */ {""}
951         };
952
953         rc = simple_fill_super(sb, SMACK_MAGIC, smack_files);
954         if (rc != 0) {
955                 printk(KERN_ERR "%s failed %d while creating inodes\n",
956                         __func__, rc);
957                 return rc;
958         }
959
960         root_inode = sb->s_root->d_inode;
961         root_inode->i_security = new_inode_smack(smack_known_floor.smk_known);
962
963         return 0;
964 }
965
966 /**
967  * smk_get_sb - get the smackfs superblock
968  * @fs_type: passed along without comment
969  * @flags: passed along without comment
970  * @dev_name: passed along without comment
971  * @data: passed along without comment
972  * @mnt: passed along without comment
973  *
974  * Just passes everything along.
975  *
976  * Returns what the lower level code does.
977  */
978 static int smk_get_sb(struct file_system_type *fs_type,
979                       int flags, const char *dev_name, void *data,
980                       struct vfsmount *mnt)
981 {
982         return get_sb_single(fs_type, flags, data, smk_fill_super, mnt);
983 }
984
985 static struct file_system_type smk_fs_type = {
986         .name           = "smackfs",
987         .get_sb         = smk_get_sb,
988         .kill_sb        = kill_litter_super,
989 };
990
991 static struct vfsmount *smackfs_mount;
992
993 /**
994  * init_smk_fs - get the smackfs superblock
995  *
996  * register the smackfs
997  *
998  * Returns 0 unless the registration fails.
999  */
1000 static int __init init_smk_fs(void)
1001 {
1002         int err;
1003
1004         err = register_filesystem(&smk_fs_type);
1005         if (!err) {
1006                 smackfs_mount = kern_mount(&smk_fs_type);
1007                 if (IS_ERR(smackfs_mount)) {
1008                         printk(KERN_ERR "smackfs:  could not mount!\n");
1009                         err = PTR_ERR(smackfs_mount);
1010                         smackfs_mount = NULL;
1011                 }
1012         }
1013
1014         sema_init(&smack_write_sem, 1);
1015         smk_cipso_doi();
1016         smk_unlbl_ambient(NULL);
1017
1018         return err;
1019 }
1020
1021 __initcall(init_smk_fs);