[7/8] net_ns: Set net_ns for child, if it has no permissions to do that

Submitted by Kirill Tkhai on June 28, 2017, 11:50 a.m.

Details

Message ID 149865063603.12218.18095870821093139619.stgit@localhost.localdomain
State New
Series "One-level leaked net_ns support"
Headers show

Commit Message

Kirill Tkhai June 28, 2017, 11:50 a.m.
Child may be created via clone with CLONE_NEWUSER,
and it may do not have permissions to enter its
net namespace, which is inherited from parent.
So, parent must set it for child like it happens
in real life.

Currently one-level inheritance is supported.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/cr-restore.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 7bf10312e..36687bf78 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -476,7 +476,7 @@  static int restore_task_pfc_before_user_ns(void)
 
 static int setup_child_task_namespaces(struct pstree_item *item, struct ns_id **ret_pid_ns)
 {
-	struct ns_id *pid_ns;
+	struct ns_id *pid_ns, *net_ns;
 
 	pid_ns = lookup_ns_by_id(item->ids->pid_ns_id, &pid_ns_desc);
 	BUG_ON(!pid_ns);
@@ -487,6 +487,16 @@  static int setup_child_task_namespaces(struct pstree_item *item, struct ns_id **
 			item->user_ns = pid_ns->user_ns;
 		else
 			item->user_ns = current->user_ns;
+
+		if (item->ids->net_ns_id != current->net_ns->id) {
+			/* Check, that child can set its net_ns */
+			net_ns = lookup_ns_by_id(item->ids->net_ns_id, &net_ns_desc);
+			if (!is_subns(net_ns->user_ns, item->user_ns) &&
+			    set_netns(net_ns) < 0) {
+				pr_err("Can't set net_ns\n");
+				return -1;
+			}
+		}
 		item->net_ns = current->net_ns;
 	} else {
 		item->user_ns = top_user_ns;