Merge tag 'nfs-for-3.15-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[linux.git] / security / device_cgroup.c
1 /*
2  * device_cgroup.c - device cgroup subsystem
3  *
4  * Copyright 2007 IBM Corp
5  */
6
7 #include <linux/device_cgroup.h>
8 #include <linux/cgroup.h>
9 #include <linux/ctype.h>
10 #include <linux/list.h>
11 #include <linux/uaccess.h>
12 #include <linux/seq_file.h>
13 #include <linux/slab.h>
14 #include <linux/rcupdate.h>
15 #include <linux/mutex.h>
16
17 #define ACC_MKNOD 1
18 #define ACC_READ  2
19 #define ACC_WRITE 4
20 #define ACC_MASK (ACC_MKNOD | ACC_READ | ACC_WRITE)
21
22 #define DEV_BLOCK 1
23 #define DEV_CHAR  2
24 #define DEV_ALL   4  /* this represents all devices */
25
26 static DEFINE_MUTEX(devcgroup_mutex);
27
28 enum devcg_behavior {
29         DEVCG_DEFAULT_NONE,
30         DEVCG_DEFAULT_ALLOW,
31         DEVCG_DEFAULT_DENY,
32 };
33
34 /*
35  * exception list locking rules:
36  * hold devcgroup_mutex for update/read.
37  * hold rcu_read_lock() for read.
38  */
39
40 struct dev_exception_item {
41         u32 major, minor;
42         short type;
43         short access;
44         struct list_head list;
45         struct rcu_head rcu;
46 };
47
48 struct dev_cgroup {
49         struct cgroup_subsys_state css;
50         struct list_head exceptions;
51         enum devcg_behavior behavior;
52 };
53
54 static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s)
55 {
56         return s ? container_of(s, struct dev_cgroup, css) : NULL;
57 }
58
59 static inline struct dev_cgroup *task_devcgroup(struct task_struct *task)
60 {
61         return css_to_devcgroup(task_css(task, devices_cgrp_id));
62 }
63
64 /*
65  * called under devcgroup_mutex
66  */
67 static int dev_exceptions_copy(struct list_head *dest, struct list_head *orig)
68 {
69         struct dev_exception_item *ex, *tmp, *new;
70
71         lockdep_assert_held(&devcgroup_mutex);
72
73         list_for_each_entry(ex, orig, list) {
74                 new = kmemdup(ex, sizeof(*ex), GFP_KERNEL);
75                 if (!new)
76                         goto free_and_exit;
77                 list_add_tail(&new->list, dest);
78         }
79
80         return 0;
81
82 free_and_exit:
83         list_for_each_entry_safe(ex, tmp, dest, list) {
84                 list_del(&ex->list);
85                 kfree(ex);
86         }
87         return -ENOMEM;
88 }
89
90 /*
91  * called under devcgroup_mutex
92  */
93 static int dev_exception_add(struct dev_cgroup *dev_cgroup,
94                              struct dev_exception_item *ex)
95 {
96         struct dev_exception_item *excopy, *walk;
97
98         lockdep_assert_held(&devcgroup_mutex);
99
100         excopy = kmemdup(ex, sizeof(*ex), GFP_KERNEL);
101         if (!excopy)
102                 return -ENOMEM;
103
104         list_for_each_entry(walk, &dev_cgroup->exceptions, list) {
105                 if (walk->type != ex->type)
106                         continue;
107                 if (walk->major != ex->major)
108                         continue;
109                 if (walk->minor != ex->minor)
110                         continue;
111
112                 walk->access |= ex->access;
113                 kfree(excopy);
114                 excopy = NULL;
115         }
116
117         if (excopy != NULL)
118                 list_add_tail_rcu(&excopy->list, &dev_cgroup->exceptions);
119         return 0;
120 }
121
122 /*
123  * called under devcgroup_mutex
124  */
125 static void dev_exception_rm(struct dev_cgroup *dev_cgroup,
126                              struct dev_exception_item *ex)
127 {
128         struct dev_exception_item *walk, *tmp;
129
130         lockdep_assert_held(&devcgroup_mutex);
131
132         list_for_each_entry_safe(walk, tmp, &dev_cgroup->exceptions, list) {
133                 if (walk->type != ex->type)
134                         continue;
135                 if (walk->major != ex->major)
136                         continue;
137                 if (walk->minor != ex->minor)
138                         continue;
139
140                 walk->access &= ~ex->access;
141                 if (!walk->access) {
142                         list_del_rcu(&walk->list);
143                         kfree_rcu(walk, rcu);
144                 }
145         }
146 }
147
148 static void __dev_exception_clean(struct dev_cgroup *dev_cgroup)
149 {
150         struct dev_exception_item *ex, *tmp;
151
152         list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) {
153                 list_del_rcu(&ex->list);
154                 kfree_rcu(ex, rcu);
155         }
156 }
157
158 /**
159  * dev_exception_clean - frees all entries of the exception list
160  * @dev_cgroup: dev_cgroup with the exception list to be cleaned
161  *
162  * called under devcgroup_mutex
163  */
164 static void dev_exception_clean(struct dev_cgroup *dev_cgroup)
165 {
166         lockdep_assert_held(&devcgroup_mutex);
167
168         __dev_exception_clean(dev_cgroup);
169 }
170
171 static inline bool is_devcg_online(const struct dev_cgroup *devcg)
172 {
173         return (devcg->behavior != DEVCG_DEFAULT_NONE);
174 }
175
176 /**
177  * devcgroup_online - initializes devcgroup's behavior and exceptions based on
178  *                    parent's
179  * @css: css getting online
180  * returns 0 in case of success, error code otherwise
181  */
182 static int devcgroup_online(struct cgroup_subsys_state *css)
183 {
184         struct dev_cgroup *dev_cgroup = css_to_devcgroup(css);
185         struct dev_cgroup *parent_dev_cgroup = css_to_devcgroup(css_parent(css));
186         int ret = 0;
187
188         mutex_lock(&devcgroup_mutex);
189
190         if (parent_dev_cgroup == NULL)
191                 dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW;
192         else {
193                 ret = dev_exceptions_copy(&dev_cgroup->exceptions,
194                                           &parent_dev_cgroup->exceptions);
195                 if (!ret)
196                         dev_cgroup->behavior = parent_dev_cgroup->behavior;
197         }
198         mutex_unlock(&devcgroup_mutex);
199
200         return ret;
201 }
202
203 static void devcgroup_offline(struct cgroup_subsys_state *css)
204 {
205         struct dev_cgroup *dev_cgroup = css_to_devcgroup(css);
206
207         mutex_lock(&devcgroup_mutex);
208         dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
209         mutex_unlock(&devcgroup_mutex);
210 }
211
212 /*
213  * called from kernel/cgroup.c with cgroup_lock() held.
214  */
215 static struct cgroup_subsys_state *
216 devcgroup_css_alloc(struct cgroup_subsys_state *parent_css)
217 {
218         struct dev_cgroup *dev_cgroup;
219
220         dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL);
221         if (!dev_cgroup)
222                 return ERR_PTR(-ENOMEM);
223         INIT_LIST_HEAD(&dev_cgroup->exceptions);
224         dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
225
226         return &dev_cgroup->css;
227 }
228
229 static void devcgroup_css_free(struct cgroup_subsys_state *css)
230 {
231         struct dev_cgroup *dev_cgroup = css_to_devcgroup(css);
232
233         __dev_exception_clean(dev_cgroup);
234         kfree(dev_cgroup);
235 }
236
237 #define DEVCG_ALLOW 1
238 #define DEVCG_DENY 2
239 #define DEVCG_LIST 3
240
241 #define MAJMINLEN 13
242 #define ACCLEN 4
243
244 static void set_access(char *acc, short access)
245 {
246         int idx = 0;
247         memset(acc, 0, ACCLEN);
248         if (access & ACC_READ)
249                 acc[idx++] = 'r';
250         if (access & ACC_WRITE)
251                 acc[idx++] = 'w';
252         if (access & ACC_MKNOD)
253                 acc[idx++] = 'm';
254 }
255
256 static char type_to_char(short type)
257 {
258         if (type == DEV_ALL)
259                 return 'a';
260         if (type == DEV_CHAR)
261                 return 'c';
262         if (type == DEV_BLOCK)
263                 return 'b';
264         return 'X';
265 }
266
267 static void set_majmin(char *str, unsigned m)
268 {
269         if (m == ~0)
270                 strcpy(str, "*");
271         else
272                 sprintf(str, "%u", m);
273 }
274
275 static int devcgroup_seq_show(struct seq_file *m, void *v)
276 {
277         struct dev_cgroup *devcgroup = css_to_devcgroup(seq_css(m));
278         struct dev_exception_item *ex;
279         char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
280
281         rcu_read_lock();
282         /*
283          * To preserve the compatibility:
284          * - Only show the "all devices" when the default policy is to allow
285          * - List the exceptions in case the default policy is to deny
286          * This way, the file remains as a "whitelist of devices"
287          */
288         if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) {
289                 set_access(acc, ACC_MASK);
290                 set_majmin(maj, ~0);
291                 set_majmin(min, ~0);
292                 seq_printf(m, "%c %s:%s %s\n", type_to_char(DEV_ALL),
293                            maj, min, acc);
294         } else {
295                 list_for_each_entry_rcu(ex, &devcgroup->exceptions, list) {
296                         set_access(acc, ex->access);
297                         set_majmin(maj, ex->major);
298                         set_majmin(min, ex->minor);
299                         seq_printf(m, "%c %s:%s %s\n", type_to_char(ex->type),
300                                    maj, min, acc);
301                 }
302         }
303         rcu_read_unlock();
304
305         return 0;
306 }
307
308 /**
309  * may_access - verifies if a new exception is part of what is allowed
310  *              by a dev cgroup based on the default policy +
311  *              exceptions. This is used to make sure a child cgroup
312  *              won't have more privileges than its parent or to
313  *              verify if a certain access is allowed.
314  * @dev_cgroup: dev cgroup to be tested against
315  * @refex: new exception
316  * @behavior: behavior of the exception
317  */
318 static bool may_access(struct dev_cgroup *dev_cgroup,
319                        struct dev_exception_item *refex,
320                        enum devcg_behavior behavior)
321 {
322         struct dev_exception_item *ex;
323         bool match = false;
324
325         rcu_lockdep_assert(rcu_read_lock_held() ||
326                            lockdep_is_held(&devcgroup_mutex),
327                            "device_cgroup::may_access() called without proper synchronization");
328
329         list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
330                 if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
331                         continue;
332                 if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR))
333                         continue;
334                 if (ex->major != ~0 && ex->major != refex->major)
335                         continue;
336                 if (ex->minor != ~0 && ex->minor != refex->minor)
337                         continue;
338                 if (refex->access & (~ex->access))
339                         continue;
340                 match = true;
341                 break;
342         }
343
344         if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) {
345                 if (behavior == DEVCG_DEFAULT_ALLOW) {
346                         /* the exception will deny access to certain devices */
347                         return true;
348                 } else {
349                         /* the exception will allow access to certain devices */
350                         if (match)
351                                 /*
352                                  * a new exception allowing access shouldn't
353                                  * match an parent's exception
354                                  */
355                                 return false;
356                         return true;
357                 }
358         } else {
359                 /* only behavior == DEVCG_DEFAULT_DENY allowed here */
360                 if (match)
361                         /* parent has an exception that matches the proposed */
362                         return true;
363                 else
364                         return false;
365         }
366         return false;
367 }
368
369 /*
370  * parent_has_perm:
371  * when adding a new allow rule to a device exception list, the rule
372  * must be allowed in the parent device
373  */
374 static int parent_has_perm(struct dev_cgroup *childcg,
375                                   struct dev_exception_item *ex)
376 {
377         struct dev_cgroup *parent = css_to_devcgroup(css_parent(&childcg->css));
378
379         if (!parent)
380                 return 1;
381         return may_access(parent, ex, childcg->behavior);
382 }
383
384 /**
385  * may_allow_all - checks if it's possible to change the behavior to
386  *                 allow based on parent's rules.
387  * @parent: device cgroup's parent
388  * returns: != 0 in case it's allowed, 0 otherwise
389  */
390 static inline int may_allow_all(struct dev_cgroup *parent)
391 {
392         if (!parent)
393                 return 1;
394         return parent->behavior == DEVCG_DEFAULT_ALLOW;
395 }
396
397 /**
398  * revalidate_active_exceptions - walks through the active exception list and
399  *                                revalidates the exceptions based on parent's
400  *                                behavior and exceptions. The exceptions that
401  *                                are no longer valid will be removed.
402  *                                Called with devcgroup_mutex held.
403  * @devcg: cgroup which exceptions will be checked
404  *
405  * This is one of the three key functions for hierarchy implementation.
406  * This function is responsible for re-evaluating all the cgroup's active
407  * exceptions due to a parent's exception change.
408  * Refer to Documentation/cgroups/devices.txt for more details.
409  */
410 static void revalidate_active_exceptions(struct dev_cgroup *devcg)
411 {
412         struct dev_exception_item *ex;
413         struct list_head *this, *tmp;
414
415         list_for_each_safe(this, tmp, &devcg->exceptions) {
416                 ex = container_of(this, struct dev_exception_item, list);
417                 if (!parent_has_perm(devcg, ex))
418                         dev_exception_rm(devcg, ex);
419         }
420 }
421
422 /**
423  * propagate_exception - propagates a new exception to the children
424  * @devcg_root: device cgroup that added a new exception
425  * @ex: new exception to be propagated
426  *
427  * returns: 0 in case of success, != 0 in case of error
428  */
429 static int propagate_exception(struct dev_cgroup *devcg_root,
430                                struct dev_exception_item *ex)
431 {
432         struct cgroup_subsys_state *pos;
433         int rc = 0;
434
435         rcu_read_lock();
436
437         css_for_each_descendant_pre(pos, &devcg_root->css) {
438                 struct dev_cgroup *devcg = css_to_devcgroup(pos);
439
440                 /*
441                  * Because devcgroup_mutex is held, no devcg will become
442                  * online or offline during the tree walk (see on/offline
443                  * methods), and online ones are safe to access outside RCU
444                  * read lock without bumping refcnt.
445                  */
446                 if (pos == &devcg_root->css || !is_devcg_online(devcg))
447                         continue;
448
449                 rcu_read_unlock();
450
451                 /*
452                  * in case both root's behavior and devcg is allow, a new
453                  * restriction means adding to the exception list
454                  */
455                 if (devcg_root->behavior == DEVCG_DEFAULT_ALLOW &&
456                     devcg->behavior == DEVCG_DEFAULT_ALLOW) {
457                         rc = dev_exception_add(devcg, ex);
458                         if (rc)
459                                 break;
460                 } else {
461                         /*
462                          * in the other possible cases:
463                          * root's behavior: allow, devcg's: deny
464                          * root's behavior: deny, devcg's: deny
465                          * the exception will be removed
466                          */
467                         dev_exception_rm(devcg, ex);
468                 }
469                 revalidate_active_exceptions(devcg);
470
471                 rcu_read_lock();
472         }
473
474         rcu_read_unlock();
475         return rc;
476 }
477
478 static inline bool has_children(struct dev_cgroup *devcgroup)
479 {
480         struct cgroup *cgrp = devcgroup->css.cgroup;
481
482         return !list_empty(&cgrp->children);
483 }
484
485 /*
486  * Modify the exception list using allow/deny rules.
487  * CAP_SYS_ADMIN is needed for this.  It's at least separate from CAP_MKNOD
488  * so we can give a container CAP_MKNOD to let it create devices but not
489  * modify the exception list.
490  * It seems likely we'll want to add a CAP_CONTAINER capability to allow
491  * us to also grant CAP_SYS_ADMIN to containers without giving away the
492  * device exception list controls, but for now we'll stick with CAP_SYS_ADMIN
493  *
494  * Taking rules away is always allowed (given CAP_SYS_ADMIN).  Granting
495  * new access is only allowed if you're in the top-level cgroup, or your
496  * parent cgroup has the access you're asking for.
497  */
498 static int devcgroup_update_access(struct dev_cgroup *devcgroup,
499                                    int filetype, char *buffer)
500 {
501         const char *b;
502         char temp[12];          /* 11 + 1 characters needed for a u32 */
503         int count, rc = 0;
504         struct dev_exception_item ex;
505         struct dev_cgroup *parent = css_to_devcgroup(css_parent(&devcgroup->css));
506
507         if (!capable(CAP_SYS_ADMIN))
508                 return -EPERM;
509
510         memset(&ex, 0, sizeof(ex));
511         b = buffer;
512
513         switch (*b) {
514         case 'a':
515                 switch (filetype) {
516                 case DEVCG_ALLOW:
517                         if (has_children(devcgroup))
518                                 return -EINVAL;
519
520                         if (!may_allow_all(parent))
521                                 return -EPERM;
522                         dev_exception_clean(devcgroup);
523                         devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
524                         if (!parent)
525                                 break;
526
527                         rc = dev_exceptions_copy(&devcgroup->exceptions,
528                                                  &parent->exceptions);
529                         if (rc)
530                                 return rc;
531                         break;
532                 case DEVCG_DENY:
533                         if (has_children(devcgroup))
534                                 return -EINVAL;
535
536                         dev_exception_clean(devcgroup);
537                         devcgroup->behavior = DEVCG_DEFAULT_DENY;
538                         break;
539                 default:
540                         return -EINVAL;
541                 }
542                 return 0;
543         case 'b':
544                 ex.type = DEV_BLOCK;
545                 break;
546         case 'c':
547                 ex.type = DEV_CHAR;
548                 break;
549         default:
550                 return -EINVAL;
551         }
552         b++;
553         if (!isspace(*b))
554                 return -EINVAL;
555         b++;
556         if (*b == '*') {
557                 ex.major = ~0;
558                 b++;
559         } else if (isdigit(*b)) {
560                 memset(temp, 0, sizeof(temp));
561                 for (count = 0; count < sizeof(temp) - 1; count++) {
562                         temp[count] = *b;
563                         b++;
564                         if (!isdigit(*b))
565                                 break;
566                 }
567                 rc = kstrtou32(temp, 10, &ex.major);
568                 if (rc)
569                         return -EINVAL;
570         } else {
571                 return -EINVAL;
572         }
573         if (*b != ':')
574                 return -EINVAL;
575         b++;
576
577         /* read minor */
578         if (*b == '*') {
579                 ex.minor = ~0;
580                 b++;
581         } else if (isdigit(*b)) {
582                 memset(temp, 0, sizeof(temp));
583                 for (count = 0; count < sizeof(temp) - 1; count++) {
584                         temp[count] = *b;
585                         b++;
586                         if (!isdigit(*b))
587                                 break;
588                 }
589                 rc = kstrtou32(temp, 10, &ex.minor);
590                 if (rc)
591                         return -EINVAL;
592         } else {
593                 return -EINVAL;
594         }
595         if (!isspace(*b))
596                 return -EINVAL;
597         for (b++, count = 0; count < 3; count++, b++) {
598                 switch (*b) {
599                 case 'r':
600                         ex.access |= ACC_READ;
601                         break;
602                 case 'w':
603                         ex.access |= ACC_WRITE;
604                         break;
605                 case 'm':
606                         ex.access |= ACC_MKNOD;
607                         break;
608                 case '\n':
609                 case '\0':
610                         count = 3;
611                         break;
612                 default:
613                         return -EINVAL;
614                 }
615         }
616
617         switch (filetype) {
618         case DEVCG_ALLOW:
619                 if (!parent_has_perm(devcgroup, &ex))
620                         return -EPERM;
621                 /*
622                  * If the default policy is to allow by default, try to remove
623                  * an matching exception instead. And be silent about it: we
624                  * don't want to break compatibility
625                  */
626                 if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) {
627                         dev_exception_rm(devcgroup, &ex);
628                         return 0;
629                 }
630                 rc = dev_exception_add(devcgroup, &ex);
631                 break;
632         case DEVCG_DENY:
633                 /*
634                  * If the default policy is to deny by default, try to remove
635                  * an matching exception instead. And be silent about it: we
636                  * don't want to break compatibility
637                  */
638                 if (devcgroup->behavior == DEVCG_DEFAULT_DENY)
639                         dev_exception_rm(devcgroup, &ex);
640                 else
641                         rc = dev_exception_add(devcgroup, &ex);
642
643                 if (rc)
644                         break;
645                 /* we only propagate new restrictions */
646                 rc = propagate_exception(devcgroup, &ex);
647                 break;
648         default:
649                 rc = -EINVAL;
650         }
651         return rc;
652 }
653
654 static int devcgroup_access_write(struct cgroup_subsys_state *css,
655                                   struct cftype *cft, char *buffer)
656 {
657         int retval;
658
659         mutex_lock(&devcgroup_mutex);
660         retval = devcgroup_update_access(css_to_devcgroup(css),
661                                          cft->private, buffer);
662         mutex_unlock(&devcgroup_mutex);
663         return retval;
664 }
665
666 static struct cftype dev_cgroup_files[] = {
667         {
668                 .name = "allow",
669                 .write_string  = devcgroup_access_write,
670                 .private = DEVCG_ALLOW,
671         },
672         {
673                 .name = "deny",
674                 .write_string = devcgroup_access_write,
675                 .private = DEVCG_DENY,
676         },
677         {
678                 .name = "list",
679                 .seq_show = devcgroup_seq_show,
680                 .private = DEVCG_LIST,
681         },
682         { }     /* terminate */
683 };
684
685 struct cgroup_subsys devices_cgrp_subsys = {
686         .css_alloc = devcgroup_css_alloc,
687         .css_free = devcgroup_css_free,
688         .css_online = devcgroup_online,
689         .css_offline = devcgroup_offline,
690         .base_cftypes = dev_cgroup_files,
691 };
692
693 /**
694  * __devcgroup_check_permission - checks if an inode operation is permitted
695  * @dev_cgroup: the dev cgroup to be tested against
696  * @type: device type
697  * @major: device major number
698  * @minor: device minor number
699  * @access: combination of ACC_WRITE, ACC_READ and ACC_MKNOD
700  *
701  * returns 0 on success, -EPERM case the operation is not permitted
702  */
703 static int __devcgroup_check_permission(short type, u32 major, u32 minor,
704                                         short access)
705 {
706         struct dev_cgroup *dev_cgroup;
707         struct dev_exception_item ex;
708         int rc;
709
710         memset(&ex, 0, sizeof(ex));
711         ex.type = type;
712         ex.major = major;
713         ex.minor = minor;
714         ex.access = access;
715
716         rcu_read_lock();
717         dev_cgroup = task_devcgroup(current);
718         rc = may_access(dev_cgroup, &ex, dev_cgroup->behavior);
719         rcu_read_unlock();
720
721         if (!rc)
722                 return -EPERM;
723
724         return 0;
725 }
726
727 int __devcgroup_inode_permission(struct inode *inode, int mask)
728 {
729         short type, access = 0;
730
731         if (S_ISBLK(inode->i_mode))
732                 type = DEV_BLOCK;
733         if (S_ISCHR(inode->i_mode))
734                 type = DEV_CHAR;
735         if (mask & MAY_WRITE)
736                 access |= ACC_WRITE;
737         if (mask & MAY_READ)
738                 access |= ACC_READ;
739
740         return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
741                         access);
742 }
743
744 int devcgroup_inode_mknod(int mode, dev_t dev)
745 {
746         short type;
747
748         if (!S_ISBLK(mode) && !S_ISCHR(mode))
749                 return 0;
750
751         if (S_ISBLK(mode))
752                 type = DEV_BLOCK;
753         else
754                 type = DEV_CHAR;
755
756         return __devcgroup_check_permission(type, MAJOR(dev), MINOR(dev),
757                         ACC_MKNOD);
758
759 }