• Home
  • Raw
  • Download

Lines Matching +full:container +full:- +full:rules

1 // SPDX-License-Identifier: GPL-2.0
3 * device_cgroup.c - device cgroup subsystem
29 * exception list locking rules:
71 list_add_tail(&new->list, dest); in dev_exceptions_copy()
78 list_del(&ex->list); in dev_exceptions_copy()
81 return -ENOMEM; in dev_exceptions_copy()
91 list_move_tail(&ex->list, dest); in dev_exceptions_move()
107 return -ENOMEM; in dev_exception_add()
109 list_for_each_entry(walk, &dev_cgroup->exceptions, list) { in dev_exception_add()
110 if (walk->type != ex->type) in dev_exception_add()
112 if (walk->major != ex->major) in dev_exception_add()
114 if (walk->minor != ex->minor) in dev_exception_add()
117 walk->access |= ex->access; in dev_exception_add()
123 list_add_tail_rcu(&excopy->list, &dev_cgroup->exceptions); in dev_exception_add()
137 list_for_each_entry_safe(walk, tmp, &dev_cgroup->exceptions, list) { in dev_exception_rm()
138 if (walk->type != ex->type) in dev_exception_rm()
140 if (walk->major != ex->major) in dev_exception_rm()
142 if (walk->minor != ex->minor) in dev_exception_rm()
145 walk->access &= ~ex->access; in dev_exception_rm()
146 if (!walk->access) { in dev_exception_rm()
147 list_del_rcu(&walk->list); in dev_exception_rm()
157 list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { in __dev_exception_clean()
158 list_del_rcu(&ex->list); in __dev_exception_clean()
164 * dev_exception_clean - frees all entries of the exception list
178 return (devcg->behavior != DEVCG_DEFAULT_NONE); in is_devcg_online()
182 * devcgroup_online - initializes devcgroup's behavior and exceptions based on
190 struct dev_cgroup *parent_dev_cgroup = css_to_devcgroup(css->parent); in devcgroup_online()
196 dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; in devcgroup_online()
198 ret = dev_exceptions_copy(&dev_cgroup->exceptions, in devcgroup_online()
199 &parent_dev_cgroup->exceptions); in devcgroup_online()
201 dev_cgroup->behavior = parent_dev_cgroup->behavior; in devcgroup_online()
213 dev_cgroup->behavior = DEVCG_DEFAULT_NONE; in devcgroup_offline()
227 return ERR_PTR(-ENOMEM); in devcgroup_css_alloc()
228 INIT_LIST_HEAD(&dev_cgroup->exceptions); in devcgroup_css_alloc()
229 dev_cgroup->behavior = DEVCG_DEFAULT_NONE; in devcgroup_css_alloc()
231 return &dev_cgroup->css; in devcgroup_css_alloc()
289 * - Only show the "all devices" when the default policy is to allow in devcgroup_seq_show()
290 * - List the exceptions in case the default policy is to deny in devcgroup_seq_show()
293 if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) { in devcgroup_seq_show()
300 list_for_each_entry_rcu(ex, &devcgroup->exceptions, list) { in devcgroup_seq_show()
301 set_access(acc, ex->access); in devcgroup_seq_show()
302 set_majmin(maj, ex->major); in devcgroup_seq_show()
303 set_majmin(min, ex->minor); in devcgroup_seq_show()
304 seq_printf(m, "%c %s:%s %s\n", type_to_char(ex->type), in devcgroup_seq_show()
314 * match_exception - iterates the exception list trying to find a complete match
332 if ((type & DEVCG_DEV_BLOCK) && !(ex->type & DEVCG_DEV_BLOCK)) in match_exception()
334 if ((type & DEVCG_DEV_CHAR) && !(ex->type & DEVCG_DEV_CHAR)) in match_exception()
336 if (ex->major != ~0 && ex->major != major) in match_exception()
338 if (ex->minor != ~0 && ex->minor != minor) in match_exception()
341 if (access & (~ex->access)) in match_exception()
349 * match_exception_partial - iterates the exception list trying to find a partial match
370 if ((type & DEVCG_DEV_BLOCK) && !(ex->type & DEVCG_DEV_BLOCK)) in match_exception_partial()
372 if ((type & DEVCG_DEV_CHAR) && !(ex->type & DEVCG_DEV_CHAR)) in match_exception_partial()
378 if (ex->major != ~0 && major != ~0 && ex->major != major) in match_exception_partial()
380 if (ex->minor != ~0 && minor != ~0 && ex->minor != minor) in match_exception_partial()
387 if (!(access & ex->access)) in match_exception_partial()
395 * verify_new_ex - verifies if a new exception is allowed by parent cgroup's permissions
413 if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) { in verify_new_ex()
426 match = match_exception_partial(&dev_cgroup->exceptions, in verify_new_ex()
427 refex->type, in verify_new_ex()
428 refex->major, in verify_new_ex()
429 refex->minor, in verify_new_ex()
430 refex->access); in verify_new_ex()
443 match = match_exception(&dev_cgroup->exceptions, refex->type, in verify_new_ex()
444 refex->major, refex->minor, in verify_new_ex()
445 refex->access); in verify_new_ex()
464 struct dev_cgroup *parent = css_to_devcgroup(childcg->css.parent); in parent_has_perm()
468 return verify_new_ex(parent, ex, childcg->behavior); in parent_has_perm()
472 * parent_allows_removal - verify if it's ok to remove an exception
485 struct dev_cgroup *parent = css_to_devcgroup(childcg->css.parent); in parent_allows_removal()
491 if (childcg->behavior == DEVCG_DEFAULT_DENY) in parent_allows_removal()
498 return !match_exception_partial(&parent->exceptions, ex->type, in parent_allows_removal()
499 ex->major, ex->minor, ex->access); in parent_allows_removal()
503 * may_allow_all - checks if it's possible to change the behavior to
504 * allow based on parent's rules.
512 return parent->behavior == DEVCG_DEFAULT_ALLOW; in may_allow_all()
516 * revalidate_active_exceptions - walks through the active exception list and
524 * This function is responsible for re-evaluating all the cgroup's active
526 * Refer to Documentation/admin-guide/cgroup-v1/devices.rst for more details.
533 list_for_each_safe(this, tmp, &devcg->exceptions) { in revalidate_active_exceptions()
541 * propagate_exception - propagates a new exception to the children
555 css_for_each_descendant_pre(pos, &devcg_root->css) { in propagate_exception()
564 if (pos == &devcg_root->css || !is_devcg_online(devcg)) in propagate_exception()
573 if (devcg_root->behavior == DEVCG_DEFAULT_ALLOW && in propagate_exception()
574 devcg->behavior == DEVCG_DEFAULT_ALLOW) { in propagate_exception()
597 * Modify the exception list using allow/deny rules.
599 * so we can give a container CAP_MKNOD to let it create devices but not
605 * Taking rules away is always allowed (given CAP_SYS_ADMIN). Granting
606 * new access is only allowed if you're in the top-level cgroup, or your
616 struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent); in devcgroup_update_access()
620 return -EPERM; in devcgroup_update_access()
630 if (css_has_online_children(&devcgroup->css)) in devcgroup_update_access()
631 return -EINVAL; in devcgroup_update_access()
634 return -EPERM; in devcgroup_update_access()
636 devcgroup->behavior = DEVCG_DEFAULT_ALLOW; in devcgroup_update_access()
643 &devcgroup->exceptions); in devcgroup_update_access()
647 rc = dev_exceptions_copy(&devcgroup->exceptions, in devcgroup_update_access()
648 &parent->exceptions); in devcgroup_update_access()
650 dev_exceptions_move(&devcgroup->exceptions, in devcgroup_update_access()
654 devcgroup->behavior = DEVCG_DEFAULT_ALLOW; in devcgroup_update_access()
658 if (css_has_online_children(&devcgroup->css)) in devcgroup_update_access()
659 return -EINVAL; in devcgroup_update_access()
662 devcgroup->behavior = DEVCG_DEFAULT_DENY; in devcgroup_update_access()
665 return -EINVAL; in devcgroup_update_access()
675 return -EINVAL; in devcgroup_update_access()
679 return -EINVAL; in devcgroup_update_access()
686 for (count = 0; count < sizeof(temp) - 1; count++) { in devcgroup_update_access()
694 return -EINVAL; in devcgroup_update_access()
696 return -EINVAL; in devcgroup_update_access()
699 return -EINVAL; in devcgroup_update_access()
708 for (count = 0; count < sizeof(temp) - 1; count++) { in devcgroup_update_access()
716 return -EINVAL; in devcgroup_update_access()
718 return -EINVAL; in devcgroup_update_access()
721 return -EINVAL; in devcgroup_update_access()
738 return -EINVAL; in devcgroup_update_access()
749 if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) { in devcgroup_update_access()
752 return -EPERM; in devcgroup_update_access()
758 return -EPERM; in devcgroup_update_access()
767 if (devcgroup->behavior == DEVCG_DEFAULT_DENY) in devcgroup_update_access()
778 rc = -EINVAL; in devcgroup_update_access()
790 of_cft(of)->private, strstrip(buf)); in devcgroup_access_write()
823 * devcgroup_legacy_check_permission - checks if an inode operation is permitted
830 * returns 0 on success, -EPERM case the operation is not permitted
840 if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) in devcgroup_legacy_check_permission()
842 rc = !match_exception_partial(&dev_cgroup->exceptions, in devcgroup_legacy_check_permission()
846 rc = match_exception(&dev_cgroup->exceptions, type, major, in devcgroup_legacy_check_permission()
851 return -EPERM; in devcgroup_legacy_check_permission()
865 return -EPERM; in devcgroup_check_permission()