Linux Kernel

8 posts

meta3 min readCurated summary

Modernizing the Meta Ads Service With an Open-Source Kernel Scheduler

At Meta’s scale, small latency regressions can materially affect ad relevance, ranking, and revenue. When Linux kernel 6.9’s EEVDF scheduler reduced ad-serving performance, Meta used sched_ext to deploy a workload-specific BPF scheduler without modifying the kernel. The solution reduced p99 ads-retrieval latency by 28%, saved 3.28 MW of power, increased ads ranked by 1.1%, and enabled further improvements through rapid user-space updates. ## Why Ads Latency Matters - Meta’s ads platform processes more than 5 million requests per second, or over 400 billion requests daily. - Lower p99 latency allows more relevant ads to be retrieved and ranked within each request. - General-purpose schedulers such as CFS and EEVDF balance CPU usage without understanding which threads are most important to ad delivery. - Ads-specific scheduling can prioritize work on the critical request path while deferring less-sensitive tasks. ## The Kernel Upgrade Problem - During a move from Linux 6.4 to 6.9, Meta found that EEVDF introduced a latency regression. - The regression reduced the number of ads ranked in responses. - Some servers had to remain on Linux 6.4, creating operational fragmentation and technical debt. - sched_ext provided a way to address the regression without waiting for another kernel release. ## How sched_ext Customizes Scheduling - sched_ext is an upstream, BPF-based framework that entered Linux 6.12. - It lets developers implement scheduling policies in BPF programs responding to events such as: - Thread wake-ups - Run-queue insertion - Dispatching the next thread - CPU idle-state transitions - Meta’s policy divides CPUs into two dynamically sized pools: - Latency-critical request-path threads - Less latency-sensitive background work - Keeping related work on the same CPUs improves L3 cache locality and reduces DRAM access. - The scheduler is loaded by a user-space binary, so new policies can be deployed by restarting the scheduler process rather than rebuilding the kernel. ## Performance and Operational Results The initial deployment on the largest ads-serving server type achieved: - 28% lower p99 latency on the ads retrieval path - 1.1% more weighted ads ranked - 3.28 MW of fleet-wide power savings Two subsequent policy updates produced additional gains: - A further 60% reduction in service p99 latency - 18% fewer timeout errors on the critical path - Delivery in days instead of the months typically required for kernel changes ## From Fix to Optimization Platform - sched_ext gives Meta an independent scheduling-development path alongside upstream Linux evolution. - BPF updates support rapid experimentation with: - Cache-aware thread placement - ROI-based executor routing - NUMA-aware scheduling - Because sched_ext is upstream, other organizations can implement workload-specific policies without maintaining a Linux kernel fork. - Meta plans to use application-level hints, such as request importance, to adjust scheduling slices and queue priority dynamically. sched_ext demonstrates that application-aware scheduling can produce measurable business, latency, and energy benefits. For workloads with priorities that general-purpose schedulers cannot see, an extensible BPF-based scheduler offers a practical way to optimize continuously without coupling improvements to kernel release cycles.

Read original(opens in new tab)
cloudflare3 min readCurated summary

When "idle" isn't idle: how a Linux kernel optimization became a QUIC bug

