Commit aa9f1df0 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Pavel Emelyanov

criu: unset loginuid value before creating userns

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-41993Signed-off-by: 's avatarDmitry Safonov <dsafonov@odin.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 594b4e3a
...@@ -1827,6 +1827,38 @@ static void ignore_kids(void) ...@@ -1827,6 +1827,38 @@ static void ignore_kids(void)
pr_perror("Restoring CHLD sigaction failed"); 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 INVALID_UID:
* 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.
*/
saved_loginuid = parse_pid_loginuid(pid, &ret);
if (ret < 0)
return -1;
if (prepare_pid_loginuid(pid, INVALID_UID) < 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) static int restore_root_task(struct pstree_item *init)
{ {
enum trace_flags flag = TRACE_ALL; enum trace_flags flag = TRACE_ALL;
...@@ -1870,6 +1902,9 @@ static int restore_root_task(struct pstree_item *init) ...@@ -1870,6 +1902,9 @@ static int restore_root_task(struct pstree_item *init)
return -1; return -1;
} }
if (prepare_userns_hook())
return -1;
if (prepare_namespace_before_tasks()) if (prepare_namespace_before_tasks())
return -1; return -1;
...@@ -1880,6 +1915,8 @@ static int restore_root_task(struct pstree_item *init) ...@@ -1880,6 +1915,8 @@ static int restore_root_task(struct pstree_item *init)
if (ret < 0) if (ret < 0)
goto out; goto out;
restore_origin_ns_hook();
if (root_as_sibling) { if (root_as_sibling) {
struct sigaction act; struct sigaction act;
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment