Skip to content

Archive / page 19

All articles

Every practical article from the Nalar archive, newest first.

Tech 17 Sep 2026 6 min read

NIC Interrupt Coalescing Trades CPU Overhead for Packet Latency

A network interface can receive packets faster than a CPU should service one hardware interrupt per packet. Interrupt coalescing addresses that mismatch by allowing the adapter to group completion notifications and interrupt the CPU less often. The tradeoff is explicit. Fewer interrupts reduce interrupt handling and scheduling pressure, but a packet may wait longer before software is told that receive work is ready. The best setting depends on packet rate, latency targets, CPU capacity, and the adapter’s coalescing controls.

Cybersecurity 17 Sep 2026 10 min read

Mutual TLS Identity Can Disappear at a Terminating Proxy

Mutual TLS Identity Can Disappear at a Terminating Proxy A service can require a client certificate at its public endpoint, accept only certificates chained to an approved authority, and still deliver an unauthenticated request to the application behind it. The TLS check may be completely correct. The gap appears when a reverse proxy terminates that TLS connection and opens a different connection to the backend. Mutual TLS authenticates endpoints of a particular TLS connection. It does not automatically attach the authenticated client identity to HTTP requests after that connection ends, and it does not cause a second TLS connection to inherit the first connection’s peer. Once a proxy becomes the TLS server for the external client, the proxy is the component that possesses the verified client-certificate result. Any backend identity derived from that result crosses a new trust boundary.

Tech 17 Sep 2026 6 min read

Memory Fences Constrain Cross-Core Memory Ordering

Memory Fences Constrain Cross-Core Memory Ordering A processor can execute memory operations with more freedom than source-code order suggests. Loads may begin early, stores may wait in buffers, cache-coherence traffic may complete at different times, and independent operations can overlap. These techniques improve throughput, but concurrent software needs precise rules for publishing and observing shared state. A memory fence places an ordering constraint around selected memory operations. It does not normally flush every cache, serialize the entire processor, or make all cores execute one instruction stream. Its role is narrower: it restricts which memory-order outcomes are permitted across a defined boundary.

Cybersecurity 17 Sep 2026 6 min read

Memfd Seals Turn Shared Memory Into Monotonic File Policy

Memfd Seals Turn Shared Memory Into Monotonic File Policy A process prepares a binary object in memory, passes its file descriptor to another process, and expects the bytes to remain stable after validation. Ordinary shared memory does not provide that property by itself: another holder of writable authority can change the object after a check, resize it, or keep a writable mapping alive. Linux file seals provide a narrower contract. They remove selected mutation operations from a sealable file, and successfully added seals cannot later be removed.

Software Engineering 17 Sep 2026 4 min read

memfd Seals Turn Shared Files into Monotonic Objects

A Linux memfd can begin as a writable anonymous file and later acquire restrictions that cannot be removed. The restrictions belong to the inode, so transferring or duplicating a descriptor does not create a less restricted view. Once a seal is added successfully, every descriptor referring to that inode is subject to it. This makes sealing different from descriptor access modes. A descriptor can carry local flags, while a seal changes the mutation boundary of the shared file object itself.

Software Engineering 17 Sep 2026 6 min read

Linux userfaultfd Turns Page Faults Into a Userspace Protocol

A thread can access a valid virtual address and stop before that access completes because another userspace component has been given responsibility for resolving the page fault. With Linux userfaultfd, selected memory ranges can turn faults into descriptor messages while the faulting thread remains blocked until an appropriate resolution operation makes progress possible. This is not a replacement for the kernel’s virtual-memory subsystem. The kernel still detects the fault, validates the registered range, blocks the affected execution path, and performs the page-table operation requested by the manager. The unusual boundary is that userspace can participate in deciding when and with what contents a fault is resolved.

Software Engineering 17 Sep 2026 4 min read

Linux timerfd Read Reports Accumulated Expirations

A periodic Linux timerfd can expire several times before an event loop reads it. The next successful read() does not return one record per wakeup. It returns one host-order uint64_t containing the number of expirations accumulated since the timer was last armed or since the preceding successful read. That count makes timerfd readiness a notification that timer state is consumable, not a one-to-one mapping between scheduler wakeups and timer periods.

Software Engineering 17 Sep 2026 6 min read

Linux timerfd Makes Missed Periods Observable as Expiration Counts

A periodic Linux timerfd can expire several times before an event loop runs again. The next successful read() does not merely report that the timer fired; it returns an unsigned 64-bit count of expirations accumulated since the previous successful read or since the timer was last configured. Delayed dispatch therefore becomes observable as a count rather than a sequence of queued timer records. That contract separates timer schedule from consumer execution. A process may be descheduled, an event loop may spend time on other descriptors, or several periods may pass before the timerfd is consumed. The kernel tracks expirations, while application code decides what multiple expirations mean for the work associated with them.

