Skip to content

Archive / page 16

All articles

Every practical article from the Nalar archive, newest first.

Cybersecurity 18 Sep 2026 4 min read

Memfd Seals Turn Mutable Anonymous Files into Explicit Handoff Objects

A process prepares a binary payload in memory, passes a file descriptor to another process, and expects the bytes to remain stable after validation. A plain descriptor does not create that guarantee. If some holder still has write authority, the object can change after a consumer has inspected it, and pathname permissions offer no useful boundary when the object has no ordinary filesystem name. Linux memfd_create() provides an anonymous file backed by memory-like filesystem storage, and file seals can constrain later changes to that file. The useful security property is not anonymity by itself. It is the ability to construct a mutable object, apply irreversible restrictions to that object, then hand out descriptors whose backing file can no longer be changed in the prohibited ways.

Cybersecurity 18 Sep 2026 6 min read

memfd File Seals Turn Shared Memory into a Kernel-Enforced Mutation Boundary

A broker can allocate a memory-backed object, populate it, and pass its file descriptor to another process over a UNIX domain socket. The receiver may treat the bytes as immutable configuration, compiled code, or a serialized artifact. That assumption is unsafe if the sender or another holder can still alter the same inode after validation. Linux memfd_create() and file seals provide a kernel-enforced way to narrow that mutation surface without assigning the object a persistent filesystem pathname.

Linux 18 Sep 2026 6 min read

membarrier Moves Memory-Ordering Cost to an Infrequent Coordination Path

A full hardware memory barrier in a frequently executed path can impose a cost on every operation, even when cross-thread coordination happens only occasionally. Linux membarrier() supports a different placement of that cost: a rare coordination path can request an ordering event across a defined set of threads while a frequent path may need only compiler-level ordering. This is not a general replacement for atomics, locks, or the memory model of a programming language. It is a Linux-specific synchronization primitive for designs whose correctness already has a precise pairing between a frequent path and an infrequent coordination path.

Software Engineering 18 Sep 2026 8 min read

MAP_SHARED mmap Couples Memory Writes to File-Backed Page State

A writable MAP_SHARED mapping lets a process modify file-backed state with ordinary memory stores. The bytes are addressed through virtual memory rather than passed to write(), but the mapping still participates in filesystem state: modifications can become visible through other shared mappings and file I/O, and dirty pages can later be written back to storage. That interface compresses several mechanisms into one address range. CPU stores, page faults, page-cache residency, filesystem writeback, and storage persistence can all participate in the lifetime of the same bytes. Treating a successful store as equivalent to durable file output collapses boundaries that the operating system keeps distinct.

Cybersecurity 18 Sep 2026 5 min read

MADV_DONTDUMP Excludes Selected Memory Mappings from Linux Core Images

A long-running service may keep credentials, session material, or decrypted state in memory while still relying on core images for crash diagnosis. Disabling core generation for the entire process removes diagnostic state along with sensitive state. Linux provides a narrower control: madvise() with MADV_DONTDUMP marks selected mappings so the kernel omits them from a core image. This mechanism changes core-dump inclusion policy for an address range. It does not make the bytes inaccessible to the process, encrypt them, erase them, or create a general barrier against process inspection. Its security value is specific to one data-exposure path: memory captured through the kernel core-dump mechanism.

Software Engineering 18 Sep 2026 6 min read

Linux userfaultfd Moves Selected Page Fault Handling into User Space

A page fault normally crosses from a process into the kernel and returns only after the kernel has resolved the virtual-memory condition or delivered an error. Linux userfaultfd can insert a user-space component into that path for explicitly registered address ranges. The kernel reports selected faults through a file descriptor, blocks the faulting execution context when the mode requires it, and accepts an ioctl that resolves the fault. This is a Linux virtual-memory interface, not a C or POSIX memory guarantee. Its behavior depends on negotiated kernel features, the registered range, its mapping type, and the registration mode.

Software Engineering 18 Sep 2026 7 min read

Linux splice Makes Pipe Capacity Part of Data-Transfer Semantics

Linux splice() can transfer bytes between file descriptors without routing those bytes through a user-space buffer, but the interface is not a generic descriptor-to-descriptor copy primitive. At least one endpoint must be a pipe. That requirement makes pipe state part of the transfer contract: capacity, readable data, writer presence, blocking mode, and partial progress can all affect an otherwise straightforward data path. The useful boundary is therefore not simply “kernel copy versus user copy.” splice() changes the shape of ownership and flow control. Application code stops owning an intermediate byte array, while it still owns the control loop that accounts for bytes transferred, handles readiness, and preserves offset semantics.

Software Engineering 18 Sep 2026 5 min read

Linux signalfd Converts Selected Signals into Descriptor Reads

A signal included in a signalfd mask can become readable state on a file descriptor instead of invoking an asynchronous signal handler, provided that the signal is blocked from ordinary delivery in the relevant thread. This changes the interface boundary: signal arrival can participate in the same descriptor-oriented event loop as sockets, pipes, and other pollable objects. The mechanism does not replace Linux signal semantics. Signal generation, process and thread signal masks, pending state, standard-signal coalescing, real-time signal queuing, and delivery rules still apply. signalfd changes the consumption interface for signals selected by its mask.

Software Engineering 18 Sep 2026 7 min read

Linux signalfd Converts Pending Signals into Descriptor Reads

Linux signalfd gives selected signals a descriptor-oriented consumption path. Instead of transferring control into an asynchronous handler, a process can block those signals, associate them with a signalfd object, and consume pending instances through read(). The descriptor can also participate in poll(), select(), and epoll, placing signal reception beside sockets, timers, and other readiness sources. This interface is Linux-specific. The signal mask, pending-signal rules, and descriptor operations come from Linux and POSIX signal semantics where applicable; they are not properties of the C language itself.

Software Engineering 18 Sep 2026 6 min read

Linux renameat2 Makes Path-Replacement Policy Atomic

A pathname rename changes directory entries while open file descriptors continue to refer to the same underlying objects. Linux renameat2() adds policy to that namespace update: a caller can reject replacement, exchange two existing names, or request a whiteout for union-filesystem operation. These policies are executed as part of the rename operation rather than as checks performed separately in userspace. The interface is Linux-specific. A zero flags argument gives renameat() behavior, while nonzero flags add Linux semantics that also depend on support from the mounted filesystem.

Software Engineering 18 Sep 2026 6 min read

Linux pidfd Binds Process Operations to Stable Kernel References

A numeric process ID is a name in a PID namespace, not a durable handle to one process lifetime. After a process exits and its PID becomes available for reuse, a later process can receive the same number. Linux PID file descriptors add a different interface boundary: a pidfd is a file descriptor referring to a particular task, so later operations can target that kernel reference rather than resolving the numeric PID again.

Software Engineering 18 Sep 2026 5 min read

Linux pidfd Binds Process Operations to Stable Kernel Identity

A numeric PID names a process through a namespace lookup. That number can later be reused after the process exits and is reaped. Linux PID file descriptors change the boundary: a pidfd is a file descriptor referring to a particular task, so later operations can target that reference instead of resolving the numeric PID again. This is Linux-specific process-management behavior. It is not a property of POSIX process identifiers or of the C language.

Software Engineering 18 Sep 2026 6 min read

Linux openat2 Constrains Path Resolution Inside a Directory Boundary

A pathname passed to openat2() can be resolved relative to a directory file descriptor while the kernel enforces restrictions on the resolution process itself. That distinction matters when a process accepts path components from a less-trusted source. A string check can inspect the pathname text, but it cannot by itself freeze the filesystem namespace while lookup proceeds. openat2() places the policy beside the lookup. Its struct open_how separates ordinary open flags from resolve flags that constrain traversal. The resulting boundary is about resolution semantics, not merely the spelling of a path.

Software Engineering 18 Sep 2026 5 min read

Linux O_PATH Separates Object Reference From I/O Authority

open() usually combines two effects: pathname resolution selects a filesystem object, then the returned file descriptor carries an access mode for data I/O. Linux O_PATH splits those effects. A successful open(path, O_PATH) returns a descriptor that refers to the selected object while ordinary read() and write() through that descriptor are not permitted. That split is useful anywhere a process needs a durable kernel reference for later metadata or pathname-relative operations without opening the object for data transfer. It also changes race analysis: later operations can start from the descriptor rather than resolving the original pathname again.

Software Engineering 18 Sep 2026 4 min read

Linux memfd Seals Turn Mutable Memory Files into Enforced State Transitions

A file created by memfd_create() can begin as mutable storage and later acquire kernel-enforced restrictions that apply to the underlying file rather than to one descriptor. With MFD_ALLOW_SEALING, a process can add seals through fcntl(F_ADD_SEALS) and make selected mutations unavailable to every holder of that file. This creates a state transition that ordinary descriptor permissions do not express. A producer can populate bytes, fix the file’s size, and then publish the descriptor with restrictions that remain attached even after the descriptor crosses a process boundary.

Software Engineering 18 Sep 2026 6 min read

Linux memfd Seals Convert Mutable Anonymous Files into Restricted Capabilities

A file descriptor returned by memfd_create() can begin as a writable, resizable anonymous file and later become an object whose permitted mutation operations have been permanently reduced. Linux implements that transition with file seals. The mechanism is attached to the underlying file rather than to one descriptor, so passing a duplicate descriptor across a process boundary does not create an independent sealing state. This property makes sealing more than a convenience around temporary storage. It changes the authority carried by every descriptor that refers to the same memfd object. The transition is monotonic: seals can be added, but they cannot be removed.

