Feat/container uprobe support#39
Open
yoloyyh wants to merge 9 commits intoeunomia-bpf:masterfrom
Open
Conversation
added 2 commits
April 8, 2026 11:50
- Add container_info.h: shared helpers for ns_pid and container_id extraction from /proc/<pid>/status (NSpid) and /proc/<pid>/cgroup (docker ID) - sslsniff.c: add container info (ns_pid, container_id) to SSL event JSON output Container SSL events now include full metadata for UI display - process_new.c: add container info to EXEC, EXIT, FILE_OPEN events Container processes show namespace PID and container short ID - bpf_common.h: fix format_ipv4_port BPF verifier back-edge error Unroll loops for kernel 5.15 compatibility (no bounded loop support) - process.rs: fix panic on CLOCK_SYNC events from process_new Use filter_map to skip metadata events without pid field - BlockAdapters.tsx: fix SSL 0 BYTES display bug Map sslsniff field names (buf_size/function/data) correctly Show container tags (container_id emoji) in SSL/process/file events Display actual SSL data preview in fold content Verified: container python process (PID 3148274, ns_pid 36) in agentsight-test container correctly shows all event types with container metadata and full SSL request/response data.
The HTTP parser analyzer transforms raw SSL events, changing the source from 'ssl' to 'http_parser' and replacing sslsniff fields (buf_size, data, function) with HTTP-parsed fields (body, headers, method, total_size, message_type, first_line, etc.). adaptSSLEvent now detects http_parser events via original_source and correctly extracts: - Size from total_size/content_length instead of buf_size - Direction from message_type (request/response) instead of function - Fold content from first_line instead of raw data preview - Expanded content from body (with JSON pretty-print) instead of data Also adds HTTP/TLS source tag to distinguish event origin.
bpf_probe_read_user_str stops at the first null byte, but argv entries in process memory are separated by null bytes (e.g. 'chmod\0+x\0/path\0'). This caused full_command to only contain argv[0] (e.g. 'chmod') without any arguments. Switch to bpf_probe_read_user which reads raw bytes for the entire arg_start..arg_end range, then replace internal null separators with spaces to produce the complete command line. Before: full_command='chmod' After: full_command='chmod +x /tmp/test_file.txt'
Feat/container uprobe support
Some kernel versions cannot track the range of unsigned long through an if-clamp alone. Adding 'arg_len &= (MAX_COMMAND_LEN - 1)' gives the verifier a provable upper bound on the read size, fixing -EACCES load failures on stricter kernels.
fix(bpf): add bitmask constraint for verifier on bpf_probe_read_user
The BPF verifier on kernel 5.15 (1M instruction limit) rejects programs
with loops iterating over MAX_COMMAND_LEN (255) bytes due to state
explosion. Two loops * 255 iterations with conditional branches easily
exceeded 1,000,000 instructions.
Solution: eliminate ALL loops from the BPF program. BPF now only:
1. Reads raw argv bytes with bpf_probe_read_user (constant size)
2. Stores actual arg_len in e->exit_code (unused for exec events)
3. Submits the raw event to userspace
Userspace postprocess_full_command() in process_utils.h then:
1. Copies to a local buffer (ringbuf memory is mmap read-only)
2. Trims to arg_len to prevent environment variable leakage
3. Replaces \0 separators between argv entries with spaces
This approach:
- Stays well under the BPF verifier instruction limit on all kernels
- Avoids SIGSEGV from writing to read-only ringbuf consumer memory
- Prevents environment variables from leaking into full_command
- Captures complete argv (e.g., "chmod +x /tmp/file") instead of
just argv[0]
Tested on 5.15.120.bsk.3-amd64: BPF loads and runs successfully.
30edc73 to
c25ee54
Compare
Signed-off-by: yoloyyh <57630263+yoloyyh@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds container-aware metadata propagation (namespace PID + container ID) through the eBPF → collector → frontend pipeline, and improves SSL event rendering to support both raw TLS events and HTTP-parser-transformed events.
Changes:
- Introduces userspace helpers for extracting/printing
ns_pidandcontainer_id, and integrates them into process/file/SSL event JSON output. - Adds dynamic uprobe discovery/attachment for container-specific
libssl.sopaths and cleans up links on exit. - Updates collector/frontend to gracefully handle metadata events and to render HTTP-parsed SSL events correctly, including container tags.
Reviewed changes
Copilot reviewed 11 out of 13 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
bpf/container_info.h |
New userspace helper for ns_pid/container_id extraction and JSON printing. |
bpf/container_utils.h |
New /proc-based lib discovery + dynamic bpf_link lifecycle management for container uprobes. |
bpf/sslsniff.c |
Uses new container helpers, adds container lib path resolution/scan, prints container fields in JSON, and destroys dynamic links at cleanup. |
bpf/process_new.c |
Prints container fields for relevant event types; uses userspace post-processing for full command line. |
bpf/process_new.bpf.c |
Captures argv block more completely by switching from _str to raw user-memory reads; stores arg length for userspace trimming. |
bpf/process.c |
Uses userspace post-processing for full command line formatting. |
bpf/process.bpf.c |
Same argv capture approach as process_new.bpf.c. |
bpf/process_utils.h |
Adds userspace command-line post-processing helper. |
bpf/process_ext/bpf_common.h |
Fully unrolls IPv4:port formatting to avoid verifier back-edge issues on kernel 5.15. |
collector/src/framework/runners/process.rs |
Skips metadata events by switching to filter_map instead of panicking on missing fields. |
frontend/src/components/process-tree/BlockAdapters.tsx |
Updates SSL adapter to handle both raw TLS and HTTP-parsed events; adds container tags + ns_pid display. |
.gitignore |
Ignores node_modules/. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- container_info.h: add SPDX license identifier - container_info.h: add #include <sys/types.h> for pid_t - container_utils.h: fix strncpy NUL-termination (PATH_MAX-1 + explicit NUL) - container_utils.h: replace 256KB stack array with heap allocation - sslsniff.c: use libbpf_get_error() instead of NULL check for ERR_PTR - sslsniff.c: gate container uprobe debug fprintf behind verbose flag - process_new.c: move #include "container_info.h" to top include block - process.rs: use current time instead of 0 when timestamp missing - BlockAdapters.tsx: truncate before regex replace for performance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add container-aware metadata (namespace PID and container ID) to all eBPF event types (process, file, SSL/TLS) and fix the frontend to correctly display HTTP-parsed SSL events.
Background: When AgentSight traces processes running inside Docker containers, the host PID is meaningless to the user — they need the container-internal (namespace) PID and the container ID to correlate events. This PR adds container metadata extraction at the BPF userspace layer and propagates it through the entire pipeline to the frontend UI.
Key changes:
bpf/container_info.h(new): Shared helper library for container metadata extractionget_ns_pid(): Parses/proc/<pid>/statusNSpid line to get the innermost namespace PIDget_container_id(): Parses/proc/<pid>/cgroupto extract the 12-char Docker container IDprint_container_fields(): Appendsns_pidandcontainer_idJSON fields to event outputbpf/container_utils.h(new): Dynamic uprobe management for container SSL tracinglibssl.soinside container processes at runtimebpf/process_new.c: Integratedcontainer_info.h— EXEC, EXIT, and FILE_OPEN events now includens_pidandcontainer_idbpf/sslsniff.c: Integratedcontainer_info.h— SSL_read/SSL_write events now include container metadatabpf/process_ext/bpf_common.h: Fixed BPF verifier back-edge error on kernel 5.15 by fully unrolling loops informat_ipv4_port()(kernel 5.15 doesn't support bounded loops)collector/src/framework/runners/process.rs: Fixed panic onCLOCK_SYNCevents fromprocess_newby switching from.map()withpanic!to.filter_map()that gracefully skips metadata eventsfrontend/.../BlockAdapters.tsx:buf_size/data/function) and http_parser-transformed events (body/headers/method/total_size/message_type)Type of change
How Has This Been Tested?
docker exec) making HTTPS requests tohttpbin.org, verified all event types (EXEC, EXIT, FILE_OPEN, SSL request/response) contain correctns_pidandcontainer_idfields intrace.logsource=http_parser) now render with correct HTTP method, status code, body content, and size instead of showing empty/0 BYTESprocess_newBPF program loads successfully on kernel 5.15 after loop unrolling fixTest Configuration:
Checklist