Software Engineering 17 Sep 2026 7 min read

Linux splice Makes the Pipe a Kernel Data-Transfer Boundary

splice() can transfer bytes between two file descriptors without first copying the payload into a userspace buffer, but the interface requires at least one endpoint to be a pipe. That requirement makes the pipe more than an incidental transport. It is the kernel-visible buffer boundary around which the operation’s offset, blocking, capacity, and partial-progress semantics are defined. This differs from a conventional read() followed by write(). In that sequence, userspace owns an intermediate byte array and can inspect or modify it. With splice(), the payload can remain in kernel-managed storage while the process coordinates movement between endpoints.

Software Engineering 17 Sep 2026 5 min read

Linux signalfd Turns Pending Signals Into Readable State

A Linux process can block selected signals and receive them by reading a file descriptor instead of running an asynchronous handler. signalfd() makes those pending signals visible through the same readiness interfaces used for sockets, pipes, and other descriptors, including poll() and epoll. That conversion is not a replacement for signal masking. The descriptor has its own signal set, while each thread retains a signal mask that controls ordinary delivery. A robust design depends on both states remaining aligned.

Software Engineering 17 Sep 2026 6 min read

Linux signalfd Moves Signal Delivery Into File-Descriptor Readiness

Linux signalfd Moves Signal Delivery Into File-Descriptor Readiness signalfd() changes the consumption interface for selected Linux signals. Instead of arranging for an asynchronous signal handler to run when one of those signals is delivered, a process can block the signals and receive their information by reading a file descriptor. That descriptor can participate in poll(), epoll, and related readiness mechanisms, so signal handling can share the same dispatch boundary as sockets, pipes, timers, and other pollable objects.

Software Engineering 17 Sep 2026 6 min read

Linux seccomp Notification Splits Syscall Entry From Supervisor Response

A seccomp filter can stop a task at syscall entry and turn that event into a message for another process. With SECCOMP_RET_USER_NOTIF, the kernel does not immediately execute the selected syscall. It creates a notification for a listener, blocks the calling task, and waits for a response that can supply a return value, inject a file descriptor, or permit the syscall to continue. That boundary is narrower than general syscall emulation. The notification carries syscall metadata and register argument values, while memory referenced by pointer arguments remains in the target process. The target can also disappear or have its notification invalidated while a supervisor is making a decision. Those properties make identity, memory ownership, and response timing part of the interface contract.

Software Engineering 17 Sep 2026 6 min read

Linux pidfds Turn Process Identity Into a Pollable Handle

A Linux process ID is a number from a reusable namespace. A pidfd is different: it is a file descriptor that refers to a particular process. That distinction changes process management from repeated lookup by numeric name into operations against a kernel-held handle whose identity does not silently retarget when a PID is recycled. The difference is most visible in supervisors, launchers, sandboxes, and service managers that retain process references across asynchronous work. A numeric PID can remain syntactically valid after the original process exits, yet later identify another process. A pidfd keeps the reference tied to the original process object and can also participate in descriptor-oriented event loops.

Software Engineering 17 Sep 2026 5 min read

Linux pidfd Binds Process Identity to a File Descriptor

A numeric PID is a name from a reusable kernel namespace. Once a process exits and its PID becomes available for reuse, a later process can receive the same number. Linux pidfds add a different form of reference: a file descriptor tied to a specific task rather than a number that must be resolved again at each operation. That distinction changes the boundary between process discovery and later process control. A program can resolve a PID once with pidfd_open(), retain the resulting descriptor, and use pidfd-aware interfaces without treating the numeric PID as permanent identity.

Software Engineering 17 Sep 2026 6 min read

Linux openat2 Makes Path Resolution Policy Part of the Open Operation

A pathname is not an object reference. It is an instruction for traversing a mutable namespace, and another task can alter directory entries, symbolic links, or mounts while that traversal is relevant to an application. Linux openat2() addresses this boundary by placing path-resolution constraints in the same kernel operation that returns the file descriptor. That placement matters when a program accepts a pathname but intends to confine resolution to a directory tree. A user-space sequence that inspects components and later calls open() separates validation from use. openat2() can instead make selected traversal rules part of the lookup itself.

Software Engineering 17 Sep 2026 9 min read

Linux openat2 Makes Path Resolution Constraints Atomic

A pathname can name a different object by the time a second lookup checks it. On Linux, openat2() addresses that boundary by attaching resolution constraints to the same kernel operation that walks the pathname and opens the resulting object. The policy is evaluated during lookup rather than inferred from a pathname inspected before or after the open. This distinction matters whenever a process accepts path components from a less-trusted source while intending to keep resolution inside a directory, reject symbolic links, avoid mount crossings, or require a cache-only lookup. The relevant object is not the input string alone. It is the result of resolving that string against a live namespace whose directory entries, links, and mounts can change concurrently.

