|
| 1 | +// This file contains the code for the tracepoint on prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ...) |
| 2 | +// to detect when a process names an anonymous memory mapping "OTEL_CTX". |
| 3 | + |
| 4 | +#include "bpfdefs.h" |
| 5 | +#include "tracemgmt.h" |
| 6 | + |
| 7 | +#include "types.h" |
| 8 | + |
| 9 | +#ifndef TESTING_COREDUMP |
| 10 | + |
| 11 | + // prctl constants from include/uapi/linux/prctl.h |
| 12 | + #define PR_SET_VMA 0x53564d41 |
| 13 | + #define PR_SET_VMA_ANON_NAME 0 |
| 14 | + |
| 15 | +// See /sys/kernel/tracing/events/syscalls/sys_enter_prctl/format |
| 16 | +struct sys_enter_prctl_ctx { |
| 17 | + unsigned char skip[16]; // common fields (8) + __syscall_nr (4) + pad (4) |
| 18 | + unsigned long option; // prctl option |
| 19 | + unsigned long arg2; // sub-option (PR_SET_VMA_ANON_NAME for PR_SET_VMA) |
| 20 | + unsigned long arg3; // addr |
| 21 | + unsigned long arg4; // len |
| 22 | + unsigned long arg5; // name (user-space pointer) |
| 23 | +}; |
| 24 | + |
| 25 | +// tracepoint__sys_enter_prctl hooks prctl() calls to detect when a process |
| 26 | +// names an anonymous VMA "OTEL_CTX". This triggers a PID resynchronization |
| 27 | +// so the profiler can discover the newly published process context mapping. |
| 28 | +SEC("tracepoint/syscalls/sys_enter_prctl") |
| 29 | +int tracepoint__sys_enter_prctl(struct sys_enter_prctl_ctx *ctx) |
| 30 | +{ |
| 31 | + if (ctx->option != PR_SET_VMA || ctx->arg2 != PR_SET_VMA_ANON_NAME) { |
| 32 | + goto exit; |
| 33 | + } |
| 34 | + |
| 35 | + u64 pid_tgid = bpf_get_current_pid_tgid(); |
| 36 | + u32 pid = pid_tgid >> 32; |
| 37 | + |
| 38 | + if (!bpf_map_lookup_elem(&reported_pids, &pid) && !pid_information_exists(pid)) { |
| 39 | + // Only report PIDs that we explicitly track. This avoids sending kernel worker PIDs |
| 40 | + // to userspace. |
| 41 | + goto exit; |
| 42 | + } |
| 43 | + |
| 44 | + // Read the VMA name from user-space. We only need 9 bytes ("OTEL_CTX" + NUL). |
| 45 | + __attribute__((aligned(8))) char name[9] = {}; |
| 46 | + if (bpf_probe_read_user(name, sizeof(name), (void *)ctx->arg5)) { |
| 47 | + goto exit; |
| 48 | + } |
| 49 | + |
| 50 | + // Check for an exact "OTEL_CTX" match. We avoid bpf_strncmp (kernel 5.17+). |
| 51 | + // Instead, compare as a u64 for the 8 characters plus a byte check for the |
| 52 | + // NUL terminator. |
| 53 | + if (*(u64 *)name != *(u64 *)"OTEL_CTX" || name[8] != '\0') { |
| 54 | + goto exit; |
| 55 | + } |
| 56 | + |
| 57 | + if (report_pid(ctx, pid_tgid, RATELIMIT_ACTION_DEFAULT)) { |
| 58 | + increment_metric(metricID_NumPrctlSetVmaOtelCtx); |
| 59 | + } |
| 60 | + |
| 61 | +exit: |
| 62 | + return 0; |
| 63 | +} |
| 64 | + |
| 65 | +#endif |
0 commit comments