Commit e19dfdc8 authored by Ondrej Mosnacek's avatar Ondrej Mosnacek Committed by Paul Moore
Browse files

kernfs: initialize security of newly created nodes

Use the new security_kernfs_init_security() hook to allow LSMs to
possibly assign a non-default security context to a newly created kernfs
node based on the attributes of the new node and also its parent node.

This fixes an issue with cgroupfs under SELinux, where newly created
cgroup subdirectories/files would not inherit its parent's context if
it had been set explicitly to a non-default value (other than the genfs
context specified by the policy). This can be reproduced as follows (on
Fedora/RHEL):

    # mkdir /sys/fs/cgroup/unified/test
    # # Need permissive to change the label under Fedora policy:
    # setenforce 0
    # chcon -t container_file_t /sys/fs/cgroup/unified/test
    # ls -lZ /sys/fs/cgroup/unified
    total 0
    -r--r--r--.  1 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 cgroup.controllers
    -rw-r--r--.  1 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 cgroup.max.depth
    -rw-r--r--.  1 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 cgroup.max.descendants
    -rw-r--r--.  1 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 cgroup.procs
    -r--r--r--.  1 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 cgroup.stat
    -rw-r--r--.  1 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 cgroup.subtree_control
    -rw-r--r--.  1 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 cgroup.threads
    drwxr-xr-x.  2 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 init.scope
    drwxr-xr-x. 26 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:21 system.slice
    drwxr-xr-x.  3 root root system_u:object_r:container_file_t:s0 0 Jan 29 03:15 test
    drwxr-xr-x.  3 root root system_u:object_r:cgroup_t:s0         0 Jan 29 03:06 user.slice
    # mkdir /sys/fs/cgroup/unified/test/subdir

Actual result:

    # ls -ldZ /sys/fs/cgroup/unified/test/subdir
    drwxr-xr-x. 2 root root system_u:object_r:cgroup_t:s0 0 Jan 29 03:15 /sys/fs/cgroup/unified/test/subdir

Expected result:

    # ls -ldZ /sys/fs/cgroup/unified/test/subdir
    drwxr-xr-x. 2 root root unconfined_u:object_r:container_file_t:s0 0 Jan 29 03:15 /sys/fs/cgroup/unified/test/subdir

Link: https://github.com/SELinuxProject/selinux-kernel/issues/39



Signed-off-by: default avatarOndrej Mosnacek <omosnace@redhat.com>
Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent ec882da5
Loading
Loading
Loading
Loading
+9 −2
Original line number Original line Diff line number Diff line
@@ -615,6 +615,7 @@ struct kernfs_node *kernfs_node_from_dentry(struct dentry *dentry)
}
}


static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
					     struct kernfs_node *parent,
					     const char *name, umode_t mode,
					     const char *name, umode_t mode,
					     kuid_t uid, kgid_t gid,
					     kuid_t uid, kgid_t gid,
					     unsigned flags)
					     unsigned flags)
@@ -671,6 +672,12 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
			goto err_out3;
			goto err_out3;
	}
	}


	if (parent) {
		ret = security_kernfs_init_security(parent, kn);
		if (ret)
			goto err_out3;
	}

	return kn;
	return kn;


 err_out3:
 err_out3:
@@ -689,7 +696,7 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
{
{
	struct kernfs_node *kn;
	struct kernfs_node *kn;


	kn = __kernfs_new_node(kernfs_root(parent),
	kn = __kernfs_new_node(kernfs_root(parent), parent,
			       name, mode, uid, gid, flags);
			       name, mode, uid, gid, flags);
	if (kn) {
	if (kn) {
		kernfs_get(parent);
		kernfs_get(parent);
@@ -958,7 +965,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
	INIT_LIST_HEAD(&root->supers);
	INIT_LIST_HEAD(&root->supers);
	root->next_generation = 1;
	root->next_generation = 1;


	kn = __kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO,
	kn = __kernfs_new_node(root, NULL, "", S_IFDIR | S_IRUGO | S_IXUGO,
			       GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
			       GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
			       KERNFS_DIR);
			       KERNFS_DIR);
	if (!kn) {
	if (!kn) {