Przeglądaj źródła

Feature #TASK_QT-18250 提交代码,修复注入header头的问题,下一步解决注入正确header数据

rock 7 miesięcy temu
rodzic
commit
ed1c29162a

+ 87 - 131
ebpftracer/ebpf/utrace/go/net/grpc.client.probe.bpf.c

@@ -25,8 +25,8 @@ struct grpc_client_request_t {
 };
 
 // struct hpack_header_field {
-//     struct go_string name;
-//     struct go_string value;
+//     struct go_string_ot name;
+//     struct go_string_ot value;
 //     bool sensitive;
 // };
 
@@ -52,17 +52,37 @@ struct {
     __uint(max_entries, 1);
 } grpc_client_storage_map SEC(".maps");
 
+// 用于 loopyWriter_headerHandler 的临时存储
+struct header_handler_storage {
+    struct span_context sc;
+    char val[SPAN_CONTEXT_STRING_SIZE];
+    struct hpack_header_field hf;
+};
+
+struct {
+    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+    __uint(key_size, sizeof(u32));
+    __uint(value_size, sizeof(struct header_handler_storage));
+    __uint(max_entries, 1);
+} header_handler_storage_map SEC(".maps");
+
 // Injected in init
-volatile const u64 clientconn_target_ptr_pos;
-volatile const u64 httpclient_nextid_pos;
+// volatile const u64 clientconn_target_ptr_pos;
+u64 clientconn_target_ptr_pos = 24;
+// volatile const u64 httpclient_nextid_pos;
+u64 httpclient_nextid_pos = 404;
 // volatile const u64 headerFrame_streamid_pos;
 u64 headerFrame_streamid_pos = 0;
 // volatile const u64 headerFrame_hf_pos;
 u64 headerFrame_hf_pos = 8;
-volatile const u64 error_status_pos;
-volatile const u64 status_s_pos;
-volatile const u64 status_message_pos;
-volatile const u64 status_code_pos;
+// volatile const u64 error_status_pos;
+u64 error_status_pos = 0;
+// volatile const u64 status_s_pos;
+// static u64 status_s_pos = 0;
+// volatile const u64 status_message_pos;
+u64 status_message_pos = 48;
+// volatile const u64 status_code_pos;
+// static u64 status_code_pos = 40;
 
 volatile const bool write_status_supported;
 
@@ -186,6 +206,7 @@ int uprobe_ClientConn_Invoke_Returns(struct pt_regs *ctx) {
         (void *)(s_ptr + status_message_pos), grpc_span->err_msg, sizeof(grpc_span->err_msg));
 
 done:
+    bpf_printk("switch to the done position\n");
     grpc_span->end_time = bpf_ktime_get_ns();
     // output_span_event(ctx, grpc_span, sizeof(*grpc_span), &grpc_span->sc);
     stop_tracking_span(&grpc_span->sc, &grpc_span->psc);
@@ -193,112 +214,26 @@ done:
     return 0;
 }
 
