[PATCH 1/4] devcg: move behavior and exceptions into its own structure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Aristeu Rozanski <aris@xxxxxxxxx>

This patch is in preparation for the next one that will allow saving locally
set rules.

Signed-off-by: Aristeu Rozanski <aris@xxxxxxxxx>
---
 security/device_cgroup.c |   72 ++++++++++++++++++++++++++-------------------
 1 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index c123628..a4b7df4 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -45,12 +45,23 @@ struct dev_exception_item {
 	struct rcu_head rcu;
 };
 
-struct dev_cgroup {
-	struct cgroup_subsys_state css;
+struct devcg_rules {
 	struct list_head exceptions;
 	enum devcg_behavior behavior;
 };
 
+struct dev_cgroup {
+	struct cgroup_subsys_state css;
+	struct devcg_rules active_rules;
+};
+
+static inline struct list_head *active_exceptions(struct dev_cgroup *devcg)
+{
+	return &(devcg->active_rules.exceptions);
+}
+
+#define active_behavior(devcg) ((devcg)->active_rules.behavior)
+
 static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s)
 {
 	return s ? container_of(s, struct dev_cgroup, css) : NULL;
@@ -113,7 +124,7 @@ static int dev_exception_add(struct dev_cgroup *dev_cgroup,
 	if (!excopy)
 		return -ENOMEM;
 
-	list_for_each_entry(walk, &dev_cgroup->exceptions, list) {
+	list_for_each_entry(walk, active_exceptions(dev_cgroup), list) {
 		if (walk->type != ex->type)
 			continue;
 		if (walk->major != ex->major)
@@ -127,7 +138,7 @@ static int dev_exception_add(struct dev_cgroup *dev_cgroup,
 	}
 
 	if (excopy != NULL)
-		list_add_tail_rcu(&excopy->list, &dev_cgroup->exceptions);
+		list_add_tail_rcu(&excopy->list, active_exceptions(dev_cgroup));
 	return 0;
 }
 
@@ -141,7 +152,7 @@ static void dev_exception_rm(struct dev_cgroup *dev_cgroup,
 
 	lockdep_assert_held(&devcgroup_mutex);
 
-	list_for_each_entry_safe(walk, tmp, &dev_cgroup->exceptions, list) {
+	list_for_each_entry_safe(walk, tmp, active_exceptions(dev_cgroup), list) {
 		if (walk->type != ex->type)
 			continue;
 		if (walk->major != ex->major)
@@ -161,7 +172,7 @@ static void __dev_exception_clean(struct dev_cgroup *dev_cgroup)
 {
 	struct dev_exception_item *ex, *tmp;
 
-	list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) {
+	list_for_each_entry_safe(ex, tmp, active_exceptions(dev_cgroup), list) {
 		list_del_rcu(&ex->list);
 		kfree_rcu(ex, rcu);
 	}
@@ -182,7 +193,7 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup)
 
 static inline bool is_devcg_online(const struct dev_cgroup *devcg)
 {
-	return (devcg->behavior != DEVCG_DEFAULT_NONE);
+	return (active_behavior(devcg) != DEVCG_DEFAULT_NONE);
 }
 
 /**
@@ -200,12 +211,12 @@ static int devcgroup_online(struct cgroup_subsys_state *css)
 	mutex_lock(&devcgroup_mutex);
 
 	if (parent_dev_cgroup == NULL)
-		dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW;
+		active_behavior(dev_cgroup) = DEVCG_DEFAULT_ALLOW;
 	else {
-		ret = dev_exceptions_copy(&dev_cgroup->exceptions,
-					  &parent_dev_cgroup->exceptions);
+		ret = dev_exceptions_copy(active_exceptions(dev_cgroup),
+					  active_exceptions(parent_dev_cgroup));
 		if (!ret)
-			dev_cgroup->behavior = parent_dev_cgroup->behavior;
+			active_behavior(dev_cgroup) = active_behavior(parent_dev_cgroup);
 	}
 	mutex_unlock(&devcgroup_mutex);
 
@@ -217,7 +228,7 @@ static void devcgroup_offline(struct cgroup_subsys_state *css)
 	struct dev_cgroup *dev_cgroup = css_to_devcgroup(css);
 
 	mutex_lock(&devcgroup_mutex);
-	dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
+	active_behavior(dev_cgroup) = DEVCG_DEFAULT_NONE;
 	mutex_unlock(&devcgroup_mutex);
 }
 
@@ -232,8 +243,8 @@ devcgroup_css_alloc(struct cgroup_subsys_state *parent_css)
 	dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL);
 	if (!dev_cgroup)
 		return ERR_PTR(-ENOMEM);
-	INIT_LIST_HEAD(&dev_cgroup->exceptions);
-	dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
+	INIT_LIST_HEAD(active_exceptions(dev_cgroup));
+	active_behavior(dev_cgroup) = DEVCG_DEFAULT_NONE;
 
 	return &dev_cgroup->css;
 }
@@ -298,14 +309,15 @@ static int devcgroup_seq_read(struct cgroup_subsys_state *css,
 	 * - List the exceptions in case the default policy is to deny
 	 * This way, the file remains as a "whitelist of devices"
 	 */
-	if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) {
+	if (active_behavior(devcgroup) == DEVCG_DEFAULT_ALLOW) {
 		set_access(acc, ACC_MASK);
 		set_majmin(maj, ~0);
 		set_majmin(min, ~0);
 		seq_printf(m, "%c %s:%s %s\n", type_to_char(DEV_ALL),
 			   maj, min, acc);
 	} else {
-		list_for_each_entry_rcu(ex, &devcgroup->exceptions, list) {
+		list_for_each_entry_rcu(ex, active_exceptions(devcgroup),
+					list) {
 			set_access(acc, ex->access);
 			set_majmin(maj, ex->major);
 			set_majmin(min, ex->minor);
@@ -339,7 +351,7 @@ static bool may_access(struct dev_cgroup *dev_cgroup,
 			   lockdep_is_held(&devcgroup_mutex),
 			   "device_cgroup::may_access() called without proper synchronization");
 
-	list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
+	list_for_each_entry_rcu(ex, active_exceptions(dev_cgroup), list) {
 		if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
 			continue;
 		if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR))
@@ -354,7 +366,7 @@ static bool may_access(struct dev_cgroup *dev_cgroup,
 		break;
 	}
 
-	if (dev_cgroup->behavior == DEVCG_DEFAULT_ALLOW) {
+	if (active_behavior(dev_cgroup) == DEVCG_DEFAULT_ALLOW) {
 		if (behavior == DEVCG_DEFAULT_ALLOW) {
 			/* the exception will deny access to certain devices */
 			return true;
@@ -391,7 +403,7 @@ static int parent_has_perm(struct dev_cgroup *childcg,
 
 	if (!parent)
 		return 1;
-	return may_access(parent, ex, childcg->behavior);
+	return may_access(parent, ex, active_behavior(childcg));
 }
 
 /**
@@ -404,7 +416,7 @@ static inline int may_allow_all(struct dev_cgroup *parent)
 {
 	if (!parent)
 		return 1;
-	return parent->behavior == DEVCG_DEFAULT_ALLOW;
+	return active_behavior(parent) == DEVCG_DEFAULT_ALLOW;
 }
 
 /**
@@ -425,7 +437,7 @@ static void revalidate_active_exceptions(struct dev_cgroup *devcg)
 	struct dev_exception_item *ex;
 	struct list_head *this, *tmp;
 
-	list_for_each_safe(this, tmp, &devcg->exceptions) {
+	list_for_each_safe(this, tmp, active_exceptions(devcg)) {
 		ex = container_of(this, struct dev_exception_item, list);
 		if (!parent_has_perm(devcg, ex))
 			dev_exception_rm(devcg, ex);
@@ -465,8 +477,8 @@ static int propagate_exception(struct dev_cgroup *devcg_root,
 		 * in case both root's behavior and devcg is allow, a new
 		 * restriction means adding to the exception list
 		 */
-		if (devcg_root->behavior == DEVCG_DEFAULT_ALLOW &&
-		    devcg->behavior == DEVCG_DEFAULT_ALLOW) {
+		if (active_behavior(devcg_root) == DEVCG_DEFAULT_ALLOW &&
+		    active_behavior(devcg) == DEVCG_DEFAULT_ALLOW) {
 			rc = dev_exception_add(devcg, ex);
 			if (rc)
 				break;
@@ -533,12 +545,12 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
 			if (!may_allow_all(parent))
 				return -EPERM;
 			dev_exception_clean(devcgroup);
-			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+			active_behavior(devcgroup) = DEVCG_DEFAULT_ALLOW;
 			if (!parent)
 				break;
 
-			rc = dev_exceptions_copy(&devcgroup->exceptions,
-						 &parent->exceptions);
+			rc = dev_exceptions_copy(active_exceptions(devcgroup),
+						 active_exceptions(parent));
 			if (rc)
 				return rc;
 			break;
@@ -547,7 +559,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
 				return -EINVAL;
 
 			dev_exception_clean(devcgroup);
-			devcgroup->behavior = DEVCG_DEFAULT_DENY;
+			active_behavior(devcgroup) = DEVCG_DEFAULT_DENY;
 			break;
 		default:
 			return -EINVAL;
@@ -636,7 +648,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
 		 * an matching exception instead. And be silent about it: we
 		 * don't want to break compatibility
 		 */
-		if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) {
+		if (active_behavior(devcgroup) == DEVCG_DEFAULT_ALLOW) {
 			dev_exception_rm(devcgroup, &ex);
 			return 0;
 		}
@@ -648,7 +660,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
 		 * an matching exception instead. And be silent about it: we
 		 * don't want to break compatibility
 		 */
-		if (devcgroup->behavior == DEVCG_DEFAULT_DENY)
+		if (active_behavior(devcgroup) == DEVCG_DEFAULT_DENY)
 			dev_exception_rm(devcgroup, &ex);
 		else
 			rc = dev_exception_add(devcgroup, &ex);
@@ -731,7 +743,7 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
 
 	rcu_read_lock();
 	dev_cgroup = task_devcgroup(current);
-	rc = may_access(dev_cgroup, &ex, dev_cgroup->behavior);
+	rc = may_access(dev_cgroup, &ex, active_behavior(dev_cgroup));
 	rcu_read_unlock();
 
 	if (!rc)
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe cgroups" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [Monitors]

  Powered by Linux