Skip to content

Commit 96f5277

Browse files
authored
Merge pull request #295 from coroot/java_tls
add Java TLS instrumentation via Java agent + eBPF uprobes
2 parents 20d3c43 + 579eef8 commit 96f5277

File tree

21 files changed

+663
-139
lines changed

21 files changed

+663
-139
lines changed

containers/container.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/coroot/coroot-node-agent/ebpftracer"
1313
"github.com/coroot/coroot-node-agent/ebpftracer/l7"
1414
"github.com/coroot/coroot-node-agent/flags"
15+
"github.com/coroot/coroot-node-agent/jvm"
1516
"github.com/coroot/coroot-node-agent/logs"
1617
"github.com/coroot/coroot-node-agent/node"
1718
"github.com/coroot/coroot-node-agent/pinger"
@@ -1262,6 +1263,18 @@ func (c *Container) attachTlsUprobes(tracer *ebpftracer.Tracer, pid uint32) {
12621263
}
12631264
p.rustlsUprobesChecked = true
12641265
}
1266+
if !p.javaTlsUprobesChecked {
1267+
p.javaTlsUprobesChecked = true
1268+
if jvm.IsJavaProcess(pid) {
1269+
if !*flags.EnableJavaTls {
1270+
klog.Infof("pid=%d: Java process detected, but Java TLS instrumentation is disabled (use --enable-java-tls to enable)", pid)
1271+
} else if nativeLibPath := jvm.EnsureTlsAgentLoaded(pid); nativeLibPath != "" {
1272+
if key := tracer.AttachJavaTlsUprobes(pid, nativeLibPath); key != nil {
1273+
p.uprobeKeys = append(p.uprobeKeys, *key)
1274+
}
1275+
}
1276+
}
1277+
}
12651278
}
12661279

12671280
func resolveFd(pid uint32, fd uint64) (mntId string, logPath string) {

containers/process.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type Process struct {
4343
goTlsUprobesChecked bool
4444
openSslUprobesChecked bool
4545
rustlsUprobesChecked bool
46+
javaTlsUprobesChecked bool
4647
pythonGilChecked bool
4748
nodejsChecked bool
4849
nodejsPrevStats *ebpftracer.NodejsStats

ebpftracer/ebpf.go

Lines changed: 10 additions & 10 deletions
Large diffs are not rendered by default.

ebpftracer/ebpf/ebpf.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,6 @@ struct trace_event_raw_sys_exit__stub {
5050
#include "l7/gotls.c"
5151
#include "l7/openssl.c"
5252
#include "l7/rustls.c"
53+
#include "l7/java_tls.c"
5354

5455
char _license[] SEC("license") = "GPL";

ebpftracer/ebpf/l7/java_tls.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
SEC("uprobe/java_tls_write_enter")
2+
int java_tls_write_enter(struct pt_regs *ctx) {
3+
__u64 tid = bpf_get_current_pid_tgid();
4+
__u32 pid = tid >> 32;
5+
6+
__u8 dummy = 1;
7+
bpf_map_update_elem(&java_tls_pids, &pid, &dummy, BPF_ANY);
8+
9+
struct ssl_args args = {};
10+
args.buf = (char *)PT_REGS_PARM1(ctx);
11+
args.size = PT_REGS_PARM2(ctx);
12+
args.is_read = 0;
13+
bpf_map_update_elem(&ssl_pending, &tid, &args, BPF_ANY);
14+
return 0;
15+
}
16+
17+
SEC("uprobe/java_tls_read_exit")
18+
int java_tls_read_exit(struct pt_regs *ctx) {
19+
__u64 pid_tgid = bpf_get_current_pid_tgid();
20+
21+
__u64 *fd_ptr = bpf_map_lookup_elem(&java_tls_last_read_fd, &pid_tgid);
22+
if (!fd_ptr) {
23+
return 0;
24+
}
25+
__u64 fd = *fd_ptr;
26+
bpf_map_delete_elem(&java_tls_last_read_fd, &pid_tgid);
27+
28+
char *buf = (char *)PT_REGS_PARM1(ctx);
29+
__s64 size = (__s64)PT_REGS_PARM2(ctx);
30+
31+
if (size <= 0) {
32+
return 0;
33+
}
34+
35+
__u32 pid = pid_tgid >> 32;
36+
__u64 id = pid_tgid | IS_TLS_READ_ID;
37+
trace_enter_read(id, pid, fd, buf, 0, 0);
38+
return trace_exit_read(ctx, id, pid, 1, size);
39+
}

ebpftracer/ebpf/l7/l7.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ struct {
122122
__uint(max_entries, 10240);
123123
} rustls_last_read_fd SEC(".maps");
124124

125+
struct {
126+
__uint(type, BPF_MAP_TYPE_LRU_HASH);
127+
__uint(key_size, sizeof(__u64));
128+
__uint(value_size, sizeof(__u64));
129+
__uint(max_entries, 10240);
130+
} java_tls_last_read_fd SEC(".maps");
131+
125132
struct {
126133
__uint(type, BPF_MAP_TYPE_LRU_HASH);
127134
__uint(key_size, sizeof(__u64));
@@ -377,6 +384,9 @@ int trace_enter_read(__u64 id, __u32 pid, __u64 fd, char *buf, __u64 *ret, __u64
377384
if (bpf_map_lookup_elem(&rustls_pids, &pid)) {
378385
bpf_map_update_elem(&rustls_last_read_fd, &id, &fd, BPF_ANY);
379386
}
387+
if (bpf_map_lookup_elem(&java_tls_pids, &pid)) {
388+
bpf_map_update_elem(&java_tls_last_read_fd, &id, &fd, BPF_ANY);
389+
}
380390

381391
struct connection_id cid = {};
382392
cid.pid = pid;

ebpftracer/ebpf/proc.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ struct {
2727
__uint(max_entries, 1024);
2828
} rustls_pids SEC(".maps");
2929

30+
struct {
31+
__uint(type, BPF_MAP_TYPE_LRU_HASH);
32+
__uint(key_size, sizeof(__u32));
33+
__uint(value_size, sizeof(__u8));
34+
__uint(max_entries, 1024);
35+
} java_tls_pids SEC(".maps");
36+
3037
struct trace_event_raw_task_newtask__stub {
3138
__u64 unused;
3239
#if defined(__CTX_EXTRA_PADDING)
@@ -74,6 +81,7 @@ int sched_process_exit(struct trace_event_raw_sched_process_template__stub *args
7481
bpf_map_delete_elem(&nodejs_prev_event_loop_iter, &pid);
7582
bpf_map_delete_elem(&nodejs_current_io_cb, &pid);
7683
bpf_map_delete_elem(&rustls_pids, &pid);
84+
bpf_map_delete_elem(&java_tls_pids, &pid);
7785

7886
struct proc_event e = {
7987
.type = EVENT_TYPE_PROCESS_EXIT,

0 commit comments

Comments
 (0)