-// func (l *loopyWriter) headerHandler(h *headerFrame) error
-// SEC("uprobe/loopyWriter_headerHandler")
-// int uprobe_LoopyWriter_HeaderHandler(struct pt_regs *ctx) {
-//     bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler \n");
-//     void *headerFrame_ptr = get_argument(ctx, 2);
-//     // u32 stream_id = 0;
-//     // bpf_probe_read(
-//     //     &stream_id, sizeof(stream_id), (void *)(headerFrame_ptr + (headerFrame_streamid_pos)));
-//     // void *sc_ptr = bpf_map_lookup_elem(&streamid_to_span_contexts, &stream_id);
-//     // if (sc_ptr == NULL) {
-//     //     return 0;
-//     // }
-//     bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler1111 \n");
-//     __u64 pid_tgid = bpf_get_current_pid_tgid();
-// 	__u32 tgid = pid_tgid >> 32;
-// 	struct ebpf_proc_info *proc_info =
-// 			bpf_map_lookup_elem(&proc_info_map, &tgid);
-//     if(!proc_info)
-//     {
-//         return 0;
-//     }
-
-//     bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler2222222\n");
-//     // struct span_context current_span_context = {};
-//     // bpf_probe_read(&current_span_context, sizeof(current_span_context), sc_ptr);
-
-//     char tp_key[CW_HEADER_KEY_LENGTH] = CW_HEADER_KEY_VAL;
-//     struct go_string_ot key_str = write_user_go_string(tp_key, sizeof(tp_key));
-//     if (key_str.len == 0) {
-//         bpf_printk("key write failed, aborting ebpf probe");
-//         goto done;
-//     }
-
-
-//     bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler333333\n");
-//     u32 map_id = 0;
-//     struct grpc_client_request_t *grpcClientReq = bpf_map_lookup_elem(&grpc_client_storage_map, &map_id);
-//     if (grpcClientReq == NULL)
-//     {
-//         cw_bpf_debug("uprobe_LoopyWriter_HeaderHandler: grpcClientReq is NULL");
-//         return 0;
-//     }
-
-//     __builtin_memset(grpcClientReq, 0, sizeof(struct grpc_client_request_t));
-//     grpcClientReq->start_time = bpf_ktime_get_ns();
-
-//     bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler444444\n");
-// 	struct apm_span_context *cw_psc = cw_get_parent_tracking_span();
-// 	if(cw_psc){
-// 		bpf_probe_read(&grpcClientReq->apm_psc, sizeof(grpcClientReq->apm_psc), cw_psc);
-// 		copy_byte_arrays(grpcClientReq->apm_psc.trace_id, grpcClientReq->apm_sc.trace_id, APM_TRACE_ID_SIZE);
-// 		generate_random_bytes(grpcClientReq->apm_sc.span_id, APM_SPAN_ID_SIZE);
-// 	}
-
-//     u32 k0 = 0;
-// 	struct trace_conf_t *trace_conf = trace_conf_map__lookup(&k0);
-// 	if (trace_conf) {
-// 		copy_byte_arrays(trace_conf->host_id, grpcClientReq->apm_sc.host_id, APM_HOST_ID_SIZE);
-// 	}
-
-//     copy_byte_arrays(proc_info->instance_id, grpcClientReq->apm_sc.instance_id, APM_APP_ID_SIZE);
-// 	copy_byte_arrays(proc_info->app_id, grpcClientReq->apm_sc.app_id, APM_APP_ID_SIZE);
-
-//     // set assumed_app_id
-// 	// set_assumed_app_id_arrays(httpReq->host, httpReq->apm_sc.assumed_app_id, APM_ASSUMED_APP_ID_STRING_SIZE);
-// 	cw_save_current_tracking_span(&grpcClientReq->apm_sc);
-
-//     // Write headers
-//     char val[CW_HEADER_VAL_LENGTH];
-// 	span_context_to_cw_string(&grpcClientReq->apm_sc, val);
-//     struct go_string_ot val_str = write_user_go_string(val, sizeof(val));
-//     if (val_str.len == 0) {
-//         bpf_printk("val write failed, aborting ebpf probe");
-//         goto done;
-//     }
-//     bpf_printk("enter the uprobe_LoopyWriter_HeaderHandler6666\n");
-//     struct hpack_header_field hf = {};
-//     hf.name = key_str;
-//     hf.value = val_str;
-//     append_item_to_slice(&hf, sizeof(hf), (void *)(headerFrame_ptr + (headerFrame_hf_pos)));
-// done:
-//     // bpf_map_delete_elem(&streamid_to_span_contexts, &stream_id);
-
-//     return 0;
-// }
-
 
 static __always_inline void
 cw_append_item_to_slice(void *new_item, u32 item_size, void *slice_user_ptr) {
     // read the slice descriptor
     struct go_slice_ot slice = {0};
-    bpf_probe_read(&slice, sizeof(slice), slice_user_ptr);
-    long res = 0;
+    long res = bpf_probe_read_user(&slice, sizeof(slice), slice_user_ptr);
+    if (res != 0) {
+        bpf_printk("cw_append_item_to_slice: failed to read slice descriptor, res=%ld\n", res);
+        return;
+    }
 
     bpf_printk("cw_append_item_to_slice len is %d\n", slice.len);
     bpf_printk("cw_append_item_to_slice cap is %d\n", slice.cap);
+    bpf_printk("cw_append_item_to_slice array is %p\n", slice.array);
 
     u64 slice_len = slice.len;
     u64 slice_cap = slice.cap;
     if (slice_len < slice_cap && slice.array != NULL) {
         // Room available on current array, append to the underlying array
         bpf_printk("enter the cw_append_item_to_slice11111\n");
-        // struct hpack_header_field hf = {};
-        // bpf_probe_read(&hf, sizeof(hf), slice.array + (item_size * 6));
-        // bpf_printk("cw_append_item_to_slice hf.name.str is %s\n", hf.name.str);
-        // bpf_printk("cw_append_item_to_slice hf.value.str is %s\n", hf.value.str);
         res = bpf_probe_write_user(slice.array + (item_size * slice_len), new_item, item_size);
     } else {
         // No room on current array - try to copy new one of size item_size * (len + 1)
@@ -359,41 +294,61 @@ cw_append_item_to_slice(void *new_item, u32 item_size, void *slice_user_ptr) {
 SEC("uprobe/loopyWriter_headerHandler")
 int uprobe_LoopyWriter_HeaderHandler(struct pt_regs *ctx) {
     void *headerFrame_ptr = get_argument(ctx, 2);
-    u32 stream_id = 0;
-    bpf_probe_read(
-        &stream_id, sizeof(stream_id), (void *)(headerFrame_ptr + (headerFrame_streamid_pos)));
-    // void *sc_ptr = bpf_map_lookup_elem(&streamid_to_span_contexts, &stream_id);
-    // if (sc_ptr == NULL) {
-    //     return 0;
-    // }
-
-    // struct span_context current_span_context = {};
-    // bpf_probe_read(&current_span_context, sizeof(current_span_context), sc_ptr);
+    bpf_printk("enter the get header handler storage\n");
+    
+    // Get storage from per-cpu map
+    u32 zero = 0;
+    struct header_handler_storage *storage = bpf_map_lookup_elem(&header_handler_storage_map, &zero);
+    if (!storage) {
+        bpf_printk("Failed to get header handler storage\n");
+        return 0;
+    }
+    
+    // Generate span context
+    generate_random_bytes(storage->sc.TraceID, TRACE_ID_SIZE);
+    generate_random_bytes(storage->sc.SpanID, SPAN_ID_SIZE);
 
+    // Strategy: Write key and value separately with manual offset
+    // First write the key
     char tp_key[11] = "traceparent";
-    struct go_string_ot key_str = write_user_go_string(tp_key, sizeof(tp_key));
-    if (key_str.len == 0) {
-        bpf_printk("key write failed, aborting ebpf probe");
-        goto done;
+    char *key_data_addr = write_target_data((void *)tp_key, sizeof(tp_key));
+    if (key_data_addr == NULL) {
+        bpf_printk("Key data write failed\n");
+        return 0;
     }
-
-    // Write headers
-    char val[SPAN_CONTEXT_STRING_SIZE] = "11111111";
-    // span_context_to_w3c_string(&current_span_context, val);
-    struct go_string_ot val_str = write_user_go_string(val, sizeof(val));
-    if (val_str.len == 0) {
-        bpf_printk("val write failed, aborting ebpf probe");
-        goto done;
+    bpf_printk("key_data_addr=%p\n", key_data_addr);
+    
+    // Manually advance the pointer for value (workaround for alloc_map bug)
+    // Allocate enough space: align to 8 bytes
+    u64 key_size_aligned = ((sizeof(tp_key) + 7) / 8) * 8;
+    
+    // Write value at offset from key
+    span_context_to_w3c_string(&storage->sc, storage->val);
+    
+    // Try to write value with manual offset
+    char *val_data_addr = key_data_addr + key_size_aligned;
+    long val_write_result = bpf_probe_write_user(val_data_addr, storage->val, sizeof(storage->val));
+    bpf_printk("val_data_addr=%p, write_result=%ld\n", val_data_addr, val_write_result);
+    
+    if (val_write_result != 0) {
+        bpf_printk("Val direct write failed\n");
+        return 0;
     }
-    struct hpack_header_field hf = {};
-    hf.name = key_str;
-    hf.value = val_str;
-    hf.sensitive = false;
-    bpf_printk("uprobe_LoopyWriter_HeaderHandler hf.name.str is %s\n", key_str.str);
-    bpf_printk("uprobe_LoopyWriter_HeaderHandler hf.value.str is %s\n", val_str.str);
-    cw_append_item_to_slice(&hf, sizeof(hf), (void *)(headerFrame_ptr + (headerFrame_hf_pos)));
-done:
-    bpf_map_delete_elem(&streamid_to_span_contexts, &stream_id);
+    
+    struct go_string_ot key_str = {.str = key_data_addr, .len = sizeof(tp_key)};
+    struct go_string_ot val_str = {.str = val_data_addr, .len = sizeof(storage->val)};
+    
+    bpf_printk("key_str: len=%d, ptr=%p\n", key_str.len, key_str.str);
+    bpf_printk("val_str: len=%d, ptr=%p\n", val_str.len, val_str.str);
+    
+    // Build header field
+    storage->hf.name = key_str;
+    storage->hf.value = val_str;
+    storage->hf.sensitive = false;
+    
+    // Append to slice
+    void *slice_ptr = (void *)(headerFrame_ptr + headerFrame_hf_pos);
+    cw_append_item_to_slice(&storage->hf, sizeof(storage->hf), slice_ptr);
 
     return 0;
 }
@@ -411,6 +366,7 @@ int uprobe_http2Client_NewStream(struct pt_regs *ctx) {
     // // the context here is derived from the Invoke context.
     // struct span_context *current_span_context = get_parent_span_context(&go_context);
     // if (current_span_context != NULL) {
+    //     bpf_printk("uprobe_http2Client_NewStream streamid is %d\n", nextid);
     //     bpf_map_update_elem(&streamid_to_span_contexts, &nextid, current_span_context, 0);
     // }
 

+ 20 - 10
ebpftracer/ebpf/utrace/go/net/grpc.server.probe.bpf.c

@@ -63,16 +63,26 @@ struct hpack_header_field {
 // Injected in init
 // volatile const u64 stream_method_ptr_pos;
 u64 stream_method_ptr_pos = 80;
-volatile const u64 frame_fields_pos;
-volatile const u64 frame_stream_id_pod;
-volatile const u64 stream_id_pos;
-volatile const u64 stream_ctx_pos;
-volatile const u64 server_stream_stream_pos;
-volatile const bool is_new_frame_pos;
-volatile const u64 status_s_pos;
-volatile const u64 status_code_pos;
-volatile const u64 http2server_peer_pos;
-volatile const u64 peer_local_addr_pos;
+// volatile const u64 frame_fields_pos;
+u64 frame_fields_pos = 8;
+// volatile const u64 frame_stream_id_pod;
+u64 frame_stream_id_pod = 8;
+// volatile const u64 stream_id_pos;
+u64 stream_id_pos = 0;
+// volatile const u64 stream_ctx_pos;
+u64 stream_ctx_pos = 32;
+// volatile const u64 server_stream_stream_pos;
+u64 server_stream_stream_pos;
+// volatile const bool is_new_frame_pos;
+bool is_new_frame_pos;
+// volatile const u64 status_s_pos;
+static u64 status_s_pos = 0;
+// volatile const u64 status_code_pos;
+static u64 status_code_pos = 40;
+// volatile const u64 http2server_peer_pos;
+u64 http2server_peer_pos;
+// volatile const u64 peer_local_addr_pos;
+u64 peer_local_addr_pos;
 
 volatile const bool server_addr_supported;