[CRIU] [PATCH v3 3/3] criu: unset loginuid value before creating userns

Dmitry Safonov dsafonov at odin.com
Tue Dec 8 07:11:57 PST 2015


The value of loginuid cannot be changed inside container, with the
exception if it was not set yet. This value is inherited on fork() from
parent.

So, to restore original loginuid values for all tasks:
  - unset the container parent loginuid
  - all children will have this value unsetted
  - on child restore set value from dump

See http://lxr.free-electrons.com/source/kernel/audit.c#L635
https://jira.sw.ru/browse/PSBM-41993

Signed-off-by: Dmitry Safonov <dsafonov at odin.com>
---
 cr-restore.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/cr-restore.c b/cr-restore.c
index b3d7019..51af83d 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1827,6 +1827,38 @@ static void ignore_kids(void)
 		pr_perror("Restoring CHLD sigaction failed");
 }
 
+static unsigned int saved_loginuid;
+
+static int prepare_userns_hook(void)
+{
+	pid_t pid = getpid();
+	int ret;
+
+	/*
+	 * Save old loginuid and set it to 4294967295:
+	 * this value means that loginuid is unset and it will be inherited.
+	 * After you set some value to /proc/<>/loginuid it can't be changed
+	 * inside container due to permissions.
+	 * But you still can set this value if it was unset (4294967295/-1).
+	 */
+	saved_loginuid = parse_pid_loginuid(pid, &ret);
+	if (ret < 0)
+		return -1;
+
+	if (prepare_pid_loginuid(pid, 4294967295) < 0) {
+		pr_err("Setting loginuid for CT init task failed, CAP_AUDIT_CONTROL?");
+		return -1;
+	}
+	return 0;
+}
+
+static void restore_origin_ns_hook(void)
+{
+	/* not critical: it does not affect CT in any way */
+	if (prepare_pid_loginuid(getpid(), saved_loginuid) < 0)
+		pr_err("Restore original /proc/self/loginuid failed");
+}
+
 static int restore_root_task(struct pstree_item *init)
 {
 	enum trace_flags flag = TRACE_ALL;
@@ -1870,6 +1902,9 @@ static int restore_root_task(struct pstree_item *init)
 		return -1;
 	}
 
+	if (prepare_userns_hook())
+		return -1;
+
 	if (prepare_namespace_before_tasks())
 		return -1;
 
@@ -1880,6 +1915,8 @@ static int restore_root_task(struct pstree_item *init)
 	if (ret < 0)
 		goto out;
 
+	restore_origin_ns_hook();
+
 	if (root_as_sibling) {
 		struct sigaction act;
 		/*
-- 
2.6.3



More information about the CRIU mailing list