@@ -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-
349325static 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+
447454void 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