Skip to content
Lesson 6 of 19

Step 1 of 5 · Reading · ~3 min

Read

Linux Namespaces

IPC Namespace

The sixth lie is the quietest: who else is in the room. Two processes that have never heard of each other can still share memory, provided they agree on a number. That is System V IPC, it predates Unix networking, and it has no permissions model worth the name — which is precisely why containers need it namespaced.

Two families, one namespace

CLONE_NEWIPC isolates exactly two things:

  • System V IPCshmget, msgget, semget. Key-based: you pass an integer key, you get back an identifier.
  • POSIX message queues, the /dev/mqueue tree.

And it isolates nothing else. Pipes, UNIX domain sockets, signals and eventfd are not in this namespace — sockets are files, so the mount namespace hides them; signals are addressed by pid, so the PID namespace does. Knowing which mechanism is isolated by which namespace is the difference between a working sidecar and a leak you cannot explain.

Why a key space is a security problem

A SysV key is a small integer that any process may guess, and the lookup was historically global:

          (no IPC namespace)
container A: shmget(0xDEAD, 4096, IPC_CREAT)   -> id 32768
container B: shmget(0xDEAD, 0, 0)              -> id 32768   (!)
container B: shmat(32768)                      -> reads A's memory

With CLONE_NEWIPC, B's shmget finds nothing under that key: it either returns ENOENT or creates a brand-new segment that has nothing to do with A's. The key was never a secret; the namespace is what makes guessing it useless.

One detail that looks like an inconsistency and is not: ids come from one global allocator, keys are per namespace. Two namespaces can each own key K, and those two segments get different ids — but an id from another namespace is not resolvable in yours, so global uniqueness costs nothing and makes the kernel's own bookkeeping simpler.

Why the exercise is a simulator

unshare(CLONE_NEWIPC) needs CAP_SYS_ADMIN, which the sandbox running your submission does not have. What is left when you remove the syscall wrapper is the part that carries all the meaning: a key table per namespace, one id allocator for the machine, and a FIFO behind each queue.

Your exercise: IPC Namespace Isolation

The kernel doesYour simulator does
shmget(key, size, IPC_CREAT) — new segment, or EEXIST if the key is taken in this namespaceSHMGET <ns> <key> <size>OK <id> or EEXIST
ipcs -m — segments of the caller's namespaceSHMLIST <ns>, sorted by id
msgget / msgsnd / msgrcv — a queue is a FIFO, and an empty one has nothing to hand backMSGGET, MSGSEND, MSGRECV (EMPTY when drained)
a lookup crossing a namespace boundary simply finds nothingPEEK <ns_a> <ns_b> <key>1 only when the two namespaces are the same

PEEK is the exercise's whole thesis in one command: it can never print 1 across two namespaces, because there is no code path in your program — as there is none in the kernel — that reaches another namespace's key table. Isolation is not a check you perform; it is a table you never consult.

Reference: man 7 ipc_namespaces.

Up nextveth + Bridge + NATLinux Namespaces

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…