As a precursor to namespacing IMA a way of uniquely identifying the namespace to appear in the IMA log is needed. This log may be transported away from the running system and may be analyzed even after the system has been rebooted. Thus we need a way of identifying namespaces in the log which is unique. UUID, being designed probabilistically never to repeat, fits this bill so add it to the user_namespace which we'll also use for namespacing IMA. uuid_gen() is used to create each uuid uniquely. It feeds off the pseudo random number generator, but this should be as unique as we need for probabilistic non repeats without depleting the entropy pool. Since there is no random initializer for a uuid, this is done in user_namespaces_init(). This should be safe because IMA is a late initcall. This patch contains no exposure mechanisms, and the subsequent patches only add uuid entries in the IMA log. However, it is not unlikely that eventually orchestration systems will want to know what the uuid is (to tie their container ID to the one in the IMA log), so additional patches exposing this via NSIO and /proc/<pid>/ns could be added. For checkpoint/restore, the uuid should not be a property that transports because otherwise we'll have to have a set mechanism with a uniqueness check. Signed-off-by: James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx> --- include/linux/user_namespace.h | 2 ++ kernel/user.c | 1 + kernel/user_namespace.c | 3 +++ 3 files changed, 6 insertions(+) diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index 33a4240e6a6f..d155788abdc1 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -10,6 +10,7 @@ #include <linux/rwsem.h> #include <linux/sysctl.h> #include <linux/err.h> +#include <linux/uuid.h> #define UID_GID_MAP_MAX_BASE_EXTENTS 5 #define UID_GID_MAP_MAX_EXTENTS 340 @@ -99,6 +100,7 @@ struct user_namespace { #endif struct ucounts *ucounts; long ucount_max[UCOUNT_COUNTS]; + uuid_t uuid; } __randomize_layout; struct ucounts { diff --git a/kernel/user.c b/kernel/user.c index e2cf8c22b539..bf9ae1d0b670 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -67,6 +67,7 @@ struct user_namespace init_user_ns = { .keyring_name_list = LIST_HEAD_INIT(init_user_ns.keyring_name_list), .keyring_sem = __RWSEM_INITIALIZER(init_user_ns.keyring_sem), #endif + /* .uuid is initialized in user_namespaces_init() */ }; EXPORT_SYMBOL_GPL(init_user_ns); diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 6b2e3ca7ee99..8ce57c16ddd3 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -141,6 +141,8 @@ int create_user_ns(struct cred *new) if (!setup_userns_sysctls(ns)) goto fail_keyring; + uuid_gen(&ns->uuid); + set_cred_user_ns(new, ns); return 0; fail_keyring: @@ -1386,6 +1388,7 @@ const struct proc_ns_operations userns_operations = { static __init int user_namespaces_init(void) { user_ns_cachep = KMEM_CACHE(user_namespace, SLAB_PANIC | SLAB_ACCOUNT); + uuid_gen(&init_user_ns.uuid); return 0; } subsys_initcall(user_namespaces_init); -- 2.33.0