Listen to this Post
A malicious container can crash or destabilize the privileged Inspektor Gadget process when a gadget using USDT probes is deployed. The vulnerability resides in the USDT note parser (pkg/uprobetracer/usdt.go), which is invoked when a gadget with a `SEC(“usdt/…”)` section attaches to a target binary.
An unprivileged process within a container can place a crafted ELF binary at the expected library path (e.g., a library name resolved via the container’s ld cache). When the USDT gadget attaches, Inspektor Gadget parses the malicious ELF, triggering one of three attack vectors:
1. Panic (immediate crash): A `stapsdt` note with a small `DescSize` causes an out-of-bounds slice access, panicking the IG process. In getUsdtInfo(), for a 64-bit ELF (wordSize = 8), the code reads three address fields from the note descriptor, requiring `desc` to be at least 24 bytes. However, `desc` is allocated based on the note’s `DescSize` field. A crafted ELF with `DescSize = 1` produces a 4-byte `desc` buffer, and the expression `desc[:8]` panics with: panic: runtime error: slice bounds out of range [:8] with capacity 4.
2. Memory exhaustion (OOM kill): A `stapsdt` note with a very large `NameSize` or `DescSize` causes IG to allocate up to ~4 GiB of memory. The `NameSize` and `DescSize` fields from the note header are used directly to allocate memory without any upper bound. A crafted ELF with `NameSize = 0xFFFFFFFF` would attempt to allocate ~4 GiB of memory. Under cgroup memory limits (common in Kubernetes deployments), this triggers an OOM kill of the IG process.
3. Missing panic recovery for debug/elf: Go’s `debug/elf` package is not hardened against adversarial inputs and may panic on malformed ELF headers. The `cilium/ebpf` library addresses this with its `SafeELFFile` wrapper that uses recover(), but `getUsdtInfo()` calls `elf.NewFile()` directly without any panic recovery.
Important: The vulnerability is only triggered when running a gadget that uses USDT probes (i.e., contains a `SEC(“usdt/…”)` eBPF section). No gadget shipped by the Inspektor Gadget project uses USDT today. Users who deploy their own custom USDT gadgets are affected.
Severity: Low — Denial of Service (process crash or OOM) of a privileged host process, triggered by an unprivileged container. The vulnerable code path is only reached when a gadget using USDT probes is deployed. No such gadget is shipped by the Inspektor Gadget project; only users running custom USDT gadgets are affected.
– Attack vector: An unprivileged process in a container places a crafted ELF file at a path that a USDT gadget targets. When the gadget attaches, IG parses the malicious ELF and crashes.
– Impact: The IG process panics and crashes (vector 1) or is OOM-killed (vector 2). This is a DoS against the monitoring infrastructure, not a code execution or privilege escalation vulnerability.
– Affected component: pkg/uprobetracer/usdt.go, function getUsdtInfo().
– Prerequisites: A gadget with a `SEC(“usdt/…”)` eBPF section must be running and configured to attach to a library inside the attacker’s container. No shipped gadgets use USDT probes, so this only affects deployments with custom USDT gadgets.
Affected Versions: All versions of Inspektor Gadget that include USDT support in pkg/uprobetracer/usdt.go, starting from v0.28.0 (commit 7ee5e7a90 “pkg/uprobetracer: support USDT trace points”).
Root Cause:
- Vector 1 (Out-of-bounds slice access): In
pkg/uprobetracer/usdt.go, `getUsdtInfo()` parses `stapsdt` notes. When a matching note is found (name == "stapsdt\0"andtype == 3), it reads three address fields from the note descriptor. For a 64-bit ELF (wordSize = 8), this requires `desc` to be at least 24 bytes. However, `desc` is allocated based onDescSize. A crafted ELF with `DescSize = 1` produces a 4-byte buffer, causing `desc[:8]` to panic. - Vector 2 (Unbounded memory allocation): `NameSize` and `DescSize` are used directly to allocate memory without any upper bound. A crafted ELF with `NameSize = 0xFFFFFFFF` attempts to allocate ~4 GiB of memory, triggering an OOM kill under cgroup limits.
- Vector 3 (Missing panic recovery): `getUsdtInfo()` calls `elf.NewFile()` directly without any panic recovery, unlike the `cilium/ebpf` library’s `SafeELFFile` wrapper which uses `recover()` around all `debug/elf` operations.
Fix: The fix (3 changes in `pkg/uprobetracer/usdt.go`):
- Bounds check on descriptor size: Validate `len(desc) >= 3wordSize` before accessing the address fields. Reject malformed notes with an error instead of panicking.
- Cap allocation sizes: Limit `NameSize` and `DescSize` to a reasonable maximum (1 MiB) before allocating memory, preventing DoS via memory exhaustion. There is no standard upper bound for ELF note fields; 1 MiB is a generous arbitrary cap — legitimate USDT notes are typically under 1 KB.
- Panic recovery: Wrap `getUsdtInfo()` with `defer/recover` to catch any panics from `debug/elf` on malformed input, converting them to errors.
References:
– `debug/elf` known issues: https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+debug%2Felf+in%3A
– `SafeELFFile` wrapper: https://github.com/cilium/ebpf/blob/main/internal/safeelf.go — uses `recover()` around all `debug/elf` operations for exactly this reason.
DailyCVE Form:
Platform: Inspektor Gadget
Version: v0.28.0 – v0.50.0
Vulnerability: DoS (Crash/OOM)
Severity: Low
date: 2026-03-12 (approx.)
Prediction: Patch in v0.50.1
What Undercode Say: Analytics
The vulnerability is triggered when a custom USDT gadget is deployed. The following command can be used to check if a gadget uses USDT probes:
Check if a gadget OCI image contains USDT sections skopeo inspect docker://<gadget-image> | grep -i usdt
To reproduce the out-of-bounds panic, an attacker can create a minimal ELF file with a malformed `stapsdt` note:
Create a malicious ELF with DescSize = 1 echo -en '\x7fELF...' > malicious.so (crafted ELF content)
To test for memory exhaustion, an attacker can set `NameSize = 0xFFFFFFFF` in the ELF note header:
Use a hex editor to modify NameSize in the .note.stapsdt section hexedit malicious.so
Exploit
An unprivileged container process can exploit this vulnerability by placing a crafted ELF binary at a path that a USDT gadget targets. For example, if a gadget is configured to attach to libc.so.6, the attacker can place a malicious `libc.so.6` in a location that the container’s ld cache resolves first.
Steps to exploit:
- Identify a target library that the USDT gadget attaches to (e.g., via
SEC("usdt/libc.so.6:...")). - Create a crafted ELF file with a malformed `stapsdt` note (either small `DescSize` for panic or large `NameSize` for OOM).
- Place the crafted ELF in a directory that is searched before the legitimate library (e.g., `/tmp` or a mounted volume).
- Wait for the gadget to attach, triggering the vulnerability.
Protection
- Upgrade: Update to Inspektor Gadget v0.50.1 or later, which includes the fix.
- Avoid USDT gadgets: Do not deploy custom gadgets that use `SEC(“usdt/…”)` sections unless necessary.
- Restrict container permissions: Limit the ability of containers to write to paths that may be targeted by USDT gadgets.
- Monitor OOM kills: Monitor for unexpected OOM kills of the Inspektor Gadget process, which may indicate an attempted exploit.
Impact
- Denial of Service: The Inspektor Gadget process can be crashed or OOM-killed, disrupting monitoring and data collection for the entire cluster.
- Limited scope: Only affects deployments with custom USDT gadgets; no shipped gadgets are vulnerable.
- No privilege escalation: The vulnerability does not allow code execution or privilege escalation; it is strictly a DoS.
- Mitigation: Upgrading to v0.50.1 fully mitigates the issue.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

