In order to revalidate local exceptions for the hierarchy change propagation, make may_access() stronger. Cc: Tejun Heo Cc: Serge Hallyn Signed-off-by: Aristeu Rozanski --- security/device_cgroup.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) Index: github/security/device_cgroup.c =================================================================== --- github.orig/security/device_cgroup.c 2012-11-26 17:28:04.399150628 -0500 +++ github/security/device_cgroup.c 2012-11-27 11:57:55.932996663 -0500 @@ -352,13 +352,14 @@ * won't have more privileges than its parent or to * verify if a certain access is allowed. * @dev_cgroup: dev cgroup to be tested against + * @behavior: behavior of the exception * @refex: new exception */ static int may_access(struct dev_cgroup *dev_cgroup, struct dev_exception_item *refex) { struct dev_exception_item *ex; - bool match = false; + int match = 0; rcu_lockdep_assert(rcu_read_lock_held() || lockdep_is_held(&devcgroup_mutex), @@ -375,22 +376,33 @@ continue; if (refex->access & (~ex->access)) continue; - match = true; + match = 1; break; } /* - * In two cases we'll consider this new exception valid: - * - the dev cgroup has its default policy to allow + exception list: - * the new exception should *not* match any of the exceptions - * (behavior == DEVCG_DEFAULT_ALLOW, !match) - * - the dev cgroup has its default policy to deny + exception list: - * the new exception *should* match the exceptions - * (behavior == DEVCG_DEFAULT_DENY, match) + * The only three possibilities are: + * devcg->behavior == ALLOW, rule behavior == ALLOW + * devcg->behavior == ALLOW, rule behavior == DENY + * devcg->behavior == DENY, rule behavior == DENY + * the remaining + * devcg->behavior == DENY, rule behavior == ALLOW + * won't be possible by hierarchy + * + * Since we want to simplify the code, here're the possibilites to + * make easier to understand: + * + * devcg behavior rule behavior match result + * allow allow 1 0 + * allow allow 0 1 + * allow deny 1 0 + * allow deny 0 1 + * deny deny 1 1 + * deny deny 0 0 */ - if ((dev_cgroup->behavior == DEVCG_DEFAULT_DENY) == match) - return 1; - return 0; + if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) + return !match; + return match; } /*