Skip to content

Commit a97d7cb

Browse files
committed
nsenter: refuse to join unknown namespaces
This is basically a no-op change because runc already disallows this, but it will be needed in future patches when we have to track what namespaces have already been joined. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 49bee5c commit a97d7cb

File tree

1 file changed

+35
-28
lines changed

1 file changed

+35
-28
lines changed

libcontainer/nsenter/nsexec.c

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -322,30 +322,6 @@ static int clone_parent(jmp_buf *env, int jmpval)
322322
return clone(child_func, ca.stack_ptr, CLONE_PARENT | SIGCHLD, &ca);
323323
}
324324

325-
/* Returns the clone(2) flag for a namespace, given the name of a namespace. */
326-
static int nsflag(char *name)
327-
{
328-
if (!strcmp(name, "cgroup"))
329-
return CLONE_NEWCGROUP;
330-
else if (!strcmp(name, "ipc"))
331-
return CLONE_NEWIPC;
332-
else if (!strcmp(name, "mnt"))
333-
return CLONE_NEWNS;
334-
else if (!strcmp(name, "net"))
335-
return CLONE_NEWNET;
336-
else if (!strcmp(name, "pid"))
337-
return CLONE_NEWPID;
338-
else if (!strcmp(name, "user"))
339-
return CLONE_NEWUSER;
340-
else if (!strcmp(name, "uts"))
341-
return CLONE_NEWUTS;
342-
else if (!strcmp(name, "time"))
343-
return CLONE_NEWTIME;
344-
345-
/* If we don't recognise a name, fallback to 0. */
346-
return 0;
347-
}
348-
349325
static uint32_t readint32(char *buf)
350326
{
351327
return *(uint32_t *) buf;
@@ -444,6 +420,37 @@ void nl_free(struct nlconfig_t *config)
444420
free(config->data);
445421
}
446422

423+
static struct nstype_t {
424+
int type;
425+
char *name;
426+
} all_ns_types[] = {
427+
{ CLONE_NEWCGROUP, "cgroup" },
428+
{ CLONE_NEWIPC, "ipc" },
429+
{ CLONE_NEWNS, "mnt" },
430+
{ CLONE_NEWNET, "net" },
431+
{ CLONE_NEWPID, "pid" },
432+
{ CLONE_NEWTIME, "time" },
433+
{ CLONE_NEWUSER, "user" },
434+
{ CLONE_NEWUTS, "uts" },
435+
{ }, /* null terminator */
436+
};
437+
438+
/* Returns the clone(2) flag for a namespace, given the name of a namespace. */
439+
static int nstype(char *name)
440+
{
441+
for (struct nstype_t * ns = all_ns_types; ns->name != NULL; ns++)
442+
if (!strcmp(name, ns->name))
443+
return ns->type;
444+
/*
445+
* setns(2) lets us join namespaces without knowing the type, but
446+
* namespaces usually require special handling of some kind (so joining
447+
* a namespace without knowing its type or joining a new namespace type
448+
* without corresponding handling could result in broken behaviour) and
449+
* the rest of runc doesn't allow unknown namespace types anyway.
450+
*/
451+
bail("unknown namespace type %s", name);
452+
}
453+
447454
void join_namespaces(char *nslist)
448455
{
449456
int num = 0, i;
@@ -499,10 +506,10 @@ void join_namespaces(char *nslist)
499506

500507
for (i = 0; i < num; i++) {
501508
struct namespace_t *ns = &namespaces[i];
502-
int flag = nsflag(ns->type);
509+
int type = nstype(ns->type);
503510

504-
write_log(DEBUG, "setns(%#x) into %s namespace (with path %s)", flag, ns->type, ns->path);
505-
if (setns(ns->fd, flag) < 0)
511+
write_log(DEBUG, "setns(%#x) into %s namespace (with path %s)", type, ns->type, ns->path);
512+
if (setns(ns->fd, type) < 0)
506513
bail("failed to setns into %s namespace", ns->type);
507514

508515
/*
@@ -511,7 +518,7 @@ void join_namespaces(char *nslist)
511518
* of things can break if we aren't the right user. See
512519
* <https://github.com/opencontainers/runc/issues/4466> for one example.
513520
*/
514-
if (flag == CLONE_NEWUSER) {
521+
if (type == CLONE_NEWUSER) {
515522
if (setresuid(0, 0, 0) < 0)
516523
bail("failed to become root in user namespace");
517524
}

0 commit comments

Comments
 (0)