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

Commit 2651225b authored by Stephen Smalley's avatar Stephen Smalley Committed by James Morris
Browse files

selinux: wrap cgroup seclabel support with its own policy capability



commit 1ea0ce40 ("selinux: allow
changing labels for cgroupfs") broke the Android init program,
which looks up security contexts whenever creating directories
and attempts to assign them via setfscreatecon().
When creating subdirectories in cgroup mounts, this would previously
be ignored since cgroup did not support userspace setting of security
contexts.  However, after the commit, SELinux would attempt to honor
the requested context on cgroup directories and fail due to permission
denial.  Avoid breaking existing userspace/policy by wrapping this change
with a conditional on a new cgroup_seclabel policy capability.  This
preserves existing behavior until/unless a new policy explicitly enables
this capability.

Reported-by: default avatarJohn Stultz <john.stultz@linaro.org>
Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
Signed-off-by: default avatarJames Morris <james.l.morris@oracle.com>
parent 0837e49a
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -480,12 +480,13 @@ static int selinux_is_sblabel_mnt(struct super_block *sb)
		sbsec->behavior == SECURITY_FS_USE_NATIVE ||
		/* Special handling. Genfs but also in-core setxattr handler */
		!strcmp(sb->s_type->name, "sysfs") ||
		!strcmp(sb->s_type->name, "cgroup") ||
		!strcmp(sb->s_type->name, "cgroup2") ||
		!strcmp(sb->s_type->name, "pstore") ||
		!strcmp(sb->s_type->name, "debugfs") ||
		!strcmp(sb->s_type->name, "tracefs") ||
		!strcmp(sb->s_type->name, "rootfs");
		!strcmp(sb->s_type->name, "rootfs") ||
		(selinux_policycap_cgroupseclabel &&
		 (!strcmp(sb->s_type->name, "cgroup") ||
		  !strcmp(sb->s_type->name, "cgroup2")));
}

static int sb_finish_set_opts(struct super_block *sb)
+2 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ enum {
	POLICYDB_CAPABILITY_OPENPERM,
	POLICYDB_CAPABILITY_EXTSOCKCLASS,
	POLICYDB_CAPABILITY_ALWAYSNETWORK,
	POLICYDB_CAPABILITY_CGROUPSECLABEL,
	__POLICYDB_CAPABILITY_MAX
};
#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
@@ -79,6 +80,7 @@ extern int selinux_policycap_netpeer;
extern int selinux_policycap_openperm;
extern int selinux_policycap_extsockclass;
extern int selinux_policycap_alwaysnetwork;
extern int selinux_policycap_cgroupseclabel;

/*
 * type_datum properties
+2 −1
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@ static char *policycap_names[] = {
	"network_peer_controls",
	"open_perms",
	"extended_socket_class",
	"always_check_network"
	"always_check_network",
	"cgroup_seclabel"
};

unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
+4 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ int selinux_policycap_netpeer;
int selinux_policycap_openperm;
int selinux_policycap_extsockclass;
int selinux_policycap_alwaysnetwork;
int selinux_policycap_cgroupseclabel;

static DEFINE_RWLOCK(policy_rwlock);

@@ -1993,6 +1994,9 @@ static void security_load_policycaps(void)
					  POLICYDB_CAPABILITY_EXTSOCKCLASS);
	selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
						  POLICYDB_CAPABILITY_ALWAYSNETWORK);
	selinux_policycap_cgroupseclabel =
		ebitmap_get_bit(&policydb.policycaps,
				POLICYDB_CAPABILITY_CGROUPSECLABEL);
}

static int security_preserve_bools(struct policydb *p);