Extend the user_namespace structure with a refcount_teardown variable to cause an early teardown function to be invoked. This allows the IMA namespace to initialize a filesystem that holds one additional reference to the user namespace it 'belongs' to. Therefore, the refount_teardown variable will be incremented by '1' once that additional reference has been created. Once the user namespace's reference counter is decremented to '1', this early teardown function is invoked and the additional user namespace reference released and the actual deletion of the user namespace can then proceed as usual. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> --- include/linux/user_namespace.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index 5249db04d62b..505e3b3748b6 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -103,6 +103,11 @@ struct user_namespace { #ifdef CONFIG_IMA struct ima_namespace *ima_ns; #endif + /* The refcount at which to start tearing down dependent namespaces + * (currently only IMA) that may hold additional references to the + * user namespace. + */ + unsigned int refcount_teardown; } __randomize_layout; struct ucounts { @@ -156,8 +161,12 @@ extern void __put_user_ns(struct user_namespace *ns); static inline void put_user_ns(struct user_namespace *ns) { - if (ns && refcount_dec_and_test(&ns->ns.count)) - __put_user_ns(ns); + if (ns) { + if (refcount_dec_and_test(&ns->ns.count)) + __put_user_ns(ns); + else if (refcount_read(&ns->ns.count) == ns->refcount_teardown) + ; + } } struct seq_operations; -- 2.31.1