Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e096209 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull cgroup fixes from Tejun Heo:
 "This contains two fix patches for device_cgroup.  One fixes a
  regression introduced earlier in 3.7 cycle where device_cgroup could
  try to dereference the NULL parent of the root cgroup.  The other one
  is RCU usage fix."

* 'for-3.7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  device_cgroup: fix RCU usage
  device_cgroup: fix unchecked cgroup parent usage
parents 9924a199 201e72ac
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -164,8 +164,8 @@ 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_del(&ex->list);
		kfree(ex);
		list_del_rcu(&ex->list);
		kfree_rcu(ex, rcu);
	}
}

@@ -298,7 +298,7 @@ static int may_access(struct dev_cgroup *dev_cgroup,
	struct dev_exception_item *ex;
	bool match = false;

	list_for_each_entry(ex, &dev_cgroup->exceptions, list) {
	list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
		if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
			continue;
		if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR))
@@ -352,6 +352,8 @@ static int parent_has_perm(struct dev_cgroup *childcg,
 */
static inline int may_allow_all(struct dev_cgroup *parent)
{
	if (!parent)
		return 1;
	return parent->behavior == DEVCG_DEFAULT_ALLOW;
}

@@ -376,11 +378,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
	int count, rc;
	struct dev_exception_item ex;
	struct cgroup *p = devcgroup->css.cgroup;
	struct dev_cgroup *parent = cgroup_to_devcgroup(p->parent);
	struct dev_cgroup *parent = NULL;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (p->parent)
		parent = cgroup_to_devcgroup(p->parent);

	memset(&ex, 0, sizeof(ex));
	b = buffer;

@@ -391,11 +396,14 @@ 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;
			if (!parent)
				break;

			rc = dev_exceptions_copy(&devcgroup->exceptions,
						 &parent->exceptions);
			if (rc)
				return rc;
			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
			break;
		case DEVCG_DENY:
			dev_exception_clean(devcgroup);