Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

setns(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)x64 308 / i386 346 / arm64-generic 268 / arm32 375
Since (kernel)3.0 (man VERSIONS; hub 3.0)
Man pageman2/setns.2 (cached, 2021-08-27)
glibc wrapperYes; <sched.h>, needs _GNU_SOURCE
Aliases coverednone
Ledger IDSC-setns

Purpose

setns() moves the calling thread into an existing namespace. The classic form takes a file descriptor referring to a /proc/[pid]/ns/ symlink (or a bind mount of one) and reassociates one namespace membership; since 5.8 the fd may instead be a pidfd, in which case the caller joins several of the target thread’s namespaces atomically. It is the join-side complement of unshare.md and the mechanism nsenter(1) is built on.

Synopsis

#define _GNU_SOURCE
#include <sched.h>
int setns(int fd, int nstype);

Arguments and behavior

With an /proc/[pid]/ns/ fd, nstype is 0 (any type) or one of the CLONE_NEW* constants, used to verify the fd’s namespace type (table below). A nonzero nstype matters when the fd was passed from another process and its type is unknown. With a pidfd (5.8), nstype is instead an OR of the constants naming which of the target’s namespaces to join (for example CLONE_NEWUSER, CLONE_NEWNET, CLONE_NEWUTS); 0 is invalid here. Type-specific capability rules are folded into the table; extra user-namespace rules: joining grants a full capability set in the target, a multithreaded process cannot change user namespace, rejoining the current one is forbidden, and CLONE_FS sharing blocks the join.

Return value and errors

Returns 0 on success, -1 on error: EBADF, EINVAL (type mismatch between fd and nstype; joining an ancestor PID namespace; rejoining the current user namespace; multithreaded or CLONE_FS-sharing caller; invalid pidfd nstype), ENOMEM, EPERM (missing capability), ESRCH (pidfd target already reaped).

Flags and constants

“both-userns” below means CAP_SYS_ADMIN in the caller’s own user namespace and in the user namespace owning the target (man setns.2):

ConstantNamespacesetns use sinceRules
CLONE_NEWIPCSysV IPC / POSIX message queues3.0both-userns
CLONE_NEWNETNetwork devices, stacks, ports3.0both-userns
CLONE_NEWNSMount namespace3.8both-userns plus CAP_SYS_CHROOT; CLONE_FS sharing forbidden
CLONE_NEWPIDPID numbering3.8both-userns; descendants only; moves only future children
CLONE_NEWUSERUser/UID mappings3.8CAP_SYS_ADMIN in target (descendants only); grants full caps there
CLONE_NEWUTSHostname, NIS domain3.0both-userns
CLONE_NEWCGROUPcgroup membership view4.6both-userns; cgroup memberships unchanged
CLONE_NEWTIMECLOCK_MONOTONIC/BOOTTIME offsets5.8both-userns

Security and notes

Namespace fd usage and NS_GET_* ioctls are described in namespace.h-adjacent man pages not cached here; the capability rules above are quoted from the cached page. Unlike fork-time namespace creation via clone flags (unshare.md, clone.md), setns moves only the calling thread, so a multithreaded process can join everything except a user namespace. Container runtimes combine setns with pivot_root.md to build a fresh root.

References

  • Cached man page: source-cache/man-pages-sparse/man2/setns.2
  • Online: https://man7.org/linux/man-pages/man2/setns.2.html
  • Kernel tables: source-cache/kernel/syscall_64.tbl (308)
  • Constants: /usr/include/linux/sched.h (CLONE_NEW*), <bits/sched.h>