CUBIC, the default congestion controller in Linux and quiche, can become permanently stuck at its minimum congestion window after an early congestion collapse. Cloudflare found the bug in a QUIC test where packet loss stopped completely, yet CUBIC continued oscillating between recovery and congestion avoidance instead of increasing its sending rate. The problem was traced to a Linux TCP optimization for idle or app-limited connections, and ultimately fixed with an elegant near-one-line change. ## How CUBIC manages traffic - CUBIC controls the sender’s congestion window (`cwnd`), limiting how many bytes can be in flight. - It increases `cwnd` when acknowledgments arrive without loss and reduces it when loss suggests the network is overloaded. - As quiche’s default congestion controller, CUBIC affects a substantial amount of QUIC traffic. - Recovery from the minimum congestion window is an important but relatively under-tested part of congestion control. ## The failing test - The test downloaded a 10 MB file over HTTP/3 between local quiche client and server. - Network conditions included: - 10 ms RTT - 30% random packet loss during the first two seconds - No packet loss after two seconds - A 10-second timeout - The expected result was for CUBIC to reduce its window during loss, then steadily recover once the network became reliable. - Instead, approximately 60% of repeated 100-run test batches failed to finish in time. ## CUBIC becomes stuck at its minimum - After packet loss stopped at two seconds, bytes in flight remained flat rather than increasing. - CUBIC’s congestion window stayed at its minimum of 2,700 bytes—roughly two full-sized packets. - The controller repeatedly switched between recovery and congestion avoidance: - 999 transitions over about 6.7 seconds - One transition approximately every 14 ms - The oscillation closely matched the connection’s RTT, indicating that each ACK round was triggering the behavior. - Because the test was a download, client ACKs caused the server’s bytes in flight to fall to zero; the server then sent another two-packet burst, repeatedly provoking the faulty state transition. - Reno passed the same test 100% of the time, confirming that the issue was specific to CUBIC rather than the test setup. ## The connection to Linux TCP - The investigation focused on behavior when `bytes_in_flight == 0`, effectively an idle or app-limited condition. - A 2017 Linux kernel change addressed a TCP CUBIC issue after application idle periods. - Before the change, CUBIC’s epoch could remain unchanged for a long time while the application was idle. - When sending resumed, the elapsed time used by CUBIC could be extremely large, producing an excessively aggressive growth slope and dangerous congestion-window inflation. - The kernel optimization was intended to align CUBIC with the app-limited exclusion described in RFC 9438 §4.2-12. - Porting this logic to QUIC exposed an unintended interaction: repeated short periods with no bytes in flight could be interpreted incorrectly, causing CUBIC to cycle between states and remain at its minimum window. The practical lesson is that congestion-control implementations must test not only steady-state throughput and ordinary loss recovery, but also recovery from the minimum window and repeated app-limited or idle periods. In this case, a small adjustment to the idle-state handling broke the cycle and allowed CUBIC to recover normally.

Read original(opens in new tab)
cloudflare3 min readCurated summary

How Cloudflare responded to the “Copy Fail” Linux vulnerability

Cloudflare assessed the “Copy Fail” Linux privilege-escalation vulnerability (CVE-2026-31431) immediately after its disclosure on April 29, 2026. Its existing kernel update process meant the relevant fixes were already deployed across most infrastructure, while behavioral detections could identify exploitation attempts within minutes. Cloudflare reported no environmental impact, customer data exposure, or service disruption. ## Cloudflare’s Linux Kernel Update Process - Cloudflare runs custom Linux kernels based on community Long-Term Support releases across datacenters in 330 cities. - Automated jobs build updated kernels approximately weekly from upstream security and stability fixes. - New builds are tested in staging before global deployment. - The Edge Reboot Release pipeline rolls updates through edge infrastructure on a four-week cycle. - Control-plane systems generally use the newest kernel, with reboots scheduled based on workload requirements. - By the time vulnerabilities are publicly disclosed, fixes are typically already present in stable LTS releases and deployed by Cloudflare. - At disclosure, most systems used Linux 6.12 LTS, while some were transitioning to 6.18 LTS. ## How Copy Fail Worked - The vulnerability affected the Linux kernel’s `AF_ALG` interface, which lets unprivileged processes access cryptographic operations through the `algif_aead` module. - Attackers could combine: - `sendmsg()` or `splice()` to submit data - `recvmsg()` to execute the cryptographic operation - Page-cache references to redirect writes into files - An older in-place optimization allowed the AEAD implementation to write beyond the intended output boundary. - The `authencesn` wrapper performed a controllable four-byte out-of-bounds write. - By using `splice()`, an attacker could target pages belonging to any readable file and control: - The file being modified - The write offset - The four bytes written ## Privilege Escalation Through `/usr/bin/su` - The public exploit targeted `/usr/bin/su`, a setuid-root binary commonly present on Linux systems. - The attacker populated the binary’s contents in the page cache and connected those cached pages to a crypto scatterlist. - Shellcode was supplied through AAD bytes in `sendmsg()`. - `splice()` parameters controlled the target offset in the binary. - Although `recvmsg()` returned `-EBADMSG`, the out-of-bounds write had already modified the shared page cache. - Executing `/usr/bin/su` then loaded the modified cached pages, causing the injected code to run with root privileges. ## Upstream Fix and Cloudflare’s Response - The upstream fix, commit `a664bf3d603d`, reverted the 2017 in-place optimization responsible for the flaw. - After disclosure, Cloudflare’s security and kernel engineering teams worked in parallel to: - Identify vulnerable kernel versions - Assess infrastructure exposure - Review the exploit technique - Validate behavioral detections - Existing monitoring could detect the exploit pattern within minutes. - Cloudflare concluded that its infrastructure was not impacted and that no customer data or services were affected. Cloudflare’s experience demonstrates the value of maintaining patched LTS kernels, automating frequent kernel builds and staged rollouts, and combining preventative patching with behavioral exploit detection.

