[RFC 18/20] userns: Introduce a refcount variable for calling early teardown function

Stefan Berger
2021-11-30T16:08:46Z

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@linux.ibm.com>
---
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