Software Engineering 18 Sep 2026 5 min read

Linux inotify Reports Directory-Entry Events, Not Durable Path Identity

An inotify watch does not make a pathname a durable identifier. Linux attaches a watch to a filesystem object selected when inotify_add_watch() succeeds, then emits records describing activity associated with watched objects and directory entries. Names can move, objects can disappear, and event delivery can lose detail when the queue overflows. That boundary matters for file synchronizers, configuration reloaders, indexers, and service supervisors. An event stream can signal that local filesystem state changed, but reconstructing authoritative state still depends on filesystem operations performed after the event.

Software Engineering 18 Sep 2026 5 min read

Linux eventfd Represents Counter State Through Descriptor Readiness

An eventfd object stores an unsigned 64-bit counter in the kernel and exposes that state through a file descriptor. Writes add to the counter under defined bounds; reads consume counter state; readiness interfaces expose whether an operation can proceed without blocking. The result is a compact synchronization boundary that fits descriptor-oriented event loops without turning the counter into a byte stream. The interface is Linux-specific. Its guarantees come from the eventfd system-call contract and kernel descriptor semantics, not from the C language or POSIX.

Software Engineering 18 Sep 2026 8 min read

Linux copy_file_range Separates Copy Semantics From Data Movement

copy_file_range() asks Linux to copy bytes between regular files without requiring the application to shuttle those bytes through a user-space buffer. The call defines a byte-range operation, but it does not prescribe the physical transfer mechanism. A filesystem can perform ordinary data movement, use a copy-on-write sharing mechanism such as reflink, or employ another supported acceleration path while preserving the visible file contents required by the operation. That separation is the central API boundary. Applications specify source and destination ranges and observe the returned byte count. The kernel and filesystem retain latitude over the mechanism used to realize the copy.

Software Engineering 18 Sep 2026 8 min read

Linux close_range Makes Descriptor-Table Cleanup a Range Operation

A process preparing to execute another program often needs a simple descriptor invariant: standard input, output, and error remain available, while unrelated descriptors do not cross the execution boundary. Closing descriptors one at a time can turn that invariant into an enumeration problem. Linux close_range() instead applies an operation to an inclusive numeric interval in the calling task’s file-descriptor table. The interface is small, but its semantics reach into descriptor-table sharing, execve() inheritance, concurrent descriptor allocation, and privilege transitions. The flags select more than implementation strategy: they determine whether descriptors disappear immediately, become close-on-exec, or are first separated from a table shared with other tasks.

Software Engineering 18 Sep 2026 5 min read

Linux close_range Makes Descriptor Cleanup a Table Operation

A process preparing for execve() often needs a simple invariant: descriptors above a small allowlist must not survive into the new program. Closing descriptor numbers one by one turns that invariant into an enumeration problem. Linux close_range() expresses it directly as an operation over an inclusive interval of the calling task’s file descriptor table. The interface is Linux-specific. Its behavior belongs to Linux file-table and system-call semantics, not to the C language or a portable POSIX guarantee.

Linux 18 Sep 2026 6 min read

Landlock Rulesets Add Process-Local Access Control

A Linux process can voluntarily remove access that its UID, capabilities, mount namespace, and other security layers would otherwise permit. Landlock implements this as a stackable Linux Security Module: a process creates a ruleset, adds allowed objects, then places itself in a Landlock domain. The resulting policy is an additional restriction. It does not grant access denied by DAC, ACLs, SELinux, AppArmor, mount permissions, or another active control. Once enforced, the Landlock layer cannot be removed from that thread; later Landlock domains can only add restrictions.

Cybersecurity 18 Sep 2026 6 min read

Landlock Rulesets Add a Process-Scoped Filesystem Access Boundary

A service can begin with ordinary filesystem permissions that are broader than the files it needs during steady-state operation. Changing ownership or mount topology may be impractical because the same host resources are shared with other processes. Linux Landlock addresses this gap by letting a process add a kernel-enforced access restriction to itself and, through inheritance, to descendants. Landlock is a Linux Security Module designed for sandboxing. Its rules do not grant filesystem access that DAC, ACLs, capabilities, or another security mechanism would otherwise deny. They add another authorization layer. An operation succeeds only when the other applicable controls and the Landlock policy permit it.

Software Engineering 18 Sep 2026 4 min read

Landlock Handled Rights Define a Deny-by-Default Sandbox Boundary

A Landlock ruleset does not implicitly deny every operation known to the running kernel. It first declares which access rights it handles. Once the ruleset is enforced, those handled actions are denied by default unless a matching rule grants them. That explicit boundary is central to Landlock compatibility. User space can restrict rights it knows and has tested while a newer kernel may expose additional rights that an older binary never named.