Read original(opens in new tab)
github3 min readCurated summary

How GitHub uses eBPF to improve deployment safety

GitHub uses eBPF to prevent deployment scripts from depending on GitHub or other services that may be unavailable during an outage. The approach applies network restrictions only to deployment processes, preserving normal traffic for stateful production hosts. By combining Linux cgroups with eBPF’s `BPF_PROG_TYPE_CGROUP_SKB` hooks, GitHub can detect or block unsafe outbound calls before they create circular deployment dependencies. ## The Deployment Circular Dependency - GitHub hosts its own source code on `github.com`, creating a basic dependency: GitHub may need GitHub to deploy a fix. - GitHub mitigates this with: - A code mirror used for “fix-forward” deployments. - Prebuilt assets used to roll back changes. - Additional circular dependencies can still be introduced by deployment scripts, internal services, or tools that download binaries dynamically. ## Three Types of Circular Dependencies The post uses a hypothetical MySQL outage to illustrate how deployment recovery can fail: - **Direct dependencies** - A deployment script downloads the latest release of an open-source tool from GitHub. - If GitHub cannot serve release data, the deployment cannot complete. - **Hidden dependencies** - A required tool is already installed locally but checks GitHub for updates when it runs. - The tool may fail or hang if that update check cannot connect. - **Transient dependencies** - The deployment calls another internal service, such as a migrations service. - That service then attempts to download a binary from GitHub, causing the failure to propagate back to the deployment. ## Why Manual Review Is Insufficient - Teams responsible for stateful hosts traditionally review deployment scripts for circular dependencies. - Many indirect or unexpected dependencies are discovered only during incidents, when they can delay recovery. - Blocking `github.com` at the host level would be too disruptive because stateful hosts continue serving customer traffic during deploys, drains, and restarts. ## Per-Process Network Filtering with eBPF - eBPF allows custom programs to run inside the Linux kernel and attach to low-level operations such as networking. - GitHub focused on `BPF_PROG_TYPE_CGROUP_SKB`, which can inspect network egress for a specific cgroup. - Linux cgroups provide process grouping, isolation, and resource controls without requiring Docker. - The proposed design: - Create a dedicated cgroup. - Place only the deployment script and its processes inside it. - Restrict or monitor outbound network access for that group. - Leave the host’s ordinary production traffic unaffected. ## Proof of Concept with Go and eBPF - The proof of concept uses Go and the `cilium/ebpf` library. - The library simplifies: - Compiling and loading eBPF programs. - Attaching programs to kernel hooks. - Reading and updating eBPF maps. - The example attaches an egress program to `/sys/fs/cgroup/system.slice`. - An eBPF array map tracks the number of egress packets, while the Go program periodically reads and reports the counter. - The same mechanism can be extended from packet counting to selectively allowing or blocking network traffic. GitHub’s approach moves dependency validation from manual inspection into enforcement at runtime. Restricting only deployment processes with cgroups and eBPF provides a practical way to make emergency deployments independent of services that may be down, without blocking the production workloads sharing the same host.

Read original(opens in new tab)
netflix3 min readCurated summary

Mount Mayhem at Netflix: Scaling Containers on Modern CPUs

Netflix’s effort to modernize its container runtime exposed a hardware-level bottleneck rather than an application problem. Under heavy startup concurrency, containers with many image layers triggered massive mount and unmount activity, causing kernel lock contention, systemd stalls, and container startup failures. The issue was especially severe on older dual-socket NUMA instances, while newer single-socket systems scaled much more reliably. ## Container Startup at Netflix - New AWS capacity is rapidly filled with pods as applications scale. - Some nodes became unresponsive, with: - Health checks timing out for more than 30 seconds - Kubelet requests to containerd timing out - systemd processing huge numbers of mount events - The mount table taking tens of seconds to read - The problem primarily affected `r5.metal` instances running images with more than 50 layers. ## Mount Lock Contention - With user namespaces, containerd performs several mount operations for every image layer: - `open_tree()` references the layer. - `mount_setattr()` applies the container’s ID mapping. - `move_mount()` creates an ID-mapped bind mount. - These bind mounts become OverlayFS lower directories and are later unmounted. - The Linux VFS uses global mount-related locks, so concurrent container creation causes CPUs to contend on the same kernel locks. - For 100 containers with 50 layers each, containerd performs the process twice: - `100 × 2 × (1 + 50 + 50) = 20,200` mount operations - This makes startup cost depend heavily on both container concurrency and image layer count. ## Why the New Runtime Exposed the Problem - The old Docker-based runtime shifted file ownership while unpacking images. - All containers shared one host user range, avoiding repeated per-container mount work. - The new containerd-based runtime assigns each container a unique host user range for stronger isolation. - Instead of rewriting file ownership during extraction, it uses Linux ID-mapped mounts to apply ownership mappings efficiently. - This improves security and avoids expensive image copying, but creates many additional mount operations during startup. ## Differences Between AWS Instance Types Netflix compared: - `r5.metal`: 5th-generation Intel, dual-socket, multiple NUMA domains - `m7i.metal-24xl`: 7th-generation Intel, single-socket, single NUMA domain - `m7a.24xlarge`: 7th-generation AMD, single-socket, single NUMA domain Results showed: - At low concurrency—around 20 containers or fewer—all systems performed similarly. - `r5.metal` began failing at roughly 100 concurrent container launches. - Newer Intel instances maintained lower startup times and better success rates. - AMD-based `m7a` instances scaled most consistently and had the fewest failures. ## Kernel and CPU-Level Diagnosis - Profiling showed that containerd spent most of its time in Linux VFS path lookup code. - Specifically, threads were spinning in `path_init()` while waiting on a sequence lock. - Intel Topdown Microarchitecture Analysis found: - 95.5% of pipeline slots stalled on contested accesses - 57% attributed to false sharing - Cache-line bouncing and global lock contention, rather than raw CPU capacity, dominated performance. ## NUMA as a Contributing Factor - NUMA systems divide memory among processor sockets. - Local memory access is faster, while remote access crosses an interconnect and introduces additional latency. - The dual-socket layout of `r5.metal` amplified contention around shared mount-related data. - The better behavior of newer single-socket instances indicated that CPU topology and memory locality were key contributors to the container startup bottleneck. ## Practical Conclusion High-concurrency container launches can overwhelm kernel mount infrastructure, especially when using per-container ID mapping and images with many layers. Netflix’s results suggest minimizing image layers, controlling startup concurrency, and favoring newer single-socket hardware can substantially improve reliability and scaling.

Read original(opens in new tab)
datadog3 min readCurated summary

Hardening eBPF for runtime security: Lessons from Datadog Workload Protection

eBPF gives security tools broad, efficient, and relatively safe access to Linux kernel activity, making it well suited for runtime threat detection. Datadog chose it for Workload Protection after comparing kernel modules, tracing interfaces, ptrace, seccomp, Linux Audit, and other approaches. However, five years of production use across diverse kernels showed that eBPF’s safety and performance benefits are not automatic; reliability, compatibility, observability, and operational discipline are essential at scale. ## Why Runtime Workload Protection Is Needed - Static analysis and vulnerability scanning cannot catch every threat. - Zero-days and vulnerable third-party dependencies can remain active while patches are being prepared or deployed. - Workload Protection is intended to: - Monitor known-vulnerable workloads until they can be patched. - Continuously observe all workloads. - Detect and help mitigate previously unknown vulnerabilities during incident response. ## Alternatives Evaluated Datadog evaluated a broad range of Linux monitoring and instrumentation mechanisms: - **Linux kernel modules** - Offer deep access and can hook or replace almost any kernel function. - Are invasive and often considered too risky for production infrastructure. - **Traditional tracing interfaces** - Include inotify, fanotify, kprobes, tracepoints, and perf events. - Provide useful visibility but generally need to be combined for comprehensive coverage. - **ptrace and seccomp-bpf** - Can provide detailed user-space process visibility. - Are less suitable as a unified solution for monitoring the whole system. - **Linux Audit** - Produces configurable streams for process execution, file access, and network activity. - Is widely used by security tooling but has its own performance and operational tradeoffs. - **Other mechanisms** - Netlink, LD_PRELOAD, and binfmt_misc were also considered. - Each involves compromises in reliability, visibility, or system impact. ## Why eBPF Stood Out - **Safety checks** - The kernel statically verifies eBPF bytecode before loading it. - Verification detects issues such as infinite loops and unsafe memory access. - This is safer than deploying custom kernel modules, though eBPF can still cause harm or performance problems. - **Performance** - eBPF generally has lower overhead than approaches such as Linux Audit or ptrace. - Actual impact depends heavily on implementation and workload. - **Unified visibility** - A single mechanism can observe process, filesystem, and network activity. - This avoids assembling multiple specialized tracing systems. - **Container and namespace coverage** - eBPF provides consistent visibility across namespaces, cgroups, and containers. - CO-RE (Compile Once–Run Everywhere) improves portability across Linux distributions and kernel versions. - **Enforcement capabilities** - BPF LSM programs support mandatory access controls. - This gives eBPF enforcement power beyond ordinary tracing mechanisms, which is important for runtime security. ## Lessons from Operating eBPF at Scale After five years of operating an agent that hooks process scheduling, filesystem, and networking internals, Datadog emphasizes that production eBPF is more complicated than its reputation suggests. The six areas of operational experience are: - Ensuring programs load, attach, and continue firing across kernel versions. - Capturing and enriching event data accurately. - Monitoring and auditing eBPF usage to reduce the attack surface. - Coexisting with other eBPF-based tools on the same host. - Measuring and controlling performance overhead. - Shipping changes safely through disciplined rollout practices. The practical recommendation is to treat eBPF as powerful infrastructure rather than a maintenance-free kernel feature: validate behavior across kernels and workloads, monitor its own operation, measure overhead continuously, and use cautious deployment practices.

Read original(opens in new tab)
datadog3 min readCurated summary

Not just another network latency issue: How we unraveled a series of hidden bottlenecks

Repeated high-startup-latency pages in Datadog’s usage estimation service were caused by several independent bottlenecks rather than application changes. The investigation eventually identified four issues: CPU-throttled Envoy sidecars, a Linux kernel bug affecting ENA transmit queues, insufficient EC2 network bandwidth, and requests routed to terminating cache pods. Fixing each layer progressively reduced remote-cache p99 latency from roughly one second to its normal level of about 100 ms. ## Service Architecture and the Original Symptoms - The service consists of router, counter, and aggregator applications. - At startup, `counter` loads data from a remote cache into a local cache. - While the local cache is populating, request processing is slower and backlog grows. - Normal p99 remote-cache latency was approximately 100 ms, but it exceeded one second during deployments. - Scaling the remote cache did not help, indicating that the cache itself was not underprovisioned. ## CPU-Throttled Envoy Sidecars - Requests to the remote cache passed through an Envoy sidecar that batched queries into packets. - When `counter` restarted, Envoy reached its two-core CPU limit and was throttled. - Delayed request and response processing caused retries, TCP retransmits, and increased remote-cache latency. - Increasing Envoy’s CPU allocation eliminated the issue in staging and reduced production latency, but did not fully resolve rollout spikes. ## Linux Kernel and ENA Transmit-Queue Bug - Investigation of system and network metrics revealed a Linux kernel bug affecting AWS Elastic Network Adapter traffic. - The kernel mapped all outbound traffic to the first transmit queue instead of distributing it across eight queues. - This limited throughput and caused retransmits during high-traffic periods such as deployments. - A hotfix distributed traffic across all eight queues. - The change removed non-rollout latency spikes but rollout latency still fluctuated between 200 and 600 ms. ## EC2 Network Bandwidth Limits - ENA metrics showed that instances exceeded AWS inbound and outbound bandwidth allowances. - AWS dropped packets at the hypervisor when those limits were exceeded, causing retransmissions and slower cache requests. - Migrating to network-optimized EC2 instance types with higher bandwidth allowances largely restored p99 latency to around 100 ms. - Occasional one-second spikes continued despite the improvement. ## Requests Sent to Terminating Cache Pods - Remaining spikes correlated with remote-cache pods that were shutting down. - Clients continued sending requests to terminating pods, leading to one-second timeouts and retries. - The cache’s graceful-shutdown behavior did not adequately wait for Envoy clients’ in-flight requests. - The team added a `preStop` hook that sets an `XXX_MAINTENANCE_MODE` key to notify clients before termination and began coordinating shutdown with outstanding requests. The incident demonstrates the importance of tracing latency across the entire request path, from application startup through proxies, kernel networking, hardware interfaces, cloud bandwidth limits, and pod lifecycle behavior. Layered system metrics and component-level investigation were necessary to eliminate alert fatigue and restore reliable deployment behavior.