Software Engineering 17 Sep 2026 6 min read

Linux O_TMPFILE Keeps Staging Files Out of the Namespace

Linux O_TMPFILE creates a regular file without first placing a name for that file in a directory. The caller receives a file descriptor and can write data, set metadata, or abandon the object while no pathname exposes the partially prepared file. If publication is required, a later link operation can attach a directory entry to the same inode. This separates object construction from namespace publication. It does not make every surrounding filesystem operation transactional, and it does not provide replacement semantics for an existing destination. Its useful boundary is narrower: intermediate file state can remain reachable only through open references until the process explicitly creates a name.

Software Engineering 17 Sep 2026 6 min read

Linux mmap Keeps File Lifetime Separate From Descriptor Lifetime

A successful file-backed mmap() creates a virtual-memory mapping that does not depend on keeping the source file descriptor open. Linux explicitly permits the descriptor to be closed immediately after mmap() returns without invalidating the mapping. The mapping and the descriptor are therefore separate references with separate lifetimes. That separation is easy to miss because both originate from the same open file. It becomes operationally important when code closes descriptors aggressively, replaces pathnames, truncates files, or passes mappings across fork(). A mapped address is not a delayed read() through the original descriptor; it participates in the virtual-memory system under its own mapping contract.

Software Engineering 17 Sep 2026 6 min read

Linux memfd Seals Turn Mutable File State Into a Restricted Contract

Linux memfd Seals Turn Mutable File State Into a Restricted Contract A file returned by memfd_create() begins as mutable file state backed by memory-oriented storage, but Linux can progressively remove mutation operations from that file. When creation uses MFD_ALLOW_SEALING, fcntl() with F_ADD_SEALS can prohibit shrinking, growth, writes, future writes, or further changes to the seal set. The resulting restrictions belong to the inode, not to one descriptor, so passing another descriptor for the same object does not restore operations that a seal removed.

Software Engineering 17 Sep 2026 7 min read

Linux memfd Seals Turn Mutable Bytes Into a Kernel-Enforced Contract

A memfd can begin as a writable anonymous file and later reject whole classes of mutation through kernel-enforced seals. The transition is attached to the inode, not to one descriptor, so a process cannot preserve an unrestricted duplicate descriptor and use it to bypass a seal added through another reference. This makes sealing materially different from handing another component a descriptor opened with narrower access. Descriptor access mode constrains one open file description. A seal changes which operations the kernel permits against the file itself, including operations attempted through other descriptors that refer to the same inode.

Software Engineering 17 Sep 2026 5 min read

Linux io_uring Separates Submission From Completion Ownership

Linux io_uring Separates Submission From Completion Ownership An io_uring request can remain in flight after the application has finished constructing its submission queue entry. That creates a lifetime boundary absent from a simple synchronous call: request metadata may become stable at submission, while memory used as the actual I/O payload can still be accessed until the operation completes. The completion queue is therefore not only a result channel. For many operations, it marks the point at which application-owned operation state can be reclaimed or reused.

Software Engineering 17 Sep 2026 6 min read

Linux inotify Events Are a Lossy Change Stream

An inotify file descriptor exposes filesystem activity as an ordered queue of event records, but that queue is not an authoritative history of namespace state. Identical unread events may be coalesced, queue capacity is bounded, and an overflow explicitly means events have been lost. A process that treats the stream as a complete transaction log can therefore preserve a state that no longer matches the filesystem. The interface is better modeled as change notification with recovery obligations. Events can make a cache current incrementally while the stream remains intact; some conditions invalidate that incremental history and require reconciliation against filesystem state.

Software Engineering 17 Sep 2026 5 min read

Linux eventfd Makes Counter State Pollable

A Linux eventfd can collapse many notifications into one kernel-maintained counter while still participating in poll(), select(), and epoll. Writers add unsigned 64-bit values to the counter; readiness reports whether that state can be consumed. The interface carries arithmetic state rather than a byte stream or a queue of individual messages. That distinction matters at process and thread boundaries. A wakeup says that the counter is nonzero. It does not preserve the number of write operations, writer identities, or ordering among independent notification sources.

Software Engineering 17 Sep 2026 6 min read

Linux eventfd Couples Counter State With Descriptor Readiness

An eventfd object combines a kernel-maintained unsigned 64-bit counter with file-descriptor readiness. A write adds to the counter when the addition is permitted; a read consumes counter state. Because the same object participates in poll(), select(), and epoll(), a counter transition can also become an event-loop notification without a byte stream or message framing layer. That compact interface has sharp semantics. Default reads drain the current value to zero, EFD_SEMAPHORE reads consume one unit, writes can block near the counter limit, and readiness indicates which operation can proceed rather than the number of logical events an application may have assigned to the counter.