|
@@ -79,10 +79,10 @@ struct
|
|
|
// cw_inject_header_half: 准备 header 注入数据,保存到 bucket_map_value,由后续的 go_update_header 完成实际注入
|
|
// cw_inject_header_half: 准备 header 注入数据,保存到 bucket_map_value,由后续的 go_update_header 完成实际注入
|
|
|
// 支持 Go 1.24+ Swiss Tables 和旧版本的 hmap
|
|
// 支持 Go 1.24+ Swiss Tables 和旧版本的 hmap
|
|
|
static __always_inline long cw_inject_header_half(void* headers_ptr, char * header_str,struct ebpf_proc_info* proc_info) {
|
|
static __always_inline long cw_inject_header_half(void* headers_ptr, char * header_str,struct ebpf_proc_info* proc_info) {
|
|
|
- bpf_printk("cw_inject_header_half: START");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: START");
|
|
|
|
|
|
|
|
if (!proc_info) {
|
|
if (!proc_info) {
|
|
|
- bpf_printk("cw_inject_header_half: proc_info is NULL");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: proc_info is NULL");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -90,26 +90,26 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
u32 map_id = CLIENT_MAP_KEY;
|
|
u32 map_id = CLIENT_MAP_KEY;
|
|
|
struct map_bucket *bucket_map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
|
|
struct map_bucket *bucket_map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
|
|
|
if (!bucket_map_value) {
|
|
if (!bucket_map_value) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to get bucket_map_value");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to get bucket_map_value");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
__builtin_memset(bucket_map_value, 0, sizeof(struct map_bucket));
|
|
__builtin_memset(bucket_map_value, 0, sizeof(struct map_bucket));
|
|
|
|
|
|
|
|
// Check if Go version >= 1.24 (Swiss Tables)
|
|
// Check if Go version >= 1.24 (Swiss Tables)
|
|
|
if (proc_info->version >= GO_VERSION(1, 24, 0)) {
|
|
if (proc_info->version >= GO_VERSION(1, 24, 0)) {
|
|
|
- bpf_printk("cw_inject_header_half: Go 1.24+ Swiss Tables detected");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Go 1.24+ Swiss Tables detected");
|
|
|
|
|
|
|
|
// Read used count (first field in maps.Map)
|
|
// Read used count (first field in maps.Map)
|
|
|
u64 used = 0;
|
|
u64 used = 0;
|
|
|
long res = bpf_probe_read_user(&used, sizeof(used), headers_ptr);
|
|
long res = bpf_probe_read_user(&used, sizeof(used), headers_ptr);
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to read used count, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to read used count, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("cw_inject_header_half: used=%llu", used);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: used=%llu", used);
|
|
|
|
|
|
|
|
if (used >= 8) {
|
|
if (used >= 8) {
|
|
|
- bpf_printk("cw_inject_header_half: Map is full (used=%llu)", used);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Map is full (used=%llu)", used);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -117,10 +117,10 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
s32 dirLen = 0;
|
|
s32 dirLen = 0;
|
|
|
res = bpf_probe_read_user(&dirLen, sizeof(dirLen), (void*)(headers_ptr + 24));
|
|
res = bpf_probe_read_user(&dirLen, sizeof(dirLen), (void*)(headers_ptr + 24));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to read dirLen, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to read dirLen, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("cw_inject_header_half: dirLen=%d", dirLen);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: dirLen=%d", dirLen);
|
|
|
|
|
|
|
|
void *group_ptr = NULL;
|
|
void *group_ptr = NULL;
|
|
|
|
|
|
|
@@ -129,7 +129,7 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
void *dirPtr_ptr = (void*)(headers_ptr + proc_info->buckets_ptr_pos);
|
|
void *dirPtr_ptr = (void*)(headers_ptr + proc_info->buckets_ptr_pos);
|
|
|
res = bpf_probe_read_user(&group_ptr, sizeof(group_ptr), dirPtr_ptr);
|
|
res = bpf_probe_read_user(&group_ptr, sizeof(group_ptr), dirPtr_ptr);
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to read dirPtr, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to read dirPtr, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -142,7 +142,7 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
u64 empty_ctrls = 0x8080808080808080ULL;
|
|
u64 empty_ctrls = 0x8080808080808080ULL;
|
|
|
group_ptr = cw_write_target_data(&empty_ctrls, sizeof(empty_ctrls), proc_info);
|
|
group_ptr = cw_write_target_data(&empty_ctrls, sizeof(empty_ctrls), proc_info);
|
|
|
if (group_ptr == NULL) {
|
|
if (group_ptr == NULL) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to allocate group");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to allocate group");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -153,25 +153,25 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
void *chunk_ptr = (void*)((u64)group_ptr + (i * 8));
|
|
void *chunk_ptr = (void*)((u64)group_ptr + (i * 8));
|
|
|
res = bpf_probe_write_user(chunk_ptr, &zero, sizeof(zero));
|
|
res = bpf_probe_write_user(chunk_ptr, &zero, sizeof(zero));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to init chunk %d, res=%ld", i, res);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to init chunk %d, res=%ld", i, res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- bpf_printk("cw_inject_header_half: Allocated new group at %p", group_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Allocated new group at %p", group_ptr);
|
|
|
|
|
|
|
|
// Update dirPtr in the map to point to the new group
|
|
// Update dirPtr in the map to point to the new group
|
|
|
res = bpf_probe_write_user(dirPtr_ptr, &group_ptr, sizeof(group_ptr));
|
|
res = bpf_probe_write_user(dirPtr_ptr, &group_ptr, sizeof(group_ptr));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to update dirPtr, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to update dirPtr, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("cw_inject_header_half: Updated dirPtr");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Updated dirPtr");
|
|
|
} else {
|
|
} else {
|
|
|
- bpf_printk("cw_inject_header_half: group_ptr=%p (existing)", group_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: group_ptr=%p (existing)", group_ptr);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- bpf_printk("cw_inject_header_half: Large map (dirLen=%d) not supported yet", dirLen);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Large map (dirLen=%d) not supported yet", dirLen);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -179,10 +179,10 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
u64 ctrls = 0;
|
|
u64 ctrls = 0;
|
|
|
res = bpf_probe_read_user(&ctrls, sizeof(ctrls), group_ptr);
|
|
res = bpf_probe_read_user(&ctrls, sizeof(ctrls), group_ptr);
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to read control word, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to read control word, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("cw_inject_header_half: ctrls=0x%llx", ctrls);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: ctrls=0x%llx", ctrls);
|
|
|
|
|
|
|
|
// Find first empty slot (ctrl byte = 0x80)
|
|
// Find first empty slot (ctrl byte = 0x80)
|
|
|
u8 empty_ctrl = 0x80;
|
|
u8 empty_ctrl = 0x80;
|
|
@@ -194,13 +194,13 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
if (ctrl_byte == empty_ctrl) {
|
|
if (ctrl_byte == empty_ctrl) {
|
|
|
slot_idx = i;
|
|
slot_idx = i;
|
|
|
found_empty = true;
|
|
found_empty = true;
|
|
|
- bpf_printk("cw_inject_header_half: Found empty slot at index %d", i);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Found empty slot at index %d", i);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!found_empty) {
|
|
if (!found_empty) {
|
|
|
- bpf_printk("cw_inject_header_half: No empty slot found (ctrls=0x%llx)", ctrls);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: No empty slot found (ctrls=0x%llx)", ctrls);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -217,7 +217,7 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
__builtin_memcpy(bucket_map_value->header_str, header_str, CW_HEADER_VAL_LENGTH);
|
|
__builtin_memcpy(bucket_map_value->header_str, header_str, CW_HEADER_VAL_LENGTH);
|
|
|
|
|
|
|
|
// Quick verification: check first 3 bytes
|
|
// Quick verification: check first 3 bytes
|
|
|
- bpf_printk("cw_inject_header_half: copied[0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: copied[0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
(u8)bucket_map_value->header_str[0],
|
|
(u8)bucket_map_value->header_str[0],
|
|
|
(u8)bucket_map_value->header_str[1],
|
|
(u8)bucket_map_value->header_str[1],
|
|
|
(u8)bucket_map_value->header_str[2]);
|
|
(u8)bucket_map_value->header_str[2]);
|
|
@@ -226,23 +226,23 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
// Actually, we can use a different approach - store dirLen in bucket_index
|
|
// Actually, we can use a different approach - store dirLen in bucket_index
|
|
|
// For now, we'll use bucket_index as slot_idx (0-7), and check version in go_update_header
|
|
// For now, we'll use bucket_index as slot_idx (0-7), and check version in go_update_header
|
|
|
|
|
|
|
|
- bpf_printk("cw_inject_header_half: SUCCESS - saved info for Swiss Tables, slot_idx=%d", slot_idx);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: SUCCESS - saved info for Swiss Tables, slot_idx=%d", slot_idx);
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Old implementation for Go < 1.24
|
|
// Old implementation for Go < 1.24
|
|
|
- bpf_printk("cw_inject_header_half: Using old hmap implementation");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Using old hmap implementation");
|
|
|
|
|
|
|
|
// Read the key-value count - this field must be the first one in the hmap struct
|
|
// Read the key-value count - this field must be the first one in the hmap struct
|
|
|
u64 curr_keyvalue_count = 0;
|
|
u64 curr_keyvalue_count = 0;
|
|
|
long res = bpf_probe_read_user(&curr_keyvalue_count, sizeof(curr_keyvalue_count), headers_ptr);
|
|
long res = bpf_probe_read_user(&curr_keyvalue_count, sizeof(curr_keyvalue_count), headers_ptr);
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("cw_inject_header_half: Couldn't read map key-value count, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Couldn't read map key-value count, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (curr_keyvalue_count >= 8) {
|
|
if (curr_keyvalue_count >= 8) {
|
|
|
- bpf_printk("cw_inject_header_half: Map size is bigger than 8, skipping");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Map size is bigger than 8, skipping");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -253,13 +253,13 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
// No key-value pairs in the Go map, need to "allocate" memory for the user
|
|
// No key-value pairs in the Go map, need to "allocate" memory for the user
|
|
|
bucket_ptr = cw_write_target_data(bucket_map_value, sizeof(struct map_bucket), proc_info);
|
|
bucket_ptr = cw_write_target_data(bucket_map_value, sizeof(struct map_bucket), proc_info);
|
|
|
if (bucket_ptr == NULL) {
|
|
if (bucket_ptr == NULL) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to write bucket to user");
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to write bucket to user");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
// Update the buckets pointer in the hmap struct to point to newly allocated bucket
|
|
// Update the buckets pointer in the hmap struct to point to newly allocated bucket
|
|
|
res = bpf_probe_write_user(buckets_ptr_ptr, &bucket_ptr, sizeof(bucket_ptr));
|
|
res = bpf_probe_write_user(buckets_ptr_ptr, &bucket_ptr, sizeof(bucket_ptr));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("cw_inject_header_half: Failed to update bucket pointer, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: Failed to update bucket pointer, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -278,7 +278,7 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
bucket_map_value->bucket_index = bucket_index;
|
|
bucket_map_value->bucket_index = bucket_index;
|
|
|
bpf_probe_read(bucket_map_value->header_str, sizeof(bucket_map_value->header_str), header_str);
|
|
bpf_probe_read(bucket_map_value->header_str, sizeof(bucket_map_value->header_str), header_str);
|
|
|
|
|
|
|
|
- bpf_printk("cw_inject_header_half: SUCCESS - saved info for old hmap, bucket_index=%d", bucket_index);
|
|
|
|
|
|
|
+ cw_bpf_debug("cw_inject_header_half: SUCCESS - saved info for old hmap, bucket_index=%d", bucket_index);
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -286,7 +286,7 @@ static __always_inline long cw_inject_header_half(void* headers_ptr, char * head
|
|
|
// func net/http/transport.roundTrip(req *Request) (*Response, error)
|
|
// func net/http/transport.roundTrip(req *Request) (*Response, error)
|
|
|
SEC("uprobe/Transport_roundTrip")
|
|
SEC("uprobe/Transport_roundTrip")
|
|
|
int uprobe_Transport_roundTrip(struct pt_regs *ctx) {
|
|
int uprobe_Transport_roundTrip(struct pt_regs *ctx) {
|
|
|
- bpf_printk("--------[Uprobe HTTP Client] start %llu",get_current_goroutine());
|
|
|
|
|
|
|
+ cw_bpf_debug("--------[Uprobe HTTP Client] start %llu",get_current_goroutine());
|
|
|
|
|
|
|
|
u64 request_pos = 2;
|
|
u64 request_pos = 2;
|
|
|
void *req_ptr = get_argument(ctx, request_pos);
|
|
void *req_ptr = get_argument(ctx, request_pos);
|
|
@@ -428,14 +428,14 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) {
|
|
|
span_context_to_cw_string(&httpReq->apm_sc, val);
|
|
span_context_to_cw_string(&httpReq->apm_sc, val);
|
|
|
|
|
|
|
|
// Verify val content after generation - check first few bytes as hex
|
|
// Verify val content after generation - check first few bytes as hex
|
|
|
- bpf_printk("uprobe_Transport_roundTrip: val[0]=0x%02x, val[1]=0x%02x, val[2]=0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("uprobe_Transport_roundTrip: val[0]=0x%02x, val[1]=0x%02x, val[2]=0x%02x",
|
|
|
(u8)val[0], (u8)val[1], (u8)val[2]);
|
|
(u8)val[0], (u8)val[1], (u8)val[2]);
|
|
|
- bpf_printk("uprobe_Transport_roundTrip: val[3]=0x%02x, val[4]=0x%02x, val[5]=0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("uprobe_Transport_roundTrip: val[3]=0x%02x, val[4]=0x%02x, val[5]=0x%02x",
|
|
|
(u8)val[3], (u8)val[4], (u8)val[5]);
|
|
(u8)val[3], (u8)val[4], (u8)val[5]);
|
|
|
|
|
|
|
|
// Also verify as characters if printable
|
|
// Also verify as characters if printable
|
|
|
if (val[0] >= 32 && val[0] < 127) {
|
|
if (val[0] >= 32 && val[0] < 127) {
|
|
|
- bpf_printk("uprobe_Transport_roundTrip: val[0-2] as chars: %c%c%c", val[0], val[1], val[2]);
|
|
|
|
|
|
|
+ cw_bpf_debug("uprobe_Transport_roundTrip: val[0-2] as chars: %c%c%c", val[0], val[1], val[2]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
long res2 = cw_inject_header_half(headers_ptr, val,proc_info);
|
|
long res2 = cw_inject_header_half(headers_ptr, val,proc_info);
|
|
@@ -459,7 +459,7 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) {
|
|
|
// bpf_prog_up__go_update_header: 完成实际的 header 注入
|
|
// bpf_prog_up__go_update_header: 完成实际的 header 注入
|
|
|
// 从 bucket_map_value 读取信息,写入到 Go map 中
|
|
// 从 bucket_map_value 读取信息,写入到 Go map 中
|
|
|
PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
- bpf_printk("go_update_header: START");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: START");
|
|
|
|
|
|
|
|
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
|
__u32 tgid = pid_tgid >> 32;
|
|
__u32 tgid = pid_tgid >> 32;
|
|
@@ -467,27 +467,27 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
bpf_map_lookup_elem(&proc_info_map, &tgid);
|
|
bpf_map_lookup_elem(&proc_info_map, &tgid);
|
|
|
if(!proc_info)
|
|
if(!proc_info)
|
|
|
{
|
|
{
|
|
|
- bpf_printk("go_update_header: proc_info is NULL");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: proc_info is NULL");
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
u32 map_id = CLIENT_MAP_KEY;
|
|
u32 map_id = CLIENT_MAP_KEY;
|
|
|
struct map_bucket *bucket_map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
|
|
struct map_bucket *bucket_map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
|
|
|
if (!bucket_map_value) {
|
|
if (!bucket_map_value) {
|
|
|
- bpf_printk("go_update_header: bucket_map_value is NULL");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: bucket_map_value is NULL");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!bucket_map_value->headers_ptr){
|
|
if (!bucket_map_value->headers_ptr){
|
|
|
- bpf_printk("go_update_header: headers_ptr is NULL");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: headers_ptr is NULL");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
if (!bucket_map_value->bucket_ptr){
|
|
if (!bucket_map_value->bucket_ptr){
|
|
|
- bpf_printk("go_update_header: bucket_ptr is NULL");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: bucket_ptr is NULL");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
if (bucket_map_value->bucket_index >= 8) {
|
|
if (bucket_map_value->bucket_index >= 8) {
|
|
|
- bpf_printk("go_update_header: bucket_index >= 8");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: bucket_index >= 8");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -497,19 +497,19 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
char * header_str = bucket_map_value->header_str;
|
|
char * header_str = bucket_map_value->header_str;
|
|
|
u8 bucket_index = bucket_map_value->bucket_index; // For old hmap: bucket_index, For Swiss Tables: slot_idx
|
|
u8 bucket_index = bucket_map_value->bucket_index; // For old hmap: bucket_index, For Swiss Tables: slot_idx
|
|
|
|
|
|
|
|
- bpf_printk("go_update_header: headers_ptr=%p", headers_ptr);
|
|
|
|
|
- bpf_printk("go_update_header: bucket_ptr=%p, count=%llu", bucket_ptr, curr_keyvalue_count);
|
|
|
|
|
- bpf_printk("go_update_header: bucket_index=%d", bucket_index);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: headers_ptr=%p", headers_ptr);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: bucket_ptr=%p, count=%llu", bucket_ptr, curr_keyvalue_count);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: bucket_index=%d", bucket_index);
|
|
|
|
|
|
|
|
// Verify header_str content before using it - check first 6 bytes
|
|
// Verify header_str content before using it - check first 6 bytes
|
|
|
- bpf_printk("go_update_header: header_str[0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: header_str[0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
(u8)header_str[0], (u8)header_str[1], (u8)header_str[2]);
|
|
(u8)header_str[0], (u8)header_str[1], (u8)header_str[2]);
|
|
|
- bpf_printk("go_update_header: header_str[3-5]=0x%02x 0x%02x 0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: header_str[3-5]=0x%02x 0x%02x 0x%02x",
|
|
|
(u8)header_str[3], (u8)header_str[4], (u8)header_str[5]);
|
|
(u8)header_str[3], (u8)header_str[4], (u8)header_str[5]);
|
|
|
|
|
|
|
|
// Check if Go version >= 1.24 (Swiss Tables)
|
|
// Check if Go version >= 1.24 (Swiss Tables)
|
|
|
if (proc_info->version >= GO_VERSION(1, 24, 0)) {
|
|
if (proc_info->version >= GO_VERSION(1, 24, 0)) {
|
|
|
- bpf_printk("go_update_header: Go 1.24+ Swiss Tables - injecting into group");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Go 1.24+ Swiss Tables - injecting into group");
|
|
|
|
|
|
|
|
// For Swiss Tables, bucket_ptr is actually group_ptr, bucket_index is slot_idx
|
|
// For Swiss Tables, bucket_ptr is actually group_ptr, bucket_index is slot_idx
|
|
|
void *group_ptr = bucket_ptr;
|
|
void *group_ptr = bucket_ptr;
|
|
@@ -520,10 +520,10 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
char key[8] = "cwtrace"; // 7 chars + null terminator for C string
|
|
char key[8] = "cwtrace"; // 7 chars + null terminator for C string
|
|
|
void *key_str_ptr = cw_write_target_data(key, CW_HEADER_KEY_LENGTH, proc_info);
|
|
void *key_str_ptr = cw_write_target_data(key, CW_HEADER_KEY_LENGTH, proc_info);
|
|
|
if (key_str_ptr == NULL) {
|
|
if (key_str_ptr == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to write key");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write key");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("go_update_header: key_str_ptr=%p", key_str_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: key_str_ptr=%p", key_str_ptr);
|
|
|
|
|
|
|
|
// Save key_str_ptr to a volatile variable to prevent compiler optimization
|
|
// Save key_str_ptr to a volatile variable to prevent compiler optimization
|
|
|
// Use multiple steps to force compiler to use correct value
|
|
// Use multiple steps to force compiler to use correct value
|
|
@@ -531,12 +531,12 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
volatile void *key_str_ptr_volatile = key_str_ptr_copy;
|
|
volatile void *key_str_ptr_volatile = key_str_ptr_copy;
|
|
|
u64 saved_key_str_ptr_early = (u64)(void*)key_str_ptr_volatile;
|
|
u64 saved_key_str_ptr_early = (u64)(void*)key_str_ptr_volatile;
|
|
|
|
|
|
|
|
- bpf_printk("go_update_header: saved_key_str_ptr_early=0x%llx", saved_key_str_ptr_early);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: saved_key_str_ptr_early=0x%llx", saved_key_str_ptr_early);
|
|
|
|
|
|
|
|
// Verify the saved value is not NULL and not equal to any future slot_ptr_u64 value
|
|
// Verify the saved value is not NULL and not equal to any future slot_ptr_u64 value
|
|
|
// We can't check against slot_ptr_u64 yet, but we can check it's not zero
|
|
// We can't check against slot_ptr_u64 yet, but we can check it's not zero
|
|
|
if (saved_key_str_ptr_early == 0) {
|
|
if (saved_key_str_ptr_early == 0) {
|
|
|
- bpf_printk("go_update_header: ERROR: saved_key_str_ptr_early is NULL!");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: ERROR: saved_key_str_ptr_early is NULL!");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -544,21 +544,21 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
void *key_str_ptr_verify = key_str_ptr;
|
|
void *key_str_ptr_verify = key_str_ptr;
|
|
|
u64 saved_verify = (u64)key_str_ptr_verify;
|
|
u64 saved_verify = (u64)key_str_ptr_verify;
|
|
|
if (saved_key_str_ptr_early != saved_verify) {
|
|
if (saved_key_str_ptr_early != saved_verify) {
|
|
|
- bpf_printk("go_update_header: ERROR: saved_key_str_ptr_early mismatch!");
|
|
|
|
|
- bpf_printk("go_update_header: saved=0x%llx, verify=0x%llx", saved_key_str_ptr_early, saved_verify);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: ERROR: saved_key_str_ptr_early mismatch!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: saved=0x%llx, verify=0x%llx", saved_key_str_ptr_early, saved_verify);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Prepare value string
|
|
// Prepare value string
|
|
|
// Verify header_str content before writing
|
|
// Verify header_str content before writing
|
|
|
- bpf_printk("go_update_header: Before write, header_str[0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Before write, header_str[0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
(u8)header_str[0], (u8)header_str[1], (u8)header_str[2]);
|
|
(u8)header_str[0], (u8)header_str[1], (u8)header_str[2]);
|
|
|
- bpf_printk("go_update_header: Before write, header_str[3-5]=0x%02x 0x%02x 0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Before write, header_str[3-5]=0x%02x 0x%02x 0x%02x",
|
|
|
(u8)header_str[3], (u8)header_str[4], (u8)header_str[5]);
|
|
(u8)header_str[3], (u8)header_str[4], (u8)header_str[5]);
|
|
|
|
|
|
|
|
void *header_str_ptr = cw_write_target_data(header_str, CW_HEADER_VAL_LENGTH, proc_info);
|
|
void *header_str_ptr = cw_write_target_data(header_str, CW_HEADER_VAL_LENGTH, proc_info);
|
|
|
if(header_str_ptr == NULL) {
|
|
if(header_str_ptr == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to write header_str");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write header_str");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
// Save header_str_ptr to u64 immediately and verify it's correct
|
|
// Save header_str_ptr to u64 immediately and verify it's correct
|
|
@@ -570,26 +570,26 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
// Verify immediately
|
|
// Verify immediately
|
|
|
u64 verify_immediate = (u64)header_str_ptr;
|
|
u64 verify_immediate = (u64)header_str_ptr;
|
|
|
if (saved_header_str_ptr_u64 != verify_immediate) {
|
|
if (saved_header_str_ptr_u64 != verify_immediate) {
|
|
|
- bpf_printk("go_update_header: ERROR: saved_header_str_ptr_u64 mismatch at save!");
|
|
|
|
|
- bpf_printk("go_update_header: saved=0x%llx, verify=0x%llx", saved_header_str_ptr_u64, verify_immediate);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: ERROR: saved_header_str_ptr_u64 mismatch at save!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: saved=0x%llx, verify=0x%llx", saved_header_str_ptr_u64, verify_immediate);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- bpf_printk("go_update_header: header_str_ptr=%p", header_str_ptr);
|
|
|
|
|
- bpf_printk("go_update_header: saved_header_str_ptr_u64=0x%llx", saved_header_str_ptr_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: header_str_ptr=%p", header_str_ptr);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: saved_header_str_ptr_u64=0x%llx", saved_header_str_ptr_u64);
|
|
|
|
|
|
|
|
// Verify what was written to userspace using both pointers
|
|
// Verify what was written to userspace using both pointers
|
|
|
char verify_header_str_saved[8] = {0};
|
|
char verify_header_str_saved[8] = {0};
|
|
|
long verify_res_saved = bpf_probe_read_user(verify_header_str_saved, sizeof(verify_header_str_saved), (void*)saved_header_str_ptr_u64);
|
|
long verify_res_saved = bpf_probe_read_user(verify_header_str_saved, sizeof(verify_header_str_saved), (void*)saved_header_str_ptr_u64);
|
|
|
if (verify_res_saved == 0) {
|
|
if (verify_res_saved == 0) {
|
|
|
- bpf_printk("go_update_header: From saved_ptr, [0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: From saved_ptr, [0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
(u8)verify_header_str_saved[0], (u8)verify_header_str_saved[1], (u8)verify_header_str_saved[2]);
|
|
(u8)verify_header_str_saved[0], (u8)verify_header_str_saved[1], (u8)verify_header_str_saved[2]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
char verify_header_str_orig[8] = {0};
|
|
char verify_header_str_orig[8] = {0};
|
|
|
long verify_res_orig = bpf_probe_read_user(verify_header_str_orig, sizeof(verify_header_str_orig), header_str_ptr);
|
|
long verify_res_orig = bpf_probe_read_user(verify_header_str_orig, sizeof(verify_header_str_orig), header_str_ptr);
|
|
|
if (verify_res_orig == 0) {
|
|
if (verify_res_orig == 0) {
|
|
|
- bpf_printk("go_update_header: From orig_ptr, [0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: From orig_ptr, [0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
(u8)verify_header_str_orig[0], (u8)verify_header_str_orig[1], (u8)verify_header_str_orig[2]);
|
|
(u8)verify_header_str_orig[0], (u8)verify_header_str_orig[1], (u8)verify_header_str_orig[2]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -597,10 +597,10 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
struct go_string_ot val_str = {.str = (void*)saved_header_str_ptr_u64, .len = CW_HEADER_VAL_LENGTH};
|
|
struct go_string_ot val_str = {.str = (void*)saved_header_str_ptr_u64, .len = CW_HEADER_VAL_LENGTH};
|
|
|
void *val_str_struct_ptr = cw_write_target_data((void*)&val_str, sizeof(val_str), proc_info);
|
|
void *val_str_struct_ptr = cw_write_target_data((void*)&val_str, sizeof(val_str), proc_info);
|
|
|
if(val_str_struct_ptr == NULL) {
|
|
if(val_str_struct_ptr == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to write val_str struct");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write val_str struct");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("go_update_header: val_str_struct_ptr=%p", val_str_struct_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: val_str_struct_ptr=%p", val_str_struct_ptr);
|
|
|
|
|
|
|
|
// Calculate slot offset
|
|
// Calculate slot offset
|
|
|
// Group layout: ctrlGroup (8 bytes) + slots[8]
|
|
// Group layout: ctrlGroup (8 bytes) + slots[8]
|
|
@@ -613,30 +613,30 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
u64 slot_size = 40; // string (16) + []string (24)
|
|
u64 slot_size = 40; // string (16) + []string (24)
|
|
|
u64 slot_offset = group_slots_offset + (slot_idx * slot_size);
|
|
u64 slot_offset = group_slots_offset + (slot_idx * slot_size);
|
|
|
|
|
|
|
|
- bpf_printk("go_update_header: slot_idx=%d", slot_idx);
|
|
|
|
|
- bpf_printk("go_update_header: group_slots_offset=%llu", group_slots_offset);
|
|
|
|
|
- bpf_printk("go_update_header: slot_size=%llu", slot_size);
|
|
|
|
|
- bpf_printk("go_update_header: slot_offset=%llu", slot_offset);
|
|
|
|
|
- bpf_printk("go_update_header: group_ptr=%p", group_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: slot_idx=%d", slot_idx);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: group_slots_offset=%llu", group_slots_offset);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: slot_size=%llu", slot_size);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: slot_offset=%llu", slot_offset);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: group_ptr=%p", group_ptr);
|
|
|
|
|
|
|
|
// Calculate slot_ptr carefully to avoid any issues
|
|
// Calculate slot_ptr carefully to avoid any issues
|
|
|
u64 group_ptr_u64 = (u64)group_ptr;
|
|
u64 group_ptr_u64 = (u64)group_ptr;
|
|
|
u64 slot_ptr_u64 = group_ptr_u64 + slot_offset;
|
|
u64 slot_ptr_u64 = group_ptr_u64 + slot_offset;
|
|
|
|
|
|
|
|
- bpf_printk("go_update_header: group_ptr_u64=0x%llx", group_ptr_u64);
|
|
|
|
|
- bpf_printk("go_update_header: slot_ptr_u64=0x%llx", slot_ptr_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: group_ptr_u64=0x%llx", group_ptr_u64);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: slot_ptr_u64=0x%llx", slot_ptr_u64);
|
|
|
|
|
|
|
|
// Verify slot_ptr is within reasonable bounds (should be >= group_ptr + 8 and < group_ptr + 328)
|
|
// Verify slot_ptr is within reasonable bounds (should be >= group_ptr + 8 and < group_ptr + 328)
|
|
|
if (slot_ptr_u64 < group_ptr_u64 + 8 || slot_ptr_u64 >= group_ptr_u64 + 328) {
|
|
if (slot_ptr_u64 < group_ptr_u64 + 8 || slot_ptr_u64 >= group_ptr_u64 + 328) {
|
|
|
- bpf_printk("go_update_header: slot_ptr out of bounds!");
|
|
|
|
|
- bpf_printk("go_update_header: group_ptr_u64=0x%llx, slot_ptr_u64=0x%llx", group_ptr_u64, slot_ptr_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: slot_ptr out of bounds!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: group_ptr_u64=0x%llx, slot_ptr_u64=0x%llx", group_ptr_u64, slot_ptr_u64);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Write key (go_string_ot at slot offset 0)
|
|
// Write key (go_string_ot at slot offset 0)
|
|
|
// Verify key_str_ptr is valid
|
|
// Verify key_str_ptr is valid
|
|
|
if (key_str_ptr == NULL) {
|
|
if (key_str_ptr == NULL) {
|
|
|
- bpf_printk("go_update_header: key_str_ptr is NULL!");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: key_str_ptr is NULL!");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -644,20 +644,20 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
char key_check[8] = {0};
|
|
char key_check[8] = {0};
|
|
|
long res = bpf_probe_read_user(key_check, sizeof(key_check), key_str_ptr);
|
|
long res = bpf_probe_read_user(key_check, sizeof(key_check), key_str_ptr);
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to verify key string data, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to verify key string data, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("go_update_header: key_str_ptr=%p", key_str_ptr);
|
|
|
|
|
- bpf_printk("go_update_header: key_check[0]=0x%x", (u8)key_check[0]);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: key_str_ptr=%p", key_str_ptr);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: key_check[0]=0x%x", (u8)key_check[0]);
|
|
|
|
|
|
|
|
// Create key_str struct and verify it's correct before writing
|
|
// Create key_str struct and verify it's correct before writing
|
|
|
struct go_string_ot key_str = {.str = key_str_ptr, .len = CW_HEADER_KEY_LENGTH};
|
|
struct go_string_ot key_str = {.str = key_str_ptr, .len = CW_HEADER_KEY_LENGTH};
|
|
|
- bpf_printk("go_update_header: Writing key: str=%p, len=%d", key_str.str, key_str.len);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Writing key: str=%p, len=%d", key_str.str, key_str.len);
|
|
|
|
|
|
|
|
// Verify key_str is still correct right before writing
|
|
// Verify key_str is still correct right before writing
|
|
|
if (key_str.str != key_str_ptr || key_str.len != CW_HEADER_KEY_LENGTH) {
|
|
if (key_str.str != key_str_ptr || key_str.len != CW_HEADER_KEY_LENGTH) {
|
|
|
- bpf_printk("go_update_header: ERROR: key_str corrupted before write!");
|
|
|
|
|
- bpf_printk("go_update_header: key_str.str=%p, expected=%p", key_str.str, key_str_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: ERROR: key_str corrupted before write!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: key_str.str=%p, expected=%p", key_str.str, key_str_ptr);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -666,8 +666,8 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
struct go_string_ot slot_before = {0};
|
|
struct go_string_ot slot_before = {0};
|
|
|
res = bpf_probe_read_user(&slot_before, sizeof(slot_before), (void*)slot_ptr_u64);
|
|
res = bpf_probe_read_user(&slot_before, sizeof(slot_before), (void*)slot_ptr_u64);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Slot before write: str=%p", slot_before.str);
|
|
|
|
|
- bpf_printk("go_update_header: Slot before write: len=%lld", slot_before.len);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Slot before write: str=%p", slot_before.str);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Slot before write: len=%lld", slot_before.len);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Write key directly using slot_ptr_u64 - write pointer and length separately to avoid corruption
|
|
// Write key directly using slot_ptr_u64 - write pointer and length separately to avoid corruption
|
|
@@ -676,21 +676,21 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
char key_recreate[8] = "cwtrace";
|
|
char key_recreate[8] = "cwtrace";
|
|
|
void *key_str_ptr_fresh = cw_write_target_data(key_recreate, CW_HEADER_KEY_LENGTH, proc_info);
|
|
void *key_str_ptr_fresh = cw_write_target_data(key_recreate, CW_HEADER_KEY_LENGTH, proc_info);
|
|
|
if (key_str_ptr_fresh == NULL) {
|
|
if (key_str_ptr_fresh == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to recreate key string");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to recreate key string");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
u64 key_str_ptr_u64 = (u64)key_str_ptr_fresh;
|
|
u64 key_str_ptr_u64 = (u64)key_str_ptr_fresh;
|
|
|
|
|
|
|
|
u64 saved_key_str_len = (u64)CW_HEADER_KEY_LENGTH;
|
|
u64 saved_key_str_len = (u64)CW_HEADER_KEY_LENGTH;
|
|
|
|
|
|
|
|
- bpf_printk("go_update_header: key_str_ptr_fresh=%p, u64=0x%llx", key_str_ptr_fresh, key_str_ptr_u64);
|
|
|
|
|
- bpf_printk("go_update_header: saved_key_str_len=%llu", saved_key_str_len);
|
|
|
|
|
- bpf_printk("go_update_header: Writing key pointer: 0x%llx to slot at 0x%llx", key_str_ptr_u64, slot_ptr_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: key_str_ptr_fresh=%p, u64=0x%llx", key_str_ptr_fresh, key_str_ptr_u64);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: saved_key_str_len=%llu", saved_key_str_len);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Writing key pointer: 0x%llx to slot at 0x%llx", key_str_ptr_u64, slot_ptr_u64);
|
|
|
|
|
|
|
|
// Write pointer first (first 8 bytes of go_string_ot) - use fresh value
|
|
// Write pointer first (first 8 bytes of go_string_ot) - use fresh value
|
|
|
res = bpf_probe_write_user((void*)slot_ptr_u64, &key_str_ptr_u64, sizeof(key_str_ptr_u64));
|
|
res = bpf_probe_write_user((void*)slot_ptr_u64, &key_str_ptr_u64, sizeof(key_str_ptr_u64));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to write key pointer, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write key pointer, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -698,34 +698,34 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
u64 verify_ptr = 0;
|
|
u64 verify_ptr = 0;
|
|
|
res = bpf_probe_read_user(&verify_ptr, sizeof(verify_ptr), (void*)slot_ptr_u64);
|
|
res = bpf_probe_read_user(&verify_ptr, sizeof(verify_ptr), (void*)slot_ptr_u64);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Verified pointer after write: 0x%llx", verify_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Verified pointer after write: 0x%llx", verify_ptr);
|
|
|
if (verify_ptr != key_str_ptr_u64) {
|
|
if (verify_ptr != key_str_ptr_u64) {
|
|
|
- bpf_printk("go_update_header: ERROR: Pointer mismatch!");
|
|
|
|
|
- bpf_printk("go_update_header: Expected 0x%llx, got 0x%llx", key_str_ptr_u64, verify_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: ERROR: Pointer mismatch!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Expected 0x%llx, got 0x%llx", key_str_ptr_u64, verify_ptr);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Write length second (next 8 bytes of go_string_ot)
|
|
// Write length second (next 8 bytes of go_string_ot)
|
|
|
u64 slot_len_ptr = slot_ptr_u64 + 8;
|
|
u64 slot_len_ptr = slot_ptr_u64 + 8;
|
|
|
- bpf_printk("go_update_header: Writing key length: %llu to slot at 0x%llx", saved_key_str_len, slot_len_ptr);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Writing key length: %llu to slot at 0x%llx", saved_key_str_len, slot_len_ptr);
|
|
|
res = bpf_probe_write_user((void*)slot_len_ptr, &saved_key_str_len, sizeof(saved_key_str_len));
|
|
res = bpf_probe_write_user((void*)slot_len_ptr, &saved_key_str_len, sizeof(saved_key_str_len));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to write key length, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write key length, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("go_update_header: Key written to slot");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Key written to slot");
|
|
|
|
|
|
|
|
// Verify what we wrote - use slot_ptr_u64 directly
|
|
// Verify what we wrote - use slot_ptr_u64 directly
|
|
|
u64 slot_ptr_for_verify = slot_ptr_u64;
|
|
u64 slot_ptr_for_verify = slot_ptr_u64;
|
|
|
struct go_string_ot verify_key = {0};
|
|
struct go_string_ot verify_key = {0};
|
|
|
res = bpf_probe_read_user(&verify_key, sizeof(verify_key), (void*)slot_ptr_for_verify);
|
|
res = bpf_probe_read_user(&verify_key, sizeof(verify_key), (void*)slot_ptr_for_verify);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Verified key: str=%p, len=%lld", verify_key.str, verify_key.len);
|
|
|
|
|
- bpf_printk("go_update_header: Verify read from 0x%llx", slot_ptr_for_verify);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Verified key: str=%p, len=%lld", verify_key.str, verify_key.len);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Verify read from 0x%llx", slot_ptr_for_verify);
|
|
|
if (verify_key.str != key_str_ptr_fresh || verify_key.len != CW_HEADER_KEY_LENGTH) {
|
|
if (verify_key.str != key_str_ptr_fresh || verify_key.len != CW_HEADER_KEY_LENGTH) {
|
|
|
- bpf_printk("go_update_header: Key verification failed!");
|
|
|
|
|
- bpf_printk("go_update_header: Expected str=%p, len=%d", key_str_ptr_fresh, CW_HEADER_KEY_LENGTH);
|
|
|
|
|
- bpf_printk("go_update_header: Got str=%p, len=%lld", verify_key.str, verify_key.len);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Key verification failed!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Expected str=%p, len=%d", key_str_ptr_fresh, CW_HEADER_KEY_LENGTH);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Got str=%p, len=%lld", verify_key.str, verify_key.len);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -733,57 +733,57 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
char key_content[8] = {0};
|
|
char key_content[8] = {0};
|
|
|
res = bpf_probe_read_user(key_content, sizeof(key_content), verify_key.str);
|
|
res = bpf_probe_read_user(key_content, sizeof(key_content), verify_key.str);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Key content[0-2]: %c%c%c", key_content[0], key_content[1], key_content[2]);
|
|
|
|
|
- bpf_printk("go_update_header: Key content[3-4]: %c%c", key_content[3], key_content[4]);
|
|
|
|
|
- bpf_printk("go_update_header: Key content[5-6]: %c%c", key_content[5], key_content[6]);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Key content[0-2]: %c%c%c", key_content[0], key_content[1], key_content[2]);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Key content[3-4]: %c%c", key_content[3], key_content[4]);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Key content[5-6]: %c%c", key_content[5], key_content[6]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Read the entire slot to see what Go runtime will see
|
|
// Read the entire slot to see what Go runtime will see
|
|
|
// Read as go_string_ot first, then verify the bytes
|
|
// Read as go_string_ot first, then verify the bytes
|
|
|
u64 slot_ptr_for_read = slot_ptr_u64;
|
|
u64 slot_ptr_for_read = slot_ptr_u64;
|
|
|
- bpf_printk("go_update_header: Reading slot at 0x%llx", slot_ptr_for_read);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Reading slot at 0x%llx", slot_ptr_for_read);
|
|
|
struct go_string_ot slot_key_verify = {0};
|
|
struct go_string_ot slot_key_verify = {0};
|
|
|
res = bpf_probe_read_user(&slot_key_verify, sizeof(slot_key_verify), (void*)slot_ptr_for_read);
|
|
res = bpf_probe_read_user(&slot_key_verify, sizeof(slot_key_verify), (void*)slot_ptr_for_read);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Slot key as struct: str=%p, len=%lld", slot_key_verify.str, slot_key_verify.len);
|
|
|
|
|
- bpf_printk("go_update_header: Expected: str=%p, len=%d", key_str_ptr_fresh, CW_HEADER_KEY_LENGTH);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Slot key as struct: str=%p, len=%lld", slot_key_verify.str, slot_key_verify.len);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Expected: str=%p, len=%d", key_str_ptr_fresh, CW_HEADER_KEY_LENGTH);
|
|
|
if (slot_key_verify.str != key_str_ptr_fresh || slot_key_verify.len != CW_HEADER_KEY_LENGTH) {
|
|
if (slot_key_verify.str != key_str_ptr_fresh || slot_key_verify.len != CW_HEADER_KEY_LENGTH) {
|
|
|
- bpf_printk("go_update_header: WARNING: Slot content mismatch!");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: WARNING: Slot content mismatch!");
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- bpf_printk("go_update_header: Failed to read slot_key_verify, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to read slot_key_verify, res=%ld", res);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Also read raw bytes for debugging - use slot_key_verify we already read
|
|
// Also read raw bytes for debugging - use slot_key_verify we already read
|
|
|
- bpf_printk("go_update_header: Slot raw pointer from struct: 0x%llx", (u64)slot_key_verify.str);
|
|
|
|
|
- bpf_printk("go_update_header: Slot raw length from struct: 0x%llx", (u64)slot_key_verify.len);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Slot raw pointer from struct: 0x%llx", (u64)slot_key_verify.str);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Slot raw length from struct: 0x%llx", (u64)slot_key_verify.len);
|
|
|
|
|
|
|
|
// Read raw bytes to see what's actually in memory
|
|
// Read raw bytes to see what's actually in memory
|
|
|
char slot_raw[16] = {0}; // Only read first 16 bytes (go_string_ot)
|
|
char slot_raw[16] = {0}; // Only read first 16 bytes (go_string_ot)
|
|
|
res = bpf_probe_read_user(slot_raw, sizeof(slot_raw), (void*)slot_ptr_for_read);
|
|
res = bpf_probe_read_user(slot_raw, sizeof(slot_raw), (void*)slot_ptr_for_read);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Slot raw bytes (first 16 bytes):");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Slot raw bytes (first 16 bytes):");
|
|
|
for (int i = 0; i < 16; i++) {
|
|
for (int i = 0; i < 16; i++) {
|
|
|
- bpf_printk("go_update_header: slot[%d]=0x%02x", i, (u8)slot_raw[i]);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: slot[%d]=0x%02x", i, (u8)slot_raw[i]);
|
|
|
}
|
|
}
|
|
|
// Verify first 8 bytes match the pointer we wrote
|
|
// Verify first 8 bytes match the pointer we wrote
|
|
|
u64 *raw_ptr = (u64*)slot_raw;
|
|
u64 *raw_ptr = (u64*)slot_raw;
|
|
|
- bpf_printk("go_update_header: First 8 bytes as u64: 0x%llx", raw_ptr[0]);
|
|
|
|
|
- bpf_printk("go_update_header: Expected pointer: 0x%llx", key_str_ptr_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: First 8 bytes as u64: 0x%llx", raw_ptr[0]);
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Expected pointer: 0x%llx", key_str_ptr_u64);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- bpf_printk("go_update_header: Failed to verify key, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to verify key, res=%ld", res);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Write value (go_slice_ot at slot offset 16, after key)
|
|
// Write value (go_slice_ot at slot offset 16, after key)
|
|
|
// Verify elem_ptr is within bounds
|
|
// Verify elem_ptr is within bounds
|
|
|
u64 elem_ptr_u64 = slot_ptr_u64 + 16; // After key (16 bytes)
|
|
u64 elem_ptr_u64 = slot_ptr_u64 + 16; // After key (16 bytes)
|
|
|
if (elem_ptr_u64 < group_ptr_u64 + 8 || elem_ptr_u64 >= group_ptr_u64 + 328) {
|
|
if (elem_ptr_u64 < group_ptr_u64 + 8 || elem_ptr_u64 >= group_ptr_u64 + 328) {
|
|
|
- bpf_printk("go_update_header: elem_ptr out of bounds!");
|
|
|
|
|
- bpf_printk("go_update_header: elem_ptr_u64=0x%llx", elem_ptr_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: elem_ptr out of bounds!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: elem_ptr_u64=0x%llx", elem_ptr_u64);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("go_update_header: elem_ptr_u64=0x%llx", elem_ptr_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: elem_ptr_u64=0x%llx", elem_ptr_u64);
|
|
|
|
|
|
|
|
// Re-create value string struct to avoid register corruption (similar to key fix)
|
|
// Re-create value string struct to avoid register corruption (similar to key fix)
|
|
|
// Re-read header_str from map to get the correct pointer value
|
|
// Re-read header_str from map to get the correct pointer value
|
|
@@ -795,40 +795,40 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
// Re-write header_str to get a fresh pointer (similar to key fix)
|
|
// Re-write header_str to get a fresh pointer (similar to key fix)
|
|
|
void *header_str_ptr_fresh = cw_write_target_data(header_str, CW_HEADER_VAL_LENGTH, proc_info);
|
|
void *header_str_ptr_fresh = cw_write_target_data(header_str, CW_HEADER_VAL_LENGTH, proc_info);
|
|
|
if (header_str_ptr_fresh == NULL) {
|
|
if (header_str_ptr_fresh == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to recreate header_str");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to recreate header_str");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
u64 header_str_ptr_fresh_u64 = (u64)header_str_ptr_fresh;
|
|
u64 header_str_ptr_fresh_u64 = (u64)header_str_ptr_fresh;
|
|
|
- bpf_printk("go_update_header: header_str_ptr_fresh=%p, u64=0x%llx", header_str_ptr_fresh, header_str_ptr_fresh_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: header_str_ptr_fresh=%p, u64=0x%llx", header_str_ptr_fresh, header_str_ptr_fresh_u64);
|
|
|
|
|
|
|
|
// Use fresh pointer to create val_str struct
|
|
// Use fresh pointer to create val_str struct
|
|
|
struct go_string_ot val_str_fresh = {.str = (void*)header_str_ptr_fresh_u64, .len = CW_HEADER_VAL_LENGTH};
|
|
struct go_string_ot val_str_fresh = {.str = (void*)header_str_ptr_fresh_u64, .len = CW_HEADER_VAL_LENGTH};
|
|
|
void *val_str_struct_ptr_fresh = cw_write_target_data((void*)&val_str_fresh, sizeof(val_str_fresh), proc_info);
|
|
void *val_str_struct_ptr_fresh = cw_write_target_data((void*)&val_str_fresh, sizeof(val_str_fresh), proc_info);
|
|
|
if (val_str_struct_ptr_fresh == NULL) {
|
|
if (val_str_struct_ptr_fresh == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to recreate val_str struct");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to recreate val_str struct");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
u64 val_str_struct_ptr_u64 = (u64)val_str_struct_ptr_fresh;
|
|
u64 val_str_struct_ptr_u64 = (u64)val_str_struct_ptr_fresh;
|
|
|
- bpf_printk("go_update_header: val_str_struct_ptr_fresh=%p, u64=0x%llx", val_str_struct_ptr_fresh, val_str_struct_ptr_u64);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: val_str_struct_ptr_fresh=%p, u64=0x%llx", val_str_struct_ptr_fresh, val_str_struct_ptr_u64);
|
|
|
|
|
|
|
|
struct go_slice_ot val_slice = {.array = (void*)val_str_struct_ptr_u64, .len = 1, .cap = 1};
|
|
struct go_slice_ot val_slice = {.array = (void*)val_str_struct_ptr_u64, .len = 1, .cap = 1};
|
|
|
- bpf_printk("go_update_header: Writing value slice: array=%p, len=%d, cap=%d", val_slice.array, val_slice.len, val_slice.cap);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Writing value slice: array=%p, len=%d, cap=%d", val_slice.array, val_slice.len, val_slice.cap);
|
|
|
// Use elem_ptr_u64 directly to avoid variable corruption
|
|
// Use elem_ptr_u64 directly to avoid variable corruption
|
|
|
res = bpf_probe_write_user((void*)elem_ptr_u64, &val_slice, sizeof(val_slice));
|
|
res = bpf_probe_write_user((void*)elem_ptr_u64, &val_slice, sizeof(val_slice));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to write value slice, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write value slice, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("go_update_header: Value written to slot");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Value written to slot");
|
|
|
|
|
|
|
|
// Verify value was written correctly
|
|
// Verify value was written correctly
|
|
|
struct go_slice_ot verify_val = {0};
|
|
struct go_slice_ot verify_val = {0};
|
|
|
res = bpf_probe_read_user(&verify_val, sizeof(verify_val), (void*)elem_ptr_u64);
|
|
res = bpf_probe_read_user(&verify_val, sizeof(verify_val), (void*)elem_ptr_u64);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Verified value: array=%p, len=%lld, cap=%lld", verify_val.array, verify_val.len, verify_val.cap);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Verified value: array=%p, len=%lld, cap=%lld", verify_val.array, verify_val.len, verify_val.cap);
|
|
|
if (verify_val.array != (void*)val_str_struct_ptr_u64 || verify_val.len != 1 || verify_val.cap != 1) {
|
|
if (verify_val.array != (void*)val_str_struct_ptr_u64 || verify_val.len != 1 || verify_val.cap != 1) {
|
|
|
- bpf_printk("go_update_header: Value verification failed!");
|
|
|
|
|
- bpf_printk("go_update_header: Expected array=%p, got array=%p", (void*)val_str_struct_ptr_u64, verify_val.array);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Value verification failed!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Expected array=%p, got array=%p", (void*)val_str_struct_ptr_u64, verify_val.array);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -836,16 +836,16 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
struct go_string_ot verify_val_str = {0};
|
|
struct go_string_ot verify_val_str = {0};
|
|
|
res = bpf_probe_read_user(&verify_val_str, sizeof(verify_val_str), verify_val.array);
|
|
res = bpf_probe_read_user(&verify_val_str, sizeof(verify_val_str), verify_val.array);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Value string: str=%p, len=%lld", verify_val_str.str, verify_val_str.len);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Value string: str=%p, len=%lld", verify_val_str.str, verify_val_str.len);
|
|
|
if (verify_val_str.str != (void*)header_str_ptr_fresh_u64) {
|
|
if (verify_val_str.str != (void*)header_str_ptr_fresh_u64) {
|
|
|
- bpf_printk("go_update_header: WARNING: Value string pointer mismatch!");
|
|
|
|
|
- bpf_printk("go_update_header: Expected str=%p, got str=%p", (void*)header_str_ptr_fresh_u64, verify_val_str.str);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: WARNING: Value string pointer mismatch!");
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Expected str=%p, got str=%p", (void*)header_str_ptr_fresh_u64, verify_val_str.str);
|
|
|
} else {
|
|
} else {
|
|
|
// Verify the actual string content
|
|
// Verify the actual string content
|
|
|
char verify_str_content[8] = {0};
|
|
char verify_str_content[8] = {0};
|
|
|
res = bpf_probe_read_user(verify_str_content, sizeof(verify_str_content), verify_val_str.str);
|
|
res = bpf_probe_read_user(verify_str_content, sizeof(verify_str_content), verify_val_str.str);
|
|
|
if (res == 0) {
|
|
if (res == 0) {
|
|
|
- bpf_printk("go_update_header: Value string content[0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Value string content[0-2]=0x%02x 0x%02x 0x%02x",
|
|
|
(u8)verify_str_content[0], (u8)verify_str_content[1], (u8)verify_str_content[2]);
|
|
(u8)verify_str_content[0], (u8)verify_str_content[1], (u8)verify_str_content[2]);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -860,7 +860,7 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
u64 ctrls = 0;
|
|
u64 ctrls = 0;
|
|
|
res = bpf_probe_read_user(&ctrls, sizeof(ctrls), group_ptr);
|
|
res = bpf_probe_read_user(&ctrls, sizeof(ctrls), group_ptr);
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to read control word, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to read control word, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -868,42 +868,42 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
u64 ctrl_mask = 0xFFULL << (slot_idx * 8);
|
|
u64 ctrl_mask = 0xFFULL << (slot_idx * 8);
|
|
|
u64 new_ctrl_value = ((u64)new_ctrl) << (slot_idx * 8);
|
|
u64 new_ctrl_value = ((u64)new_ctrl) << (slot_idx * 8);
|
|
|
ctrls = (ctrls & ~ctrl_mask) | new_ctrl_value;
|
|
ctrls = (ctrls & ~ctrl_mask) | new_ctrl_value;
|
|
|
- bpf_printk("go_update_header: Updating ctrl, slot_idx=%d, new_ctrl=0x%x", slot_idx, new_ctrl);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Updating ctrl, slot_idx=%d, new_ctrl=0x%x", slot_idx, new_ctrl);
|
|
|
|
|
|
|
|
res = bpf_probe_write_user(group_ptr, &ctrls, sizeof(ctrls));
|
|
res = bpf_probe_write_user(group_ptr, &ctrls, sizeof(ctrls));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to update control word, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to update control word, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("go_update_header: Control word updated");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Control word updated");
|
|
|
|
|
|
|
|
// Update used count
|
|
// Update used count
|
|
|
u64 used = curr_keyvalue_count + 1;
|
|
u64 used = curr_keyvalue_count + 1;
|
|
|
res = bpf_probe_write_user(headers_ptr, &used, sizeof(used));
|
|
res = bpf_probe_write_user(headers_ptr, &used, sizeof(used));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to update used count, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to update used count, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
- bpf_printk("go_update_header: Used count updated to %llu", used);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Used count updated to %llu", used);
|
|
|
|
|
|
|
|
bpf_memset((unsigned char *)bucket_map_value, sizeof(struct map_bucket), 0);
|
|
bpf_memset((unsigned char *)bucket_map_value, sizeof(struct map_bucket), 0);
|
|
|
- bpf_printk("go_update_header: SUCCESS - Swiss Tables injection completed");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: SUCCESS - Swiss Tables injection completed");
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Old implementation for Go < 1.24
|
|
// Old implementation for Go < 1.24
|
|
|
- bpf_printk("go_update_header: Using old hmap implementation");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Using old hmap implementation");
|
|
|
|
|
|
|
|
char key[CW_HEADER_KEY_LENGTH] = CW_HEADER_KEY_VAL;
|
|
char key[CW_HEADER_KEY_LENGTH] = CW_HEADER_KEY_VAL;
|
|
|
void *ptr = cw_write_target_data(key, CW_HEADER_KEY_LENGTH, proc_info);
|
|
void *ptr = cw_write_target_data(key, CW_HEADER_KEY_LENGTH, proc_info);
|
|
|
if (ptr == NULL) {
|
|
if (ptr == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to write key");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write key");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void * header_str_ptr = cw_write_target_data(header_str, CW_HEADER_VAL_LENGTH, proc_info);
|
|
void * header_str_ptr = cw_write_target_data(header_str, CW_HEADER_VAL_LENGTH, proc_info);
|
|
|
if(header_str_ptr == NULL) {
|
|
if(header_str_ptr == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to write header_str");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write header_str");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -911,7 +911,7 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
struct go_string_ot header_value = {.len = CW_HEADER_VAL_LENGTH, .str = header_str_ptr};
|
|
struct go_string_ot header_value = {.len = CW_HEADER_VAL_LENGTH, .str = header_str_ptr};
|
|
|
void * header_value_ptr = cw_write_target_data((void*)&header_value, sizeof(header_value), proc_info);
|
|
void * header_value_ptr = cw_write_target_data((void*)&header_value, sizeof(header_value), proc_info);
|
|
|
if(header_value_ptr == NULL) {
|
|
if(header_value_ptr == NULL) {
|
|
|
- bpf_printk("go_update_header: Failed to write go_string");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to write go_string");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -925,19 +925,19 @@ PROGUP(go_update_header)(struct pt_regs *ctx) {
|
|
|
curr_keyvalue_count = curr_keyvalue_count + 1;
|
|
curr_keyvalue_count = curr_keyvalue_count + 1;
|
|
|
long res = bpf_probe_write_user(headers_ptr, &curr_keyvalue_count, sizeof(curr_keyvalue_count));
|
|
long res = bpf_probe_write_user(headers_ptr, &curr_keyvalue_count, sizeof(curr_keyvalue_count));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to update count, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to update count, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Update the bucket
|
|
// Update the bucket
|
|
|
res = bpf_probe_write_user(bucket_ptr, bucket_map_value, sizeof(struct map_bucket));
|
|
res = bpf_probe_write_user(bucket_ptr, bucket_map_value, sizeof(struct map_bucket));
|
|
|
if (res < 0) {
|
|
if (res < 0) {
|
|
|
- bpf_printk("go_update_header: Failed to update bucket, res=%ld", res);
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: Failed to update bucket, res=%ld", res);
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bpf_memset((unsigned char *)bucket_map_value, sizeof(struct map_bucket), 0);
|
|
bpf_memset((unsigned char *)bucket_map_value, sizeof(struct map_bucket), 0);
|
|
|
- bpf_printk("go_update_header: SUCCESS - old hmap injection completed");
|
|
|
|
|
|
|
+ cw_bpf_debug("go_update_header: SUCCESS - old hmap injection completed");
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|