Read original(opens in new tab)
datadog3 min readCurated summary

Escaping containers using the Dirty Pipe vulnerability | Datadog Security Labs

The post demonstrates how the Linux Dirty Pipe vulnerability can enable an unprivileged process to escape a container and gain administrative privileges on the host. The exploit abuses runC’s execution model and its host binary, which is exposed read-only inside the container but can still be modified through the kernel page cache. A proof of concept shows how a compromised Kubernetes pod can overwrite runC with a malicious executable when an administrator runs `kubectl exec`. ## Container Runtimes and runC - Kubernetes commonly uses containerd or CRI-O through the Container Runtime Interface (CRI). - These runtimes rely on lower-level OCI runtimes, most notably runC, to create isolated Linux processes. - runC configures namespaces, cgroups, and the container environment before executing the supplied entrypoint with `execve`. - During execution, `/proc/self/exe` inside the container can refer to an open descriptor for the runC binary on the host. ## Earlier runC Escape Vulnerability - CVE-2019-5736 exploited this `/proc/self/exe` behavior: - A malicious container entrypoint could write to the host’s runC binary. - Overwriting runC enabled subsequent container operations to execute attacker-controlled code with host-level privileges. - runC initially mitigated the issue by cloning its binary before execution. - It later changed the design to mount the runC binary read-only inside the container, improving performance through kernel page-cache sharing. - That optimization created conditions in which Dirty Pipe could bypass the apparent read-only protection. ## Dirty Pipe as a Container Escape Primitive - Dirty Pipe allows an unprivileged process to overwrite files it can read, even without write permission. - The modification occurs in the kernel page cache rather than persistent storage: - The original file remains intact on disk. - Dropping caches or rebooting can restore the original contents. - Despite being temporary, the overwrite is sufficient to execute malicious code when the modified binary is run. - In this case, the attacker targets the host’s runC binary through `/proc/<runC-pid>/exe`. ## Kubernetes Proof of Concept - The demonstration starts an ordinary, unprivileged pod using an attacker-controlled container image. - Its entrypoint script: - Replaces `/bin/sh` with a launcher referencing `/proc/self/exe`. - Waits for a runC process to appear. - Invokes the Dirty Pipe exploit against that process’s executable. - An administrator running `kubectl exec` causes runC to execute inside the container, triggering the overwrite. - The modified runC is replaced with a malicious ELF binary that runs commands such as `id` and `hostname`, recording their output in `/tmp/hacked`. - The exploit is adapted from the original Dirty Pipe proof of concept and the earlier runC escape technique. The attack illustrates that kernel vulnerabilities can undermine container isolation even when the container is unprivileged and the target binary is mounted read-only. Systems should promptly patch vulnerable Linux kernels and container runtimes, while treating compromised containers as potential paths to host compromise.

Read original(opens in new tab)