Fix selinux_state_create() to consume the provided parent state reference rather than incrementing its refcount. Fix sel_write_unshare() to put any previously set parent_cred prior to setting the new one. With these two fixes, nested SELinux namespaces are properly freed when all references are dropped. Signed-off-by: Stephen Smalley <stephen.smalley.work@xxxxxxxxx> --- security/selinux/hooks.c | 3 ++- security/selinux/selinuxfs.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3bf4428ccfca..3c4ea7ed3750 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7606,7 +7606,8 @@ int selinux_state_create(struct selinux_state *parent, goto err; if (parent) { - newstate->parent = get_selinux_state(parent); + /* Consumes parent reference */ + newstate->parent = parent; newstate->depth = parent->depth + 1; } diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 7a0947dece69..0395ab187fd9 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -386,6 +386,8 @@ static ssize_t sel_write_unshare(struct file *file, const char __user *buf, tsec->osid = tsec->sid = SECINITSID_KERNEL; tsec->exec_sid = tsec->create_sid = tsec->keycreate_sid = tsec->sockcreate_sid = SECSID_NULL; + if (tsec->parent_cred) + put_cred(tsec->parent_cred); tsec->parent_cred = get_current_cred(); commit_creds(cred); } -- 2.47.1