Smack: Transmute labels on specified directories
[linux-flexiantxendom0-natty.git] / 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 <linux/slab.h>
24 #include <net/net_namespace.h>
25 #include <net/netlabel.h>
26 #include <net/cipso_ipv4.h>
27 #include <linux/seq_file.h>
28 #include <linux/ctype.h>
29 #include <linux/audit.h>
30 #include "smack.h"
31
32 /*
33  * smackfs pseudo filesystem.
34  */
35
36 enum smk_inos {
37         SMK_ROOT_INO    = 2,
38         SMK_LOAD        = 3,    /* load policy */
39         SMK_CIPSO       = 4,    /* load label -> CIPSO mapping */
40         SMK_DOI         = 5,    /* CIPSO DOI */
41         SMK_DIRECT      = 6,    /* CIPSO level indicating direct label */
42         SMK_AMBIENT     = 7,    /* internet ambient label */
43         SMK_NETLBLADDR  = 8,    /* single label hosts */
44         SMK_ONLYCAP     = 9,    /* the only "capable" label */
45         SMK_LOGGING     = 10,   /* logging */
46 };
47
48 /*
49  * List locks
50  */
51 static DEFINE_MUTEX(smack_list_lock);
52 static DEFINE_MUTEX(smack_cipso_lock);
53 static DEFINE_MUTEX(smack_ambient_lock);
54 static DEFINE_MUTEX(smk_netlbladdr_lock);
55
56 /*
57  * This is the "ambient" label for network traffic.
58  * If it isn't somehow marked, use this.
59  * It can be reset via smackfs/ambient
60  */
61 char *smack_net_ambient = smack_known_floor.smk_known;
62
63 /*
64  * This is the level in a CIPSO header that indicates a
65  * smack label is contained directly in the category set.
66  * It can be reset via smackfs/direct
67  */
68 int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
69
70 /*
71  * Unless a process is running with this label even
72  * having CAP_MAC_OVERRIDE isn't enough to grant
73  * privilege to violate MAC policy. If no label is
74  * designated (the NULL case) capabilities apply to
75  * everyone. It is expected that the hat (^) label
76  * will be used if any label is used.
77  */
78 char *smack_onlycap;
79
80 /*
81  * Certain IP addresses may be designated as single label hosts.
82  * Packets are sent there unlabeled, but only from tasks that
83  * can write to the specified label.
84  */
85
86 LIST_HEAD(smk_netlbladdr_list);
87 LIST_HEAD(smack_rule_list);
88
89 static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
90
91 const char *smack_cipso_option = SMACK_CIPSO_OPTION;
92
93
94 #define SEQ_READ_FINISHED       1
95
96 /*
97  * Values for parsing cipso rules
98  * SMK_DIGITLEN: Length of a digit field in a rule.
99  * SMK_CIPSOMIN: Minimum possible cipso rule length.
100  * SMK_CIPSOMAX: Maximum possible cipso rule length.
101  */
102 #define SMK_DIGITLEN 4
103 #define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN)
104 #define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN)
105
106 /*
107  * Values for parsing MAC rules
108  * SMK_ACCESS: Maximum possible combination of access permissions
109  * SMK_ACCESSLEN: Maximum length for a rule access field
110  * SMK_LOADLEN: Smack rule length
111  */
112 #define SMK_OACCESS     "rwxa"
113 #define SMK_ACCESS      "rwxat"
114 #define SMK_OACCESSLEN  (sizeof(SMK_OACCESS) - 1)
115 #define SMK_ACCESSLEN   (sizeof(SMK_ACCESS) - 1)
116 #define SMK_OLOADLEN    (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
117 #define SMK_LOADLEN     (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
118
119 /**
120  * smk_netlabel_audit_set - fill a netlbl_audit struct
121  * @nap: structure to fill
122  */
123 static void smk_netlabel_audit_set(struct netlbl_audit *nap)
124 {
125         nap->loginuid = audit_get_loginuid(current);
126         nap->sessionid = audit_get_sessionid(current);
127         nap->secid = smack_to_secid(smk_of_current());
128 }
129
130 /*
131  * Values for parsing single label host rules
132  * "1.2.3.4 X"
133  * "192.168.138.129/32 abcdefghijklmnopqrstuvw"
134  */
135 #define SMK_NETLBLADDRMIN       9
136 #define SMK_NETLBLADDRMAX       42
137
138 /*
139  * Seq_file read operations for /smack/load
140  */
141
142 static void *load_seq_start(struct seq_file *s, loff_t *pos)
143 {
144         if (*pos == SEQ_READ_FINISHED)
145                 return NULL;
146         if (list_empty(&smack_rule_list))
147                 return NULL;
148         return smack_rule_list.next;
149 }
150
151 static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
152 {
153         struct list_head *list = v;
154
155         if (list_is_last(list, &smack_rule_list)) {
156                 *pos = SEQ_READ_FINISHED;
157                 return NULL;
158         }
159         return list->next;
160 }
161
162 static int load_seq_show(struct seq_file *s, void *v)
163 {
164         struct list_head *list = v;
165         struct smack_rule *srp =
166                  list_entry(list, struct smack_rule, list);
167
168         seq_printf(s, "%s %s", (char *)srp->smk_subject,
169                    (char *)srp->smk_object);
170
171         seq_putc(s, ' ');
172
173         if (srp->smk_access & MAY_READ)
174                 seq_putc(s, 'r');
175         if (srp->smk_access & MAY_WRITE)
176                 seq_putc(s, 'w');
177         if (srp->smk_access & MAY_EXEC)
178                 seq_putc(s, 'x');
179         if (srp->smk_access & MAY_APPEND)
180                 seq_putc(s, 'a');
181         if (srp->smk_access & MAY_TRANSMUTE)
182                 seq_putc(s, 't');
183         if (srp->smk_access == 0)
184                 seq_putc(s, '-');
185
186         seq_putc(s, '\n');
187
188         return 0;
189 }
190
191 static void load_seq_stop(struct seq_file *s, void *v)
192 {
193         /* No-op */
194 }
195
196 static const struct seq_operations load_seq_ops = {
197         .start = load_seq_start,
198         .next  = load_seq_next,
199         .show  = load_seq_show,
200         .stop  = load_seq_stop,
201 };
202
203 /**
204  * smk_open_load - open() for /smack/load
205  * @inode: inode structure representing file
206  * @file: "load" file pointer
207  *
208  * For reading, use load_seq_* seq_file reading operations.
209  */
210 static int smk_open_load(struct inode *inode, struct file *file)
211 {
212         return seq_open(file, &load_seq_ops);
213 }
214
215 /**
216  * smk_set_access - add a rule to the rule list
217  * @srp: the new rule to add
218  *
219  * Looks through the current subject/object/access list for
220  * the subject/object pair and replaces the access that was
221  * there. If the pair isn't found add it with the specified
222  * access.
223  *
224  * Returns 0 if nothing goes wrong or -ENOMEM if it fails
225  * during the allocation of the new pair to add.
226  */
227 static int smk_set_access(struct smack_rule *srp)
228 {
229         struct smack_rule *sp;
230         int ret = 0;
231         int found;
232         mutex_lock(&smack_list_lock);
233
234         found = 0;
235         list_for_each_entry_rcu(sp, &smack_rule_list, list) {
236                 if (sp->smk_subject == srp->smk_subject &&
237                     sp->smk_object == srp->smk_object) {
238                         found = 1;
239                         sp->smk_access = srp->smk_access;
240                         break;
241                 }
242         }
243         if (found == 0)
244                 list_add_rcu(&srp->list, &smack_rule_list);
245
246         mutex_unlock(&smack_list_lock);
247
248         return ret;
249 }
250
251 /**
252  * smk_write_load - write() for /smack/load
253  * @file: file pointer, not actually used
254  * @buf: where to get the data from
255  * @count: bytes sent
256  * @ppos: where to start - must be 0
257  *
258  * Get one smack access rule from above.
259  * The format is exactly:
260  *     char subject[SMK_LABELLEN]
261  *     char object[SMK_LABELLEN]
262  *     char access[SMK_ACCESSLEN]
263  *
264  * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
265  */
266 static ssize_t smk_write_load(struct file *file, const char __user *buf,
267                               size_t count, loff_t *ppos)
268 {
269         struct smack_rule *rule;
270         char *data;
271         int rc = -EINVAL;
272
273         /*
274          * Must have privilege.
275          * No partial writes.
276          * Enough data must be present.
277          */
278         if (!capable(CAP_MAC_ADMIN))
279                 return -EPERM;
280
281         if (*ppos != 0)
282                 return -EINVAL;
283         /*
284          * Minor hack for backward compatability
285          */
286         if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN)
287                 return -EINVAL;
288
289         data = kzalloc(SMK_LOADLEN, GFP_KERNEL);
290         if (data == NULL)
291                 return -ENOMEM;
292
293         if (copy_from_user(data, buf, count) != 0) {
294                 rc = -EFAULT;
295                 goto out;
296         }
297
298         /*
299          * More on the minor hack for backward compatability
300          */
301         if (count == (SMK_OLOADLEN))
302                 data[SMK_OLOADLEN] = '-';
303
304         rule = kzalloc(sizeof(*rule), GFP_KERNEL);
305         if (rule == NULL) {
306                 rc = -ENOMEM;
307                 goto out;
308         }
309
310         rule->smk_subject = smk_import(data, 0);
311         if (rule->smk_subject == NULL)
312                 goto out_free_rule;
313
314         rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
315         if (rule->smk_object == NULL)
316                 goto out_free_rule;
317
318         rule->smk_access = 0;
319
320         switch (data[SMK_LABELLEN + SMK_LABELLEN]) {
321         case '-':
322                 break;
323         case 'r':
324         case 'R':
325                 rule->smk_access |= MAY_READ;
326                 break;
327         default:
328                 goto out_free_rule;
329         }
330
331         switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
332         case '-':
333                 break;
334         case 'w':
335         case 'W':
336                 rule->smk_access |= MAY_WRITE;
337                 break;
338         default:
339                 goto out_free_rule;
340         }
341
342         switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
343         case '-':
344                 break;
345         case 'x':
346         case 'X':
347                 rule->smk_access |= MAY_EXEC;
348                 break;
349         default:
350                 goto out_free_rule;
351         }
352
353         switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
354         case '-':
355                 break;
356         case 'a':
357         case 'A':
358                 rule->smk_access |= MAY_APPEND;
359                 break;
360         default:
361                 goto out_free_rule;
362         }
363
364         switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) {
365         case '-':
366                 break;
367         case 't':
368         case 'T':
369                 rule->smk_access |= MAY_TRANSMUTE;
370                 break;
371         default:
372                 goto out_free_rule;
373         }
374
375         rc = smk_set_access(rule);
376
377         if (!rc)
378                 rc = count;
379         goto out;
380
381 out_free_rule:
382         kfree(rule);
383 out:
384         kfree(data);
385         return rc;
386 }
387
388 static const struct file_operations smk_load_ops = {
389         .open           = smk_open_load,
390         .read           = seq_read,
391         .llseek         = seq_lseek,
392         .write          = smk_write_load,
393         .release        = seq_release,
394 };
395
396 /**
397  * smk_cipso_doi - initialize the CIPSO domain
398  */
399 static void smk_cipso_doi(void)
400 {
401         int rc;
402         struct cipso_v4_doi *doip;
403         struct netlbl_audit nai;
404
405         smk_netlabel_audit_set(&nai);
406
407         rc = netlbl_cfg_map_del(NULL, PF_INET, NULL, NULL, &nai);
408         if (rc != 0)
409                 printk(KERN_WARNING "%s:%d remove rc = %d\n",
410                        __func__, __LINE__, rc);
411
412         doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL);
413         if (doip == NULL)
414                 panic("smack:  Failed to initialize cipso DOI.\n");
415         doip->map.std = NULL;
416         doip->doi = smk_cipso_doi_value;
417         doip->type = CIPSO_V4_MAP_PASS;
418         doip->tags[0] = CIPSO_V4_TAG_RBITMAP;
419         for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
420                 doip->tags[rc] = CIPSO_V4_TAG_INVALID;
421
422         rc = netlbl_cfg_cipsov4_add(doip, &nai);
423         if (rc != 0) {
424                 printk(KERN_WARNING "%s:%d cipso add rc = %d\n",
425                        __func__, __LINE__, rc);
426                 kfree(doip);
427                 return;
428         }
429         rc = netlbl_cfg_cipsov4_map_add(doip->doi, NULL, NULL, NULL, &nai);
430         if (rc != 0) {
431                 printk(KERN_WARNING "%s:%d map add rc = %d\n",
432                        __func__, __LINE__, rc);
433                 kfree(doip);
434                 return;
435         }
436 }
437
438 /**
439  * smk_unlbl_ambient - initialize the unlabeled domain
440  * @oldambient: previous domain string
441  */
442 static void smk_unlbl_ambient(char *oldambient)
443 {
444         int rc;
445         struct netlbl_audit nai;
446
447         smk_netlabel_audit_set(&nai);
448
449         if (oldambient != NULL) {
450                 rc = netlbl_cfg_map_del(oldambient, PF_INET, NULL, NULL, &nai);
451                 if (rc != 0)
452                         printk(KERN_WARNING "%s:%d remove rc = %d\n",
453                                __func__, __LINE__, rc);
454         }
455
456         rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET,
457                                       NULL, NULL, &nai);
458         if (rc != 0)
459                 printk(KERN_WARNING "%s:%d add rc = %d\n",
460                        __func__, __LINE__, rc);
461 }
462
463 /*
464  * Seq_file read operations for /smack/cipso
465  */
466
467 static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
468 {
469         if (*pos == SEQ_READ_FINISHED)
470                 return NULL;
471         if (list_empty(&smack_known_list))
472                 return NULL;
473
474         return smack_known_list.next;
475 }
476
477 static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
478 {
479         struct list_head  *list = v;
480
481         /*
482          * labels with no associated cipso value wont be printed
483          * in cipso_seq_show
484          */
485         if (list_is_last(list, &smack_known_list)) {
486                 *pos = SEQ_READ_FINISHED;
487                 return NULL;
488         }
489
490         return list->next;
491 }
492
493 /*
494  * Print cipso labels in format:
495  * label level[/cat[,cat]]
496  */
497 static int cipso_seq_show(struct seq_file *s, void *v)
498 {
499         struct list_head  *list = v;
500         struct smack_known *skp =
501                  list_entry(list, struct smack_known, list);
502         struct smack_cipso *scp = skp->smk_cipso;
503         char *cbp;
504         char sep = '/';
505         int cat = 1;
506         int i;
507         unsigned char m;
508
509         if (scp == NULL)
510                 return 0;
511
512         seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level);
513
514         cbp = scp->smk_catset;
515         for (i = 0; i < SMK_LABELLEN; i++)
516                 for (m = 0x80; m != 0; m >>= 1) {
517                         if (m & cbp[i]) {
518                                 seq_printf(s, "%c%d", sep, cat);
519                                 sep = ',';
520                         }
521                         cat++;
522                 }
523
524         seq_putc(s, '\n');
525
526         return 0;
527 }
528
529 static void cipso_seq_stop(struct seq_file *s, void *v)
530 {
531         /* No-op */
532 }
533
534 static const struct seq_operations cipso_seq_ops = {
535         .start = cipso_seq_start,
536         .stop  = cipso_seq_stop,
537         .next  = cipso_seq_next,
538         .show  = cipso_seq_show,
539 };
540
541 /**
542  * smk_open_cipso - open() for /smack/cipso
543  * @inode: inode structure representing file
544  * @file: "cipso" file pointer
545  *
546  * Connect our cipso_seq_* operations with /smack/cipso
547  * file_operations
548  */
549 static int smk_open_cipso(struct inode *inode, struct file *file)
550 {
551         return seq_open(file, &cipso_seq_ops);
552 }
553
554 /**
555  * smk_write_cipso - write() for /smack/cipso
556  * @file: file pointer, not actually used
557  * @buf: where to get the data from
558  * @count: bytes sent
559  * @ppos: where to start
560  *
561  * Accepts only one cipso rule per write call.
562  * Returns number of bytes written or error code, as appropriate
563  */
564 static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
565                                size_t count, loff_t *ppos)
566 {
567         struct smack_known *skp;
568         struct smack_cipso *scp = NULL;
569         char mapcatset[SMK_LABELLEN];
570         int maplevel;
571         int cat;
572         int catlen;
573         ssize_t rc = -EINVAL;
574         char *data = NULL;
575         char *rule;
576         int ret;
577         int i;
578
579         /*
580          * Must have privilege.
581          * No partial writes.
582          * Enough data must be present.
583          */
584         if (!capable(CAP_MAC_ADMIN))
585                 return -EPERM;
586         if (*ppos != 0)
587                 return -EINVAL;
588         if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)
589                 return -EINVAL;
590
591         data = kzalloc(count + 1, GFP_KERNEL);
592         if (data == NULL)
593                 return -ENOMEM;
594
595         if (copy_from_user(data, buf, count) != 0) {
596                 rc = -EFAULT;
597                 goto unlockedout;
598         }
599
600         /* labels cannot begin with a '-' */
601         if (data[0] == '-') {
602                 rc = -EINVAL;
603                 goto unlockedout;
604         }
605         data[count] = '\0';
606         rule = data;
607         /*
608          * Only allow one writer at a time. Writes should be
609          * quite rare and small in any case.
610          */
611         mutex_lock(&smack_cipso_lock);
612
613         skp = smk_import_entry(rule, 0);
614         if (skp == NULL)
615                 goto out;
616
617         rule += SMK_LABELLEN;
618         ret = sscanf(rule, "%d", &maplevel);
619         if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
620                 goto out;
621
622         rule += SMK_DIGITLEN;
623         ret = sscanf(rule, "%d", &catlen);
624         if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
625                 goto out;
626
627         if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
628                 goto out;
629
630         memset(mapcatset, 0, sizeof(mapcatset));
631
632         for (i = 0; i < catlen; i++) {
633                 rule += SMK_DIGITLEN;
634                 ret = sscanf(rule, "%d", &cat);
635                 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
636                         goto out;
637
638                 smack_catset_bit(cat, mapcatset);
639         }
640
641         if (skp->smk_cipso == NULL) {
642                 scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL);
643                 if (scp == NULL) {
644                         rc = -ENOMEM;
645                         goto out;
646                 }
647         }
648
649         spin_lock_bh(&skp->smk_cipsolock);
650
651         if (scp == NULL)
652                 scp = skp->smk_cipso;
653         else
654                 skp->smk_cipso = scp;
655
656         scp->smk_level = maplevel;
657         memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset));
658
659         spin_unlock_bh(&skp->smk_cipsolock);
660
661         rc = count;
662 out:
663         mutex_unlock(&smack_cipso_lock);
664 unlockedout:
665         kfree(data);
666         return rc;
667 }
668
669 static const struct file_operations smk_cipso_ops = {
670         .open           = smk_open_cipso,
671         .read           = seq_read,
672         .llseek         = seq_lseek,
673         .write          = smk_write_cipso,
674         .release        = seq_release,
675 };
676
677 /*
678  * Seq_file read operations for /smack/netlabel
679  */
680
681 static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos)
682 {
683         if (*pos == SEQ_READ_FINISHED)
684                 return NULL;
685         if (list_empty(&smk_netlbladdr_list))
686                 return NULL;
687         return smk_netlbladdr_list.next;
688 }
689
690 static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
691 {
692         struct list_head *list = v;
693
694         if (list_is_last(list, &smk_netlbladdr_list)) {
695                 *pos = SEQ_READ_FINISHED;
696                 return NULL;
697         }
698
699         return list->next;
700 }
701 #define BEBITS  (sizeof(__be32) * 8)
702
703 /*
704  * Print host/label pairs
705  */
706 static int netlbladdr_seq_show(struct seq_file *s, void *v)
707 {
708         struct list_head *list = v;
709         struct smk_netlbladdr *skp =
710                          list_entry(list, struct smk_netlbladdr, list);
711         unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr;
712         int maskn;
713         u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
714
715         for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++);
716
717         seq_printf(s, "%u.%u.%u.%u/%d %s\n",
718                 hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label);
719
720         return 0;
721 }
722
723 static void netlbladdr_seq_stop(struct seq_file *s, void *v)
724 {
725         /* No-op */
726 }
727
728 static const struct seq_operations netlbladdr_seq_ops = {
729         .start = netlbladdr_seq_start,
730         .stop  = netlbladdr_seq_stop,
731         .next  = netlbladdr_seq_next,
732         .show  = netlbladdr_seq_show,
733 };
734
735 /**
736  * smk_open_netlbladdr - open() for /smack/netlabel
737  * @inode: inode structure representing file
738  * @file: "netlabel" file pointer
739  *
740  * Connect our netlbladdr_seq_* operations with /smack/netlabel
741  * file_operations
742  */
743 static int smk_open_netlbladdr(struct inode *inode, struct file *file)
744 {
745         return seq_open(file, &netlbladdr_seq_ops);
746 }
747
748 /**
749  * smk_netlbladdr_insert
750  * @new : netlabel to insert
751  *
752  * This helper insert netlabel in the smack_netlbladdrs list
753  * sorted by netmask length (longest to smallest)
754  * locked by &smk_netlbladdr_lock in smk_write_netlbladdr
755  *
756  */
757 static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
758 {
759         struct smk_netlbladdr *m, *m_next;
760
761         if (list_empty(&smk_netlbladdr_list)) {
762                 list_add_rcu(&new->list, &smk_netlbladdr_list);
763                 return;
764         }
765
766         m = list_entry_rcu(smk_netlbladdr_list.next,
767                            struct smk_netlbladdr, list);
768
769         /* the comparison '>' is a bit hacky, but works */
770         if (new->smk_mask.s_addr > m->smk_mask.s_addr) {
771                 list_add_rcu(&new->list, &smk_netlbladdr_list);
772                 return;
773         }
774
775         list_for_each_entry_rcu(m, &smk_netlbladdr_list, list) {
776                 if (list_is_last(&m->list, &smk_netlbladdr_list)) {
777                         list_add_rcu(&new->list, &m->list);
778                         return;
779                 }
780                 m_next = list_entry_rcu(m->list.next,
781                                         struct smk_netlbladdr, list);
782                 if (new->smk_mask.s_addr > m_next->smk_mask.s_addr) {
783                         list_add_rcu(&new->list, &m->list);
784                         return;
785                 }
786         }
787 }
788
789
790 /**
791  * smk_write_netlbladdr - write() for /smack/netlabel
792  * @file: file pointer, not actually used
793  * @buf: where to get the data from
794  * @count: bytes sent
795  * @ppos: where to start
796  *
797  * Accepts only one netlbladdr per write call.
798  * Returns number of bytes written or error code, as appropriate
799  */
800 static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
801                                 size_t count, loff_t *ppos)
802 {
803         struct smk_netlbladdr *skp;
804         struct sockaddr_in newname;
805         char smack[SMK_LABELLEN];
806         char *sp;
807         char data[SMK_NETLBLADDRMAX + 1];
808         char *host = (char *)&newname.sin_addr.s_addr;
809         int rc;
810         struct netlbl_audit audit_info;
811         struct in_addr mask;
812         unsigned int m;
813         int found;
814         u32 mask_bits = (1<<31);
815         __be32 nsa;
816         u32 temp_mask;
817
818         /*
819          * Must have privilege.
820          * No partial writes.
821          * Enough data must be present.
822          * "<addr/mask, as a.b.c.d/e><space><label>"
823          * "<addr, as a.b.c.d><space><label>"
824          */
825         if (!capable(CAP_MAC_ADMIN))
826                 return -EPERM;
827         if (*ppos != 0)
828                 return -EINVAL;
829         if (count < SMK_NETLBLADDRMIN || count > SMK_NETLBLADDRMAX)
830                 return -EINVAL;
831         if (copy_from_user(data, buf, count) != 0)
832                 return -EFAULT;
833
834         data[count] = '\0';
835
836         rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s",
837                 &host[0], &host[1], &host[2], &host[3], &m, smack);
838         if (rc != 6) {
839                 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
840                         &host[0], &host[1], &host[2], &host[3], smack);
841                 if (rc != 5)
842                         return -EINVAL;
843                 m = BEBITS;
844         }
845         if (m > BEBITS)
846                 return -EINVAL;
847
848         /* if smack begins with '-', its an option, don't import it */
849         if (smack[0] != '-') {
850                 sp = smk_import(smack, 0);
851                 if (sp == NULL)
852                         return -EINVAL;
853         } else {
854                 /* check known options */
855                 if (strcmp(smack, smack_cipso_option) == 0)
856                         sp = (char *)smack_cipso_option;
857                 else
858                         return -EINVAL;
859         }
860
861         for (temp_mask = 0; m > 0; m--) {
862                 temp_mask |= mask_bits;
863                 mask_bits >>= 1;
864         }
865         mask.s_addr = cpu_to_be32(temp_mask);
866
867         newname.sin_addr.s_addr &= mask.s_addr;
868         /*
869          * Only allow one writer at a time. Writes should be
870          * quite rare and small in any case.
871          */
872         mutex_lock(&smk_netlbladdr_lock);
873
874         nsa = newname.sin_addr.s_addr;
875         /* try to find if the prefix is already in the list */
876         found = 0;
877         list_for_each_entry_rcu(skp, &smk_netlbladdr_list, list) {
878                 if (skp->smk_host.sin_addr.s_addr == nsa &&
879                     skp->smk_mask.s_addr == mask.s_addr) {
880                         found = 1;
881                         break;
882                 }
883         }
884         smk_netlabel_audit_set(&audit_info);
885
886         if (found == 0) {
887                 skp = kzalloc(sizeof(*skp), GFP_KERNEL);
888                 if (skp == NULL)
889                         rc = -ENOMEM;
890                 else {
891                         rc = 0;
892                         skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr;
893                         skp->smk_mask.s_addr = mask.s_addr;
894                         skp->smk_label = sp;
895                         smk_netlbladdr_insert(skp);
896                 }
897         } else {
898                 /* we delete the unlabeled entry, only if the previous label
899                  * wasnt the special CIPSO option */
900                 if (skp->smk_label != smack_cipso_option)
901                         rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
902                                         &skp->smk_host.sin_addr, &skp->smk_mask,
903                                         PF_INET, &audit_info);
904                 else
905                         rc = 0;
906                 skp->smk_label = sp;
907         }
908
909         /*
910          * Now tell netlabel about the single label nature of
911          * this host so that incoming packets get labeled.
912          * but only if we didn't get the special CIPSO option
913          */
914         if (rc == 0 && sp != smack_cipso_option)
915                 rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
916                         &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET,
917                         smack_to_secid(skp->smk_label), &audit_info);
918
919         if (rc == 0)
920                 rc = count;
921
922         mutex_unlock(&smk_netlbladdr_lock);
923
924         return rc;
925 }
926
927 static const struct file_operations smk_netlbladdr_ops = {
928         .open           = smk_open_netlbladdr,
929         .read           = seq_read,
930         .llseek         = seq_lseek,
931         .write          = smk_write_netlbladdr,
932         .release        = seq_release,
933 };
934
935 /**
936  * smk_read_doi - read() for /smack/doi
937  * @filp: file pointer, not actually used
938  * @buf: where to put the result
939  * @count: maximum to send along
940  * @ppos: where to start
941  *
942  * Returns number of bytes read or error code, as appropriate
943  */
944 static ssize_t smk_read_doi(struct file *filp, char __user *buf,
945                             size_t count, loff_t *ppos)
946 {
947         char temp[80];
948         ssize_t rc;
949
950         if (*ppos != 0)
951                 return 0;
952
953         sprintf(temp, "%d", smk_cipso_doi_value);
954         rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
955
956         return rc;
957 }
958
959 /**
960  * smk_write_doi - write() for /smack/doi
961  * @file: file pointer, not actually used
962  * @buf: where to get the data from
963  * @count: bytes sent
964  * @ppos: where to start
965  *
966  * Returns number of bytes written or error code, as appropriate
967  */
968 static ssize_t smk_write_doi(struct file *file, const char __user *buf,
969                              size_t count, loff_t *ppos)
970 {
971         char temp[80];
972         int i;
973
974         if (!capable(CAP_MAC_ADMIN))
975                 return -EPERM;
976
977         if (count >= sizeof(temp) || count == 0)
978                 return -EINVAL;
979
980         if (copy_from_user(temp, buf, count) != 0)
981                 return -EFAULT;
982
983         temp[count] = '\0';
984
985         if (sscanf(temp, "%d", &i) != 1)
986                 return -EINVAL;
987
988         smk_cipso_doi_value = i;
989
990         smk_cipso_doi();
991
992         return count;
993 }
994
995 static const struct file_operations smk_doi_ops = {
996         .read           = smk_read_doi,
997         .write          = smk_write_doi,
998         .llseek         = default_llseek,
999 };
1000
1001 /**
1002  * smk_read_direct - read() for /smack/direct
1003  * @filp: file pointer, not actually used
1004  * @buf: where to put the result
1005  * @count: maximum to send along
1006  * @ppos: where to start
1007  *
1008  * Returns number of bytes read or error code, as appropriate
1009  */
1010 static ssize_t smk_read_direct(struct file *filp, char __user *buf,
1011                                size_t count, loff_t *ppos)
1012 {
1013         char temp[80];
1014         ssize_t rc;
1015
1016         if (*ppos != 0)
1017                 return 0;
1018
1019         sprintf(temp, "%d", smack_cipso_direct);
1020         rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1021
1022         return rc;
1023 }
1024
1025 /**
1026  * smk_write_direct - write() for /smack/direct
1027  * @file: file pointer, not actually used
1028  * @buf: where to get the data from
1029  * @count: bytes sent
1030  * @ppos: where to start
1031  *
1032  * Returns number of bytes written or error code, as appropriate
1033  */
1034 static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1035                                 size_t count, loff_t *ppos)
1036 {
1037         char temp[80];
1038         int i;
1039
1040         if (!capable(CAP_MAC_ADMIN))
1041                 return -EPERM;
1042
1043         if (count >= sizeof(temp) || count == 0)
1044                 return -EINVAL;
1045
1046         if (copy_from_user(temp, buf, count) != 0)
1047                 return -EFAULT;
1048
1049         temp[count] = '\0';
1050
1051         if (sscanf(temp, "%d", &i) != 1)
1052                 return -EINVAL;
1053
1054         smack_cipso_direct = i;
1055
1056         return count;
1057 }
1058
1059 static const struct file_operations smk_direct_ops = {
1060         .read           = smk_read_direct,
1061         .write          = smk_write_direct,
1062         .llseek         = default_llseek,
1063 };
1064
1065 /**
1066  * smk_read_ambient - read() for /smack/ambient
1067  * @filp: file pointer, not actually used
1068  * @buf: where to put the result
1069  * @cn: maximum to send along
1070  * @ppos: where to start
1071  *
1072  * Returns number of bytes read or error code, as appropriate
1073  */
1074 static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1075                                 size_t cn, loff_t *ppos)
1076 {
1077         ssize_t rc;
1078         int asize;
1079
1080         if (*ppos != 0)
1081                 return 0;
1082         /*
1083          * Being careful to avoid a problem in the case where
1084          * smack_net_ambient gets changed in midstream.
1085          */
1086         mutex_lock(&smack_ambient_lock);
1087
1088         asize = strlen(smack_net_ambient) + 1;
1089
1090         if (cn >= asize)
1091                 rc = simple_read_from_buffer(buf, cn, ppos,
1092                                              smack_net_ambient, asize);
1093         else
1094                 rc = -EINVAL;
1095
1096         mutex_unlock(&smack_ambient_lock);
1097
1098         return rc;
1099 }
1100
1101 /**
1102  * smk_write_ambient - write() for /smack/ambient
1103  * @file: file pointer, not actually used
1104  * @buf: where to get the data from
1105  * @count: bytes sent
1106  * @ppos: where to start
1107  *
1108  * Returns number of bytes written or error code, as appropriate
1109  */
1110 static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1111                                  size_t count, loff_t *ppos)
1112 {
1113         char in[SMK_LABELLEN];
1114         char *oldambient;
1115         char *smack;
1116
1117         if (!capable(CAP_MAC_ADMIN))
1118                 return -EPERM;
1119
1120         if (count >= SMK_LABELLEN)
1121                 return -EINVAL;
1122
1123         if (copy_from_user(in, buf, count) != 0)
1124                 return -EFAULT;
1125
1126         smack = smk_import(in, count);
1127         if (smack == NULL)
1128                 return -EINVAL;
1129
1130         mutex_lock(&smack_ambient_lock);
1131
1132         oldambient = smack_net_ambient;
1133         smack_net_ambient = smack;
1134         smk_unlbl_ambient(oldambient);
1135
1136         mutex_unlock(&smack_ambient_lock);
1137
1138         return count;
1139 }
1140
1141 static const struct file_operations smk_ambient_ops = {
1142         .read           = smk_read_ambient,
1143         .write          = smk_write_ambient,
1144         .llseek         = default_llseek,
1145 };
1146
1147 /**
1148  * smk_read_onlycap - read() for /smack/onlycap
1149  * @filp: file pointer, not actually used
1150  * @buf: where to put the result
1151  * @cn: maximum to send along
1152  * @ppos: where to start
1153  *
1154  * Returns number of bytes read or error code, as appropriate
1155  */
1156 static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1157                                 size_t cn, loff_t *ppos)
1158 {
1159         char *smack = "";
1160         ssize_t rc = -EINVAL;
1161         int asize;
1162
1163         if (*ppos != 0)
1164                 return 0;
1165
1166         if (smack_onlycap != NULL)
1167                 smack = smack_onlycap;
1168
1169         asize = strlen(smack) + 1;
1170
1171         if (cn >= asize)
1172                 rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
1173
1174         return rc;
1175 }
1176
1177 /**
1178  * smk_write_onlycap - write() for /smack/onlycap
1179  * @file: file pointer, not actually used
1180  * @buf: where to get the data from
1181  * @count: bytes sent
1182  * @ppos: where to start
1183  *
1184  * Returns number of bytes written or error code, as appropriate
1185  */
1186 static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1187                                  size_t count, loff_t *ppos)
1188 {
1189         char in[SMK_LABELLEN];
1190         char *sp = smk_of_task(current->cred->security);
1191
1192         if (!capable(CAP_MAC_ADMIN))
1193                 return -EPERM;
1194
1195         /*
1196          * This can be done using smk_access() but is done
1197          * explicitly for clarity. The smk_access() implementation
1198          * would use smk_access(smack_onlycap, MAY_WRITE)
1199          */
1200         if (smack_onlycap != NULL && smack_onlycap != sp)
1201                 return -EPERM;
1202
1203         if (count >= SMK_LABELLEN)
1204                 return -EINVAL;
1205
1206         if (copy_from_user(in, buf, count) != 0)
1207                 return -EFAULT;
1208
1209         /*
1210          * Should the null string be passed in unset the onlycap value.
1211          * This seems like something to be careful with as usually
1212          * smk_import only expects to return NULL for errors. It
1213          * is usually the case that a nullstring or "\n" would be
1214          * bad to pass to smk_import but in fact this is useful here.
1215          */
1216         smack_onlycap = smk_import(in, count);
1217
1218         return count;
1219 }
1220
1221 static const struct file_operations smk_onlycap_ops = {
1222         .read           = smk_read_onlycap,
1223         .write          = smk_write_onlycap,
1224         .llseek         = default_llseek,
1225 };
1226
1227 /**
1228  * smk_read_logging - read() for /smack/logging
1229  * @filp: file pointer, not actually used
1230  * @buf: where to put the result
1231  * @cn: maximum to send along
1232  * @ppos: where to start
1233  *
1234  * Returns number of bytes read or error code, as appropriate
1235  */
1236 static ssize_t smk_read_logging(struct file *filp, char __user *buf,
1237                                 size_t count, loff_t *ppos)
1238 {
1239         char temp[32];
1240         ssize_t rc;
1241
1242         if (*ppos != 0)
1243                 return 0;
1244
1245         sprintf(temp, "%d\n", log_policy);
1246         rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1247         return rc;
1248 }
1249
1250 /**
1251  * smk_write_logging - write() for /smack/logging
1252  * @file: file pointer, not actually used
1253  * @buf: where to get the data from
1254  * @count: bytes sent
1255  * @ppos: where to start
1256  *
1257  * Returns number of bytes written or error code, as appropriate
1258  */
1259 static ssize_t smk_write_logging(struct file *file, const char __user *buf,
1260                                 size_t count, loff_t *ppos)
1261 {
1262         char temp[32];
1263         int i;
1264
1265         if (!capable(CAP_MAC_ADMIN))
1266                 return -EPERM;
1267
1268         if (count >= sizeof(temp) || count == 0)
1269                 return -EINVAL;
1270
1271         if (copy_from_user(temp, buf, count) != 0)
1272                 return -EFAULT;
1273
1274         temp[count] = '\0';
1275
1276         if (sscanf(temp, "%d", &i) != 1)
1277                 return -EINVAL;
1278         if (i < 0 || i > 3)
1279                 return -EINVAL;
1280         log_policy = i;
1281         return count;
1282 }
1283
1284
1285
1286 static const struct file_operations smk_logging_ops = {
1287         .read           = smk_read_logging,
1288         .write          = smk_write_logging,
1289         .llseek         = default_llseek,
1290 };
1291 /**
1292  * smk_fill_super - fill the /smackfs superblock
1293  * @sb: the empty superblock
1294  * @data: unused
1295  * @silent: unused
1296  *
1297  * Fill in the well known entries for /smack
1298  *
1299  * Returns 0 on success, an error code on failure
1300  */
1301 static int smk_fill_super(struct super_block *sb, void *data, int silent)
1302 {
1303         int rc;
1304         struct inode *root_inode;
1305
1306         static struct tree_descr smack_files[] = {
1307                 [SMK_LOAD]      =
1308                         {"load", &smk_load_ops, S_IRUGO|S_IWUSR},
1309                 [SMK_CIPSO]     =
1310                         {"cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR},
1311                 [SMK_DOI]       =
1312                         {"doi", &smk_doi_ops, S_IRUGO|S_IWUSR},
1313                 [SMK_DIRECT]    =
1314                         {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR},
1315                 [SMK_AMBIENT]   =
1316                         {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
1317                 [SMK_NETLBLADDR] =
1318                         {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR},
1319                 [SMK_ONLYCAP]   =
1320                         {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
1321                 [SMK_LOGGING]   =
1322                         {"logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
1323                 /* last one */ {""}
1324         };
1325
1326         rc = simple_fill_super(sb, SMACK_MAGIC, smack_files);
1327         if (rc != 0) {
1328                 printk(KERN_ERR "%s failed %d while creating inodes\n",
1329                         __func__, rc);
1330                 return rc;
1331         }
1332
1333         root_inode = sb->s_root->d_inode;
1334         root_inode->i_security = new_inode_smack(smack_known_floor.smk_known);
1335
1336         return 0;
1337 }
1338
1339 /**
1340  * smk_mount - get the smackfs superblock
1341  * @fs_type: passed along without comment
1342  * @flags: passed along without comment
1343  * @dev_name: passed along without comment
1344  * @data: passed along without comment
1345  *
1346  * Just passes everything along.
1347  *
1348  * Returns what the lower level code does.
1349  */
1350 static struct dentry *smk_mount(struct file_system_type *fs_type,
1351                       int flags, const char *dev_name, void *data)
1352 {
1353         return mount_single(fs_type, flags, data, smk_fill_super);
1354 }
1355
1356 static struct file_system_type smk_fs_type = {
1357         .name           = "smackfs",
1358         .mount          = smk_mount,
1359         .kill_sb        = kill_litter_super,
1360 };
1361
1362 static struct vfsmount *smackfs_mount;
1363
1364 /**
1365  * init_smk_fs - get the smackfs superblock
1366  *
1367  * register the smackfs
1368  *
1369  * Do not register smackfs if Smack wasn't enabled
1370  * on boot. We can not put this method normally under the
1371  * smack_init() code path since the security subsystem get
1372  * initialized before the vfs caches.
1373  *
1374  * Returns true if we were not chosen on boot or if
1375  * we were chosen and filesystem registration succeeded.
1376  */
1377 static int __init init_smk_fs(void)
1378 {
1379         int err;
1380
1381         if (!security_module_enable(&smack_ops))
1382                 return 0;
1383
1384         err = register_filesystem(&smk_fs_type);
1385         if (!err) {
1386                 smackfs_mount = kern_mount(&smk_fs_type);
1387                 if (IS_ERR(smackfs_mount)) {
1388                         printk(KERN_ERR "smackfs:  could not mount!\n");
1389                         err = PTR_ERR(smackfs_mount);
1390                         smackfs_mount = NULL;
1391                 }
1392         }
1393
1394         smk_cipso_doi();
1395         smk_unlbl_ambient(NULL);
1396
1397         return err;
1398 }
1399
1400 __initcall(init_smk_fs);