@@ -185,93 +185,22 @@ struct {
185185 __uint (max_entries , 1 );
186186} syscall_filter SEC (".maps" );
187187
188-
189- // static __always_inline u32 read_args(program_data_t p, struct syscall_point_args_t* syscall_point_args, args_t* args, u32 check_flag, u32 next_arg_index, u32 read_) {
190- // u32 point_arg_count = MAX_POINT_ARG_COUNT;
191- // if (syscall_point_args->count <= point_arg_count) {
192- // point_arg_count = syscall_point_args->count;
193- // }
194- // for (int i = 0; i < point_arg_count; i++) {
195- // u64 ptr = args->args[i];
196- // // 保存参数的寄存器
197- // save_to_submit_buf(p.event, (void *)ptr, sizeof(u64), next_arg_index);
198- // next_arg_index += 1;
199- // struct point_arg_t* point_arg = (struct point_arg_t*) &syscall_point_args->point_args[i];
200- // if (point_arg->read_flag != SYS_ENTER_EXIT) {
201- // if (point_arg->read_flag != check_flag) {
202- // continue;
203- // }
204- // }
205- // if (point_arg->type == TYPE_NONE) {
206- // continue;
207- // }
208- // if (point_arg->type == TYPE_NUM) {
209- // // 这种具体类型转换交给前端做
210- // continue;
211- // }
212- // if (point_arg->type == TYPE_STRING) {
213- // u32 buf_off = 0;
214- // buf_t *string_p = get_buf(STRING_BUF_IDX);
215- // if (string_p == NULL) {
216- // continue;
217- // }
218- // int status = bpf_probe_read_user(&string_p->buf[buf_off], MAX_STRING_SIZE, (void *)ptr);
219- // if (status < 0) {
220- // // MTE 其实也正常读取到了
221- // bpf_probe_read_user_str(&string_p->buf[buf_off], MAX_STRING_SIZE, (void *)ptr);
222- // }
223- // save_str_to_buf(p.event, &string_p->buf[buf_off], next_arg_index);
224- // next_arg_index += 1;
225- // continue;
226- // }
227- // if (point_arg->type == TYPE_STRING_ARR && ptr != 0) {
228- // save_str_arr_to_buf(p.event, (const char *const *) ptr /*ptr*/, next_arg_index);
229- // next_arg_index += 1;
230- // continue;
231- // }
232- // if (point_arg->type == TYPE_POINTER) {
233- // // 指针类型 通常读一下对应指针的数据即可 后续记得考虑兼容下32位
234-
235- // // point_arg->alias_type
236- // // 某些成员是指针 有可能有必要再深入读取
237- // // 这个时候可以根据 alias_type 取出对应的参数配置 然后解析保存
238- // // 这个后面增补
239-
240- // // if (point_arg->alias_type == TYPE_BY) {
241-
242- // // }
243-
244- // u64 addr = 0;
245- // bpf_probe_read_user(&addr, sizeof(addr), (void*) ptr);
246- // save_to_submit_buf(p.event, (void *) &addr, sizeof(u64), next_arg_index);
247- // next_arg_index += 1;
248- // continue;
249- // }
250- // if (point_arg->type == TYPE_STRUCT && ptr != 0) {
251- // // 结构体类型 直接读取对应大小的数据 具体转换交给前端
252- // u32 struct_size = MAX_BYTES_ARR_SIZE;
253- // if (point_arg->size <= struct_size) {
254- // struct_size = point_arg->size;
255- // }
256- // // 修复 MTE 读取可能不正常的情况
257- // int status = save_bytes_to_buf(p.event, (void *)(ptr & 0xffffffffff), struct_size, next_arg_index);
258- // if (status == 0) {
259- // // 保存失败的情况 比如 ptr 是一个非法的地址 ...
260- // buf_t *zero_p = get_buf(ZERO_BUF_IDX);
261- // if (zero_p == NULL) {
262- // continue;
263- // }
264- // // 这个时候填充一个全0的内容进去 不然前端不好解析
265- // save_bytes_to_buf(p.event, &zero_p->buf[0], struct_size, next_arg_index);
266- // next_arg_index += 1;
267- // } else {
268- // next_arg_index += 1;
269- // }
270- // }
271- // }
272- // return next_arg_index;
273- // }
274- static __always_inline u32 read_arg (program_data_t p , struct point_arg_t * point_arg , u64 ptr , u32 read_len , u32 next_arg_index ) {
188+ static __always_inline u32 save_bytes_with_len (program_data_t p , u64 ptr , u32 read_len , u32 next_arg_index ) {
189+ if (read_len > MAX_BUF_READ_SIZE ) {
190+ read_len = MAX_BUF_READ_SIZE ;
191+ }
192+ int status = save_bytes_to_buf (p .event , (void * )(ptr & 0xffffffffff ), read_len , next_arg_index );
193+ if (status == 0 ) {
194+ buf_t * zero_p = get_buf (ZERO_BUF_IDX );
195+ if (zero_p == NULL ) {
196+ return next_arg_index ;
197+ }
198+ save_bytes_to_buf (p .event , & zero_p -> buf [0 ], read_len , next_arg_index );
199+ }
200+ next_arg_index += 1 ;
201+ return next_arg_index ;
202+ }
203+ static __always_inline u32 read_arg (program_data_t p , struct point_arg_t * point_arg , u64 ptr , u32 read_count , u32 next_arg_index ) {
275204 if (point_arg -> type == TYPE_NONE ) {
276205 return next_arg_index ;
277206 }
@@ -306,13 +235,10 @@ static __always_inline u32 read_arg(program_data_t p, struct point_arg_t* point_
306235 // 某些成员是指针 有可能有必要再深入读取
307236 // 这个时候可以根据 alias_type 取出对应的参数配置 然后解析保存
308237 // 这个后面增补
309-
310238 if (point_arg -> alias_type == TYPE_BUFFER_T ) {
311- u32 aaa = MAX_BUF_READ_SIZE
312- if (read_len <= aaa ) {
313- aaa = read_len ;
314- }
315- int status = save_bytes_to_buf (p .event , (void * )(ptr & 0xffffffffff ), aaa , next_arg_index );
239+ // buffer 的单个元素长度就是 1 所以这里就是 read_count
240+ u32 read_len = read_count * 1 ;
241+ int status = save_bytes_to_buf (p .event , (void * )(ptr & 0xffffffffff ), read_len , next_arg_index );
316242 if (status == 0 ) {
317243 buf_t * zero_p = get_buf (ZERO_BUF_IDX );
318244 if (zero_p == NULL ) {
@@ -333,6 +259,32 @@ static __always_inline u32 read_arg(program_data_t p, struct point_arg_t* point_
333259 return next_arg_index ;
334260 }
335261 if (point_arg -> type == TYPE_STRUCT && ptr != 0 ) {
262+
263+ if (point_arg -> alias_type == TYPE_IOVEC ) {
264+ struct iovec iovec_ptr ;
265+ int errno = bpf_probe_read_user (& iovec_ptr , sizeof (iovec_ptr ), (void * ) ptr );
266+ if (errno == 0 ) {
267+ save_to_submit_buf (p .event , (void * )& iovec_ptr , sizeof (iovec_ptr ), next_arg_index );
268+ next_arg_index += 1 ;
269+ // 目前这样只是读取了第一个 iov 实际上要多次读取 数量是 iovcnt
270+ // 但是注意多个缓冲区并不是连续的
271+ u64 iov_base = (u64 )iovec_ptr .iov_base ;
272+ u32 iov_len = (u64 )iovec_ptr .iov_len ;
273+ // u32 read_len = read_count * iov_len;
274+ u32 read_len = iov_len ;
275+ if (read_len > MAX_BUF_READ_SIZE ) {
276+ read_len = MAX_BUF_READ_SIZE ;
277+ }
278+ // save_to_submit_buf(p.event, (void *)&iov_base, sizeof(iov_base), next_arg_index);
279+ // next_arg_index += 1;
280+ // // 注意 这里存放的大小是 u64 与结构体大小保持一致
281+ // save_to_submit_buf(p.event, (void *)&read_len, sizeof(read_len), next_arg_index);
282+ // next_arg_index += 1;
283+ next_arg_index = save_bytes_with_len (p , iov_base , read_len , next_arg_index );
284+ return next_arg_index ;
285+ }
286+ }
287+
336288 // 结构体类型 直接读取对应大小的数据 具体转换交给前端
337289 u32 struct_size = MAX_BYTES_ARR_SIZE ;
338290 if (point_arg -> size <= struct_size ) {
@@ -520,9 +472,6 @@ int raw_syscalls_sys_enter(struct bpf_raw_tracepoint_args* ctx) {
520472 point_arg_count = syscall_point_args -> count ;
521473 }
522474
523-
524- // int next_arg_index = read_args(p, syscall_point_args, &args, SYS_ENTER, 4);
525-
526475 int next_arg_index = 4 ;
527476 // #pragma unroll
528477 for (int i = 0 ; i < point_arg_count ; i ++ ) {
@@ -533,31 +482,23 @@ int raw_syscalls_sys_enter(struct bpf_raw_tracepoint_args* ctx) {
533482 if (point_arg -> read_flag != SYS_ENTER ) {
534483 continue ;
535484 }
536- // 如果是要读取 buffer
537- // u32 read_len = 0;
538- // if (point_arg->alias_type == TYPE_BUFFER_T) {
539- // u32 item_count = args.args[point_arg->item_countindex];
540- // u32 item_persize = point_arg->item_persize;
541- // if (item_count <= MAX_BUF_READ_SIZE && item_persize < MAX_BUF_READ_SIZE) {
542- // read_len = item_count * item_persize;
543- // }
544- // // u32 item_count = args.args[point_arg->item_countindex];
545- // // if (item_count <= MAX_BUF_READ_SIZE) {
546- // // read_len = item_count;
547- // // } else {
548- // // read_len = MAX_BUF_READ_SIZE;
549- // // }
550- // }
551- // if (read_len >= MAX_BUF_READ_SIZE) {
552- // read_len = MAX_BUF_READ_SIZE;
553- // }
554-
555- u32 read_len = MAX_BUF_READ_SIZE ;
556- if (args .args [point_arg -> item_countindex ] <= read_len ) {
557- read_len = args .args [point_arg -> item_countindex ];
485+ u32 read_count = MAX_BUF_READ_SIZE ;
486+ if (point_arg -> item_countindex >= 0 ) {
487+ // math between fp pointer and register with unbounded min value is not allowed
488+ // 后面取寄存器可能存在越界 所以必须保证索引必须是在正确的范围内
489+ // 这里必须把 item_countindex 赋值给临时变量 并且必须转换类型
490+ // 然后通过 if 比较来明确它不会越界 然后后面再用它作为取寄存器的索引
491+ // 最后计算要读取数据的最终大小 当然这里也必须有一个上限大小
492+ u32 item_index = (u32 ) point_arg -> item_countindex ;
493+ if (item_index >= 6 ) {
494+ return 0 ;
495+ }
496+ u32 item_count = (u32 ) args .args [item_index ];
497+ if (item_count <= read_count ) {
498+ read_count = item_count ;
499+ }
558500 }
559-
560- next_arg_index = read_arg (p , point_arg , args .args [i ], read_len , next_arg_index );
501+ next_arg_index = read_arg (p , point_arg , args .args [i ], read_count , next_arg_index );
561502 }
562503 events_perf_submit (& p , SYSCALL_ENTER );
563504 return 0 ;
@@ -662,8 +603,6 @@ int raw_syscalls_sys_exit(struct bpf_raw_tracepoint_args* ctx) {
662603 save_to_submit_buf (p .event , (void * ) & syscallno , sizeof (u32 ), next_arg_index );
663604 next_arg_index += 1 ;
664605
665- // next_arg_index = read_args(p, syscall_point_args, &saved_args, SYS_EXIT, next_arg_index);
666-
667606 u32 point_arg_count = MAX_POINT_ARG_COUNT ;
668607 if (syscall_point_args -> count <= point_arg_count ) {
669608 point_arg_count = syscall_point_args -> count ;
@@ -677,7 +616,23 @@ int raw_syscalls_sys_exit(struct bpf_raw_tracepoint_args* ctx) {
677616 if (point_arg -> read_flag != SYS_EXIT ) {
678617 continue ;
679618 }
680- next_arg_index = read_arg (p , point_arg , saved_args .args [i ], 0 , next_arg_index );
619+ u32 read_count = MAX_BUF_READ_SIZE ;
620+ if (point_arg -> item_countindex >= 0 ) {
621+ // math between fp pointer and register with unbounded min value is not allowed
622+ // 后面取寄存器可能存在越界 所以必须保证索引必须是在正确的范围内
623+ // 这里必须把 item_countindex 赋值给临时变量 并且必须转换类型
624+ // 然后通过 if 比较来明确它不会越界 然后后面再用它作为取寄存器的索引
625+ // 最后计算要读取数据的最终大小 当然这里也必须有一个上限大小
626+ u32 item_index = (u32 ) point_arg -> item_countindex ;
627+ if (item_index >= 6 ) {
628+ return 0 ;
629+ }
630+ u32 item_count = (u32 ) saved_args .args [item_index ];
631+ if (item_count <= read_count ) {
632+ read_count = item_count ;
633+ }
634+ }
635+ next_arg_index = read_arg (p , point_arg , saved_args .args [i ], read_count , next_arg_index );
681636 }
682637 // 读取返回值
683638 u64 ret = READ_KERN (regs -> regs [0 ]);
0 commit comments