Kernel IPC Mastery

Master the kernel mechanisms behind every Unix IPC channel. From the tmpfs namespace that holds your sockets, to the AF_UNIX transport that carries your data, to the credential system that proves your identity — IPC is where userspace meets the kernel.

The Unix IPC Philosophy

Unix is basically a simple operating system, but you have to be a genius to understand the simplicity.
— Dennis Ritchie

Everything is a file descriptor. Sockets, pipes, devices, regular files — the kernel presents them all through the same read()/write()/close() interface. IPC mechanisms are just different ways of connecting two file descriptors across process boundaries.

Why IPC Matters

Mechanism Kernel Source What Uses It

tmpfs

mm/shmem.c

Runtime namespace for sockets (/run/user/$UID/)

AF_UNIX sockets

net/unix/af_unix.c

Wayland, D-Bus, PipeWire, systemd, containerd

SCM_RIGHTS

net/core/scm.c

Zero-copy fd passing (Wayland clipboard, GPU buffers, DMA-BUF)

SO_PEERCRED

net/core/sock.c

Kernel-enforced identity (D-Bus policy, systemd activation)

Environment discovery

fork()/execve() in kernel/fork.c

How processes find each other’s IPC endpoints

This curriculum was born from debugging a real bug: gopass show -c failed inside tmux because XDG_RUNTIME_DIR was missing from tmux’s update-environment. See CR-2026-04-05 for the incident.

Curriculum

Module Description Level

tmpfs & XDG_RUNTIME_DIR

The ephemeral per-user filesystem — mm/shmem.c, mount options, VFS permission model, socket inode creation

Core

AF_UNIX Sockets & SCM_RIGHTS

The IPC transport — SOCK_STREAM vs SOCK_DGRAM vs SOCK_SEQPACKET, file descriptor passing, zero-copy architecture

Core

Credential Passing (SO_PEERCRED)

Kernel-enforced identity — SO_PEERCRED vs SCM_CREDENTIALS, task_struct, struct cred, D-Bus security model

Intermediate

Environment Variable Discovery

The kernel-userspace bridge — fork()/execve() propagation, tmux environment filtering, the live workaround pattern

Intermediate

Future modules (add as you learn):

Module Description Level

Pipes & FIFOs

pipe(), mkfifo(), splice(), shell pipelines at the kernel level

Core

Shared Memory

shmget()/shmat(), mmap() with MAP_SHARED, memfd_create()

Intermediate

Message Queues

POSIX vs SysV, mq_open(), priority-based delivery

Intermediate

Netlink Sockets

Kernel-to-userspace messaging — AF_NETLINK, rtnetlink, genetlink

Advanced

eventfd / signalfd / timerfd

Modern fd-based IPC primitives, epoll integration

Advanced

The Mastery Path

Level 1: Awareness (Week 1)

  • Explain what /run/user/$UID/ is and why it exists

  • List the sockets in your runtime directory and identify each service

  • Describe the difference between AF_UNIX and AF_INET sockets

  • Know what SO_PEERCRED returns and why it matters

Level 2: Comprehension (Week 2-3)

  • Trace wl-copy with strace and explain each syscall

  • Explain how SCM_RIGHTS enables zero-copy clipboard transfer

  • Describe how tmux’s update-environment breaks the IPC chain

  • Read the kernel source for unix_stream_connect() on Elixir

Level 3: Application (Month 2)

  • Write a minimal AF_UNIX client/server in C

  • Implement fd passing with SCM_RIGHTS between two processes

  • Debug an IPC failure by reading strace output alone

  • Explain the security implications of SO_PEERCRED vs SCM_CREDENTIALS

Level 4: Mastery (Month 3+)

  • Trace an IPC path from userspace through to kernel source

  • Understand how IPC mechanisms compose (tmpfs + sockets + credentials)

  • Read and review kernel patches to net/unix/af_unix.c

  • Contribute documentation or tests to kernel IPC subsystems

Quick Reference

Key Syscalls

// Create a Unix domain socket
int fd = socket(AF_UNIX, SOCK_STREAM, 0);

// Bind to a path
struct sockaddr_un addr = { .sun_family = AF_UNIX };
strncpy(addr.sun_path, "/run/user/1000/my-socket", sizeof(addr.sun_path)-1);
bind(fd, (struct sockaddr*)&addr, sizeof(addr));

// Get peer credentials after accept()
struct ucred cred;
socklen_t len = sizeof(cred);
getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &cred, &len);
printf("uid=%d pid=%d\n", cred.uid, cred.pid);

strace Patterns

# Trace socket operations
strace -e socket,bind,connect,listen,accept wl-copy <<< "test"

# Trace fd passing
strace -e sendmsg,recvmsg -v wl-copy <<< "test"

# Trace credential queries
strace -e getsockopt dbus-send --session --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetId

# Trace environment inheritance
strace -f -e execve bash -c 'printenv XDG_RUNTIME_DIR'

Kernel Source Browser

All source references use Bootlin Elixir: elixir.bootlin.com/linux/latest/source

Key entry points:

  • net/unix/af_unix.c — AF_UNIX socket implementation

  • net/core/scm.c — Ancillary data (fd passing, credentials)

  • mm/shmem.c — tmpfs filesystem

  • include/linux/sched.h — task_struct definition

  • kernel/fork.c — fork() implementation (environment inheritance)

The Practice Method

Explore Your System

# 1. Map your IPC landscape
ls -la /run/user/$(id -u)/
ss -xlp | head -20

# 2. Trace a real clipboard operation
strace -e connect,sendmsg wl-copy <<< "test"

# 3. Read your own process credentials
cat /proc/self/status | awk '/^(Pid|Uid|Gid|Cap)/'

# 4. Compare environments across tmux boundary
printenv | sort > /tmp/env-outer.txt
# (in a tmux pane)
printenv | sort > /tmp/env-inner.txt
diff /tmp/env-outer.txt /tmp/env-inner.txt

Build Something

Write a minimal AF_UNIX echo server in C:

  1. Create a socket, bind to /tmp/my-ipc-test, listen

  2. Accept connections, read data, echo it back

  3. Print SO_PEERCRED for each connection

  4. Bonus: implement SCM_RIGHTS to pass an open file between client and server

This exercise touches every kernel subsystem covered in this curriculum.