Skip to content

security: fix BPF C code injection in 43 Python tools + unsafe directory perms#5465

Open
SleuthCo wants to merge 4 commits intoiovisor:masterfrom
SleuthCo:security/fix-bpf-code-injection-and-dir-perms
Open

security: fix BPF C code injection in 43 Python tools + unsafe directory perms#5465
SleuthCo wants to merge 4 commits intoiovisor:masterfrom
SleuthCo:security/fix-bpf-code-injection-and-dir-perms

Conversation

@SleuthCo
Copy link
Copy Markdown

Summary

  • BCC-2026-001 (High): 43 Python-based BCC tools accept CLI arguments (PIDs, TIDs, UIDs, signal numbers) as unvalidated strings and interpolate them directly into BPF C source code via bpf_text.replace(). A local attacker can inject arbitrary C code into kernel-loaded BPF programs. Fixed by adding type=int (or a custom positive_int_list validator) to all vulnerable argparse arguments.
  • BCC-2026-002 (Medium): bpf_module.cc creates /var/tmp/bcc/ with mode 0777, enabling symlink attacks for arbitrary file overwrites as root. Fixed by using mode 0700, adding O_NOFOLLOW, and checking write() return values.
  • Adds shared input validators (positive_int, positive_nonzero_int, positive_int_list) to bcc.utils
  • Adds comprehensive test coverage (unit + integration tests for all 43 tools)
  • Adds SECURITY.md with reporting policy and advisories

Commits (4)

  1. security: add shared input validators to bcc.utilspositive_int, positive_nonzero_int, positive_int_list argparse type validators
  2. security: add type=int to 43 Python tools to prevent BPF code injection — fixes 29 tools in tools/ and 14 in tools/old/
  3. security: fix world-writable directory and unsafe file operationsbpf_module.cc hardening (0700, O_NOFOLLOW, write checks)
  4. security: add tests and security advisory for BPF injection fixes — test_utils.py, test_tool_args_validation.py (~60 test methods), SECURITY.md

Affected tools

tcptop, tcpconnlat, tcplife, tcpaccept, tcpconnect, capable, cpudist, statsnoop, filelife, filegone, compactsnoop, vfsstat, ext4dist, shmsnoop, sofdsnoop, numasched, klockstat, opensnoop, drsnoop, bindsnoop, nfsslower, xfsslower, zfsslower, ext4slower, btrfsslower, f2fsslower, execsnoop, killsnoop, ttysnoop, and 14 tools in tools/old/.

Test plan

  • python -m pytest tests/python/test_utils.py — unit tests for validators
  • python -m pytest tests/python/test_tool_args_validation.py — integration tests that all 43 tools reject injection payloads (does not require root)
  • Manual: verify sudo tcptop -p "1; } evil(); if(0" is rejected at argparse with error: argument -p: invalid int value
  • Manual: verify /var/tmp/bcc/ directories are created with 0700 not 0777

🤖 Generated with Claude Code

SleuthCo and others added 4 commits February 10, 2026 15:28
Add positive_int, positive_nonzero_int, and positive_int_list argparse
type validators for secure input validation of CLI arguments that get
interpolated into BPF C source code. These prevent code injection via
malicious non-numeric argument values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CLI arguments (PIDs, TIDs, UIDs, signals) were passed as raw strings
and interpolated directly into BPF C source via bpf_text.replace().
An attacker could inject arbitrary C code into kernel BPF programs.

Fix: add type=int (or type=positive_int_list for killsnoop --signal)
to all vulnerable argparse arguments. This ensures argparse rejects
non-numeric input before it reaches string interpolation.

Special cases:
- execsnoop.py: --max-args default "20" -> 20, replacement uses str()
- killsnoop.py: --signal uses positive_int_list validator, removes
  manual .split(',') parsing
- ttysnoop.py: --datasize/--datacount defaults "256"/"16" -> 256/16,
  replacements use str()

Affects 29 tools in tools/ and 14 tools in tools/old/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change mkdir() mode from 0777 to 0700 for BCC_PROG_TAG_DIR and
  per-program subdirectories to prevent local users from tampering
  with cached BPF program sources
- Add O_NOFOLLOW to all open() calls to prevent symlink attacks
- Check write() return values to detect I/O errors

This prevents local privilege escalation via symlink attacks on the
world-writable /var/tmp/bcc directory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add comprehensive test coverage for the security fixes:

- tests/python/test_utils.py: Unit tests for positive_int,
  positive_nonzero_int, and positive_int_list validators
- tests/python/test_tool_args_validation.py: Integration tests that
  verify all 43 fixed tools reject malicious non-integer input via
  subprocess invocation (~60 test methods). Does not require root.
- SECURITY.md: Security reporting policy and advisories for
  BCC-2026-001 (BPF code injection) and BCC-2026-002 (world-writable
  directory permissions)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@SleuthCo
Copy link
Copy Markdown
Author

Friendly ping — this PR fixes a BPF C code injection vulnerability across 43 Python tools where unsanitized user input (PIDs, device names, function names, etc.) is interpolated directly into BPF C source before compilation. The fix uses a consistent allowlist-based validation pattern.

Happy to address any feedback or split the PR if that's easier to review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant