Skip to content

Commit

Permalink
fix the issue with retrieving the return value of the Read function i…
Browse files Browse the repository at this point in the history
…n the Golang TLS module. (#646)

* kern: fix the issue with retrieving the return value of the Read function in the Golang TLS module. improve #623

* kern: format code by new clang-format style.

* makefile: fix Recursive variable 'KERN_HEADERS' references itself (eventually).

Signed-off-by: CFC4N <[email protected]>

---------

Signed-off-by: CFC4N <[email protected]>
  • Loading branch information
cfc4n authored Oct 2, 2024
1 parent 716cd74 commit 6e2ac38
Show file tree
Hide file tree
Showing 21 changed files with 237 additions and 465 deletions.
28 changes: 9 additions & 19 deletions kern/bash_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,10 @@ int uretprobe_bash_readline(struct pt_regs *ctx) {
event.uid = uid;
event.type = BASH_EVENT_TYPE_READLINE;
// bpf_printk("!! uretprobe_bash_readline pid:%d",target_pid );
bpf_probe_read_user(&event.line, sizeof(event.line),
(void *)PT_REGS_RC(ctx));
bpf_probe_read_user(&event.line, sizeof(event.line), (void *)PT_REGS_RC(ctx));
bpf_get_current_comm(&event.comm, sizeof(event.comm));
bpf_map_update_elem(&events_t, &pid, &event, BPF_ANY);
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event,
sizeof(struct event));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(struct event));

return 0;
}
Expand All @@ -93,12 +91,10 @@ int uretprobe_bash_retval(struct pt_regs *ctx) {
#ifndef KERNEL_LESS_5_2
// if target_errno is 128 then we target all
if (target_errno != BASH_ERRNO_DEFAULT && target_errno != retval) {
if (event_p)
{
if (event_p) {
event_p->retval = BASH_ERRNO_DEFAULT;
event_p->type = BASH_EVENT_TYPE_RETVAL;
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event_p,
sizeof(struct event));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event_p, sizeof(struct event));
bpf_map_delete_elem(&events_t, &pid);
}
return 0;
Expand All @@ -110,13 +106,12 @@ int uretprobe_bash_retval(struct pt_regs *ctx) {
event_p->type = BASH_EVENT_TYPE_RETVAL;
// bpf_map_update_elem(&events_t, &pid, event_p, BPF_ANY);
bpf_map_delete_elem(&events_t, &pid);
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event_p,
sizeof(struct event));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event_p, sizeof(struct event));
}
return 0;
}

static __always_inline int send_bash_exit_event(struct pt_regs *ctx){
static __always_inline int send_bash_exit_event(struct pt_regs *ctx) {
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u64 current_uid_gid = bpf_get_current_uid_gid();
Expand All @@ -127,17 +122,12 @@ static __always_inline int send_bash_exit_event(struct pt_regs *ctx){
.uid = uid,
};
bpf_get_current_comm(&event.comm, sizeof(event.comm));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event,
sizeof(struct event));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(struct event));
return 0;
}

SEC("uprobe/exec_builtin")
int uprobe_exec_builtin(struct pt_regs *ctx){
return send_bash_exit_event(ctx);
}
int uprobe_exec_builtin(struct pt_regs *ctx) { return send_bash_exit_event(ctx); }

SEC("uprobe/exit_builtin")
int uprobe_exit_builtin(struct pt_regs *ctx){
return send_bash_exit_event(ctx);
}
int uprobe_exit_builtin(struct pt_regs *ctx) { return send_bash_exit_event(ctx); }
140 changes: 50 additions & 90 deletions kern/boringssl_masterkey.h

Large diffs are not rendered by default.

13 changes: 5 additions & 8 deletions kern/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,15 @@ const volatile u64 target_errno = BASH_ERRNO_DEFAULT;
#else
#endif


// fix 4.19.91-27.7.al7.x86_64/source/include/linux/kernel.h:140:9: warning: 'roundup' macro redefined
#ifndef roundup
#define roundup(x, y) ( \
{ \
typeof(y) __y = y; \
(((x) + (__y - 1)) / __y) * __y; \
} \
)
#define roundup(x, y) \
({ \
typeof(y) __y = y; \
(((x) + (__y - 1)) / __y) * __y; \
})
#endif


char __license[] SEC("license") = "Dual MIT/GPL";
__u32 _version SEC("version") = 0xFFFFFFFE;

Expand Down
28 changes: 9 additions & 19 deletions kern/gnutls_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,9 @@ struct {
* General helper functions
***********************************************************/

static __inline struct ssl_data_event_t* create_ssl_data_event(
u64 current_pid_tgid) {
static __inline struct ssl_data_event_t* create_ssl_data_event(u64 current_pid_tgid) {
u32 kZero = 0;
struct ssl_data_event_t* event =
bpf_map_lookup_elem(&data_buffer_heap, &kZero);
struct ssl_data_event_t* event = bpf_map_lookup_elem(&data_buffer_heap, &kZero);
if (event == NULL) {
return NULL;
}
Expand All @@ -86,8 +84,7 @@ static __inline struct ssl_data_event_t* create_ssl_data_event(
* BPF syscall processing functions
***********************************************************/

static int process_SSL_data(struct pt_regs* ctx, u64 id,
enum ssl_data_event_type type, const char* buf) {
static int process_SSL_data(struct pt_regs* ctx, u64 id, enum ssl_data_event_type type, const char* buf) {
int len = (int)PT_REGS_RC(ctx);
if (len < 0) {
return 0;
Expand All @@ -101,13 +98,10 @@ static int process_SSL_data(struct pt_regs* ctx, u64 id,
event->type = type;
// This is a max function, but it is written in such a way to keep older BPF
// verifiers happy.
event->data_len =
(len < MAX_DATA_SIZE_OPENSSL ? (len & (MAX_DATA_SIZE_OPENSSL - 1))
: MAX_DATA_SIZE_OPENSSL);
event->data_len = (len < MAX_DATA_SIZE_OPENSSL ? (len & (MAX_DATA_SIZE_OPENSSL - 1)) : MAX_DATA_SIZE_OPENSSL);
bpf_probe_read_user(event->data, event->data_len, buf);
bpf_get_current_comm(&event->comm, sizeof(event->comm));
bpf_perf_event_output(ctx, &gnutls_events, BPF_F_CURRENT_CPU, event,
sizeof(struct ssl_data_event_t));
bpf_perf_event_output(ctx, &gnutls_events, BPF_F_CURRENT_CPU, event, sizeof(struct ssl_data_event_t));
return 0;
}

Expand Down Expand Up @@ -139,8 +133,7 @@ int probe_entry_SSL_write(struct pt_regs* ctx) {
#endif

const char* buf = (const char*)PT_REGS_PARM2(ctx);
bpf_map_update_elem(&active_ssl_write_args_map, &current_pid_tgid, &buf,
BPF_ANY);
bpf_map_update_elem(&active_ssl_write_args_map, &current_pid_tgid, &buf, BPF_ANY);
return 0;
}

Expand All @@ -162,8 +155,7 @@ int probe_ret_SSL_write(struct pt_regs* ctx) {
}
#endif

const char** buf =
bpf_map_lookup_elem(&active_ssl_write_args_map, &current_pid_tgid);
const char** buf = bpf_map_lookup_elem(&active_ssl_write_args_map, &current_pid_tgid);
if (buf != NULL) {
process_SSL_data(ctx, current_pid_tgid, kSSLWrite, *buf);
}
Expand Down Expand Up @@ -195,8 +187,7 @@ int probe_entry_SSL_read(struct pt_regs* ctx) {
#endif

const char* buf = (const char*)PT_REGS_PARM2(ctx);
bpf_map_update_elem(&active_ssl_read_args_map, &current_pid_tgid, &buf,
BPF_ANY);
bpf_map_update_elem(&active_ssl_read_args_map, &current_pid_tgid, &buf, BPF_ANY);
return 0;
}

Expand All @@ -218,8 +209,7 @@ int probe_ret_SSL_read(struct pt_regs* ctx) {
}
#endif

const char** buf =
bpf_map_lookup_elem(&active_ssl_read_args_map, &current_pid_tgid);
const char** buf = bpf_map_lookup_elem(&active_ssl_read_args_map, &current_pid_tgid);
if (buf != NULL) {
process_SSL_data(ctx, current_pid_tgid, kSSLRead, *buf);
}
Expand Down
88 changes: 33 additions & 55 deletions kern/gotls_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,13 @@ static __always_inline struct go_tls_event *get_gotls_event() {
return bpf_map_lookup_elem(&gte_context, &id);
}

static __always_inline int gotls_write(struct pt_regs *ctx,
bool is_register_abi) {
static __always_inline int gotls_write(struct pt_regs *ctx, bool is_register_abi) {
s32 record_type, len;
const char *str;
void *record_type_ptr;
void *len_ptr;
record_type_ptr = (void *)go_get_argument(ctx, is_register_abi, 2);
bpf_probe_read_kernel(&record_type, sizeof(record_type),
(void *)&record_type_ptr);
bpf_probe_read_kernel(&record_type, sizeof(record_type), (void *)&record_type_ptr);
str = (void *)go_get_argument(ctx, is_register_abi, 3);
len_ptr = (void *)go_get_argument(ctx, is_register_abi, 4);
bpf_probe_read_kernel(&len, sizeof(len), (void *)&len_ptr);
Expand All @@ -120,16 +118,12 @@ static __always_inline int gotls_write(struct pt_regs *ctx,
}
len = len & 0xFFFF;
event->data_len = len;
int ret =
bpf_probe_read_user(&event->data, sizeof(event->data), (void *)str);
int ret = bpf_probe_read_user(&event->data, sizeof(event->data), (void *)str);
if (ret < 0) {
debug_bpf_printk(
"gotls_write bpf_probe_read_user_str failed, ret:%d, str:%d\n", ret,
str);
debug_bpf_printk("gotls_write bpf_probe_read_user_str failed, ret:%d, str:%d\n", ret, str);
return 0;
}
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event,
sizeof(struct go_tls_event));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event, sizeof(struct go_tls_event));
return 0;
}

Expand All @@ -143,27 +137,31 @@ int gotls_write_register(struct pt_regs *ctx) { return gotls_write(ctx, true); }
SEC("uprobe/gotls_write_stack")
int gotls_write_stack(struct pt_regs *ctx) { return gotls_write(ctx, false); }

// crypto/tls/conn.go
// func (c *Conn) Read(b []byte) (int, error)
static __always_inline int gotls_read(struct pt_regs *ctx,
bool is_register_abi) {
s32 record_type, len, ret_len;
static __always_inline int gotls_read(struct pt_regs *ctx, bool is_register_abi) {
s32 record_type, ret_len;
const char *str;
void *len_ptr, *ret_len_ptr;

// golang
// uretprobe的实现,为选择目标函数中,汇编指令的RET指令地址,即调用子函数的返回后的触发点,此时,此函数参数等地址存放在SP(stack
// Point)上,故使用stack方式读取
str = (void *)go_get_argument_by_stack(ctx, 2);
len_ptr = (void *)go_get_argument_by_stack(ctx, 3);
bpf_probe_read_kernel(&len, sizeof(len), (void *)&len_ptr);

// Read函数的返回值第一个是int类型,存放在栈里的顺序是5
ret_len_ptr = (void *)go_get_argument_by_stack(ctx, 5);
// str 是 Golang TLS *Conn.Read函数第一个参数b []byte的类型,对应runtime中

str = (void *)go_get_argument(ctx, false, 2);
if (is_register_abi) {
ret_len_ptr = (void *)go_get_argument(ctx, is_register_abi, 1);
} else {
// by stack, Read函数的返回值第一个是int类型,存放在栈里的顺序是5
ret_len_ptr = (void *)go_get_argument(ctx, is_register_abi, 5);
}
bpf_probe_read_kernel(&ret_len, sizeof(ret_len), (void *)&ret_len_ptr);
if (len <= 0) {
debug_bpf_printk("gotls_read event, str:%p ret_len_ptr:%d, ret_len:%d\n", str, ret_len_ptr, ret_len);
if (str <= 0) {
return 0;
}
if (ret_len <= 0 ) {
if (ret_len <= 0) {
return 0;
}

Expand All @@ -172,21 +170,14 @@ static __always_inline int gotls_read(struct pt_regs *ctx,
return 0;
}

debug_bpf_printk("gotls_read event, str addr:%p, len:%d\n", len_ptr, len);
debug_bpf_printk("gotls_read event, str ret_len_ptr:%d, ret_len:%d\n",
ret_len_ptr, ret_len);
event->data_len = len;
event->data_len = ret_len;
event->event_type = GOTLS_EVENT_TYPE_READ;
int ret =
bpf_probe_read_user(&event->data, sizeof(event->data), (void *)str);
int ret = bpf_probe_read_user(&event->data, sizeof(event->data), (void *)str);
if (ret < 0) {
debug_bpf_printk(
"gotls_text bpf_probe_read_user_str failed, ret:%d, str:%d\n", ret,
str);
debug_bpf_printk("gotls_text bpf_probe_read_user_str failed, ret:%d, str:%d\n", ret, str);
return 0;
}
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event,
sizeof(struct go_tls_event));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event, sizeof(struct go_tls_event));
return 0;
}

Expand All @@ -203,8 +194,7 @@ int gotls_read_stack(struct pt_regs *ctx) { return gotls_read(ctx, false); }
* crypto/tls/common.go
* func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error
*/
static __always_inline int gotls_mastersecret(struct pt_regs *ctx,
bool is_register_abi) {
static __always_inline int gotls_mastersecret(struct pt_regs *ctx, bool is_register_abi) {
// const char *label, *clientrandom, *secret;
void *lab_ptr, *cr_ptr, *secret_ptr;
void *lab_len_ptr, *cr_len_ptr, *secret_len_ptr;
Expand All @@ -230,8 +220,7 @@ static __always_inline int gotls_mastersecret(struct pt_regs *ctx,

bpf_probe_read_kernel(&lab_len, sizeof(lab_len), (void *)&lab_len_ptr);
bpf_probe_read_kernel(&cr_len, sizeof(lab_len), (void *)&cr_len_ptr);
bpf_probe_read_kernel(&secret_len, sizeof(lab_len),
(void *)&secret_len_ptr);
bpf_probe_read_kernel(&secret_len, sizeof(lab_len), (void *)&secret_len_ptr);

if (lab_len <= 0 || cr_len <= 0 || secret_len <= 0) {
return 0;
Expand All @@ -246,9 +235,7 @@ static __always_inline int gotls_mastersecret(struct pt_regs *ctx,
mastersecret_gotls.labellen = lab_len;
mastersecret_gotls.client_random_len = cr_len;
mastersecret_gotls.secret_len = secret_len;
int ret = bpf_probe_read_user_str(&mastersecret_gotls.label,
sizeof(mastersecret_gotls.label),
(void *)lab_ptr);
int ret = bpf_probe_read_user_str(&mastersecret_gotls.label, sizeof(mastersecret_gotls.label), (void *)lab_ptr);
if (ret < 0) {
debug_bpf_printk(
"gotls_mastersecret read mastersecret label failed, ret:%d, "
Expand All @@ -257,10 +244,8 @@ static __always_inline int gotls_mastersecret(struct pt_regs *ctx,
return 0;
}

debug_bpf_printk("gotls_mastersecret read mastersecret label:%s\n",
mastersecret_gotls.label);
ret = bpf_probe_read_user_str(&mastersecret_gotls.client_random,
sizeof(mastersecret_gotls.client_random),
debug_bpf_printk("gotls_mastersecret read mastersecret label:%s\n", mastersecret_gotls.label);
ret = bpf_probe_read_user_str(&mastersecret_gotls.client_random, sizeof(mastersecret_gotls.client_random),
(void *)cr_ptr);
if (ret < 0) {
debug_bpf_printk(
Expand All @@ -270,9 +255,7 @@ static __always_inline int gotls_mastersecret(struct pt_regs *ctx,
return 0;
}

ret = bpf_probe_read_user_str(&mastersecret_gotls.secret_,
sizeof(mastersecret_gotls.secret_),
(void *)secret_ptr);
ret = bpf_probe_read_user_str(&mastersecret_gotls.secret_, sizeof(mastersecret_gotls.secret_), (void *)secret_ptr);
if (ret < 0) {
debug_bpf_printk(
"gotls_mastersecret read mastersecret secret_ failed, ret:%d, "
Expand All @@ -281,18 +264,13 @@ static __always_inline int gotls_mastersecret(struct pt_regs *ctx,
return 0;
}

bpf_perf_event_output(ctx, &mastersecret_go_events, BPF_F_CURRENT_CPU,
&mastersecret_gotls,
bpf_perf_event_output(ctx, &mastersecret_go_events, BPF_F_CURRENT_CPU, &mastersecret_gotls,
sizeof(struct mastersecret_gotls_t));
return 0;
}

SEC("uprobe/gotls_mastersecret_register")
int gotls_mastersecret_register(struct pt_regs *ctx) {
return gotls_mastersecret(ctx, true);
}
int gotls_mastersecret_register(struct pt_regs *ctx) { return gotls_mastersecret(ctx, true); }

SEC("uprobe/gotls_mastersecret_stack")
int gotls_mastersecret_stack(struct pt_regs *ctx) {
return gotls_mastersecret(ctx, false);
}
int gotls_mastersecret_stack(struct pt_regs *ctx) { return gotls_mastersecret(ctx, false); }
12 changes: 4 additions & 8 deletions kern/mysqld_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ int mysql56_query(struct pt_regs *ctx) {
data.alllen = len; // origin query sql length
data.timestamp = bpf_ktime_get_ns();
data.retval = -1;
len = (len < MAX_DATA_SIZE_MYSQL ? (len & (MAX_DATA_SIZE_MYSQL - 1))
: MAX_DATA_SIZE_MYSQL);
len = (len < MAX_DATA_SIZE_MYSQL ? (len & (MAX_DATA_SIZE_MYSQL - 1)) : MAX_DATA_SIZE_MYSQL);
data.len = len; // only process id
bpf_get_current_comm(&data.comm, sizeof(data.comm));

Expand Down Expand Up @@ -137,8 +136,7 @@ int mysql56_query_return(struct pt_regs *ctx) {
debug_bpf_printk("mysql query:%s\n", data->query);
data->retval = command_return;
debug_bpf_printk("mysql query return :%d\n", command_return);
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, data,
sizeof(struct data_t));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, data, sizeof(struct data_t));
return 0;
}

Expand Down Expand Up @@ -217,8 +215,7 @@ int mysql57_query(struct pt_regs *ctx) {
bpf_probe_read_user(&data.query, sizeof(data.query), query.query);
bpf_probe_read_user(&data.alllen, sizeof(data.alllen), &query.length);
len = data.alllen;
len = (len < MAX_DATA_SIZE_MYSQL ? (len & (MAX_DATA_SIZE_MYSQL - 1))
: MAX_DATA_SIZE_MYSQL);
len = (len < MAX_DATA_SIZE_MYSQL ? (len & (MAX_DATA_SIZE_MYSQL - 1)) : MAX_DATA_SIZE_MYSQL);
data.len = len;
bpf_get_current_comm(&data.comm, sizeof(data.comm));

Expand Down Expand Up @@ -263,8 +260,7 @@ int mysql57_query_return(struct pt_regs *ctx) {
} else {
data->retval = command_return;
}
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, data,
sizeof(struct data_t));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, data, sizeof(struct data_t));

return 0;
}
Loading

0 comments on commit 6e2ac38

Please sign in to comment.