函数源码 |
Source File:kernel\bpf\btf.c |
Create Date:2022-07-27 14:38:45 |
首页 | Copyright©Brick |
3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 | bool btf_ctx_access( int off, int size, enum bpf_access_type type, const struct bpf_prog *prog, struct bpf_insn_access_aux *info) { const struct btf_type *t = prog->aux->attach_func_proto; struct bpf_prog *tgt_prog = prog->aux->linked_prog; struct btf *btf = bpf_prog_get_target_btf(prog); const char *tname = prog->aux->attach_func_name; struct bpf_verifier_log * log = info-> log ; const struct btf_param *args; u32 nr_args, arg; int ret; if (off % 8) { bpf_log( log , "func '%s' offset %d is not multiple of 8\n" , tname, off); return false ; } arg = off / 8; args = ( const struct btf_param *)(t + 1); /* if (t == NULL) Fall back to default BPF prog with 5 u64 arguments */ nr_args = t ? btf_type_vlen(t) : 5; if (prog->aux->attach_btf_trace) { /* skip first 'void *__data' argument in btf_trace_##name typedef */ args++; nr_args--; } if (prog->expected_attach_type == BPF_TRACE_FEXIT && arg == nr_args) { if (!t) /* Default prog with 5 args. 6th arg is retval. */ return true ; /* function return type */ t = btf_type_by_id(btf, t->type); } else if (arg >= nr_args) { bpf_log( log , "func '%s' doesn't have %d-th argument\n" , tname, arg + 1); return false ; } else { if (!t) /* Default prog with 5 args */ return true ; t = btf_type_by_id(btf, args[arg].type); } /* skip modifiers */ while (btf_type_is_modifier(t)) t = btf_type_by_id(btf, t->type); if (btf_type_is_int(t)) /* accessing a scalar */ return true ; if (!btf_type_is_ptr(t)) { bpf_log( log , "func '%s' arg%d '%s' has type %s. Only pointer access is allowed\n" , tname, arg, __btf_name_by_offset(btf, t->name_off), btf_kind_str[BTF_INFO_KIND(t->info)]); return false ; } if (t->type == 0) /* This is a pointer to void. * It is the same as scalar from the verifier safety pov. * No further pointer walking is allowed. */ return true ; /* this is a pointer to another type */ info->reg_type = PTR_TO_BTF_ID; info->btf_id = t->type; if (tgt_prog) { ret = btf_translate_to_vmlinux( log , btf, t, tgt_prog->type); if (ret > 0) { info->btf_id = ret; return true ; } else { return false ; } } t = btf_type_by_id(btf, t->type); /* skip modifiers */ while (btf_type_is_modifier(t)) t = btf_type_by_id(btf, t->type); if (!btf_type_is_struct(t)) { bpf_log( log , "func '%s' arg%d type %s is not a struct\n" , tname, arg, btf_kind_str[BTF_INFO_KIND(t->info)]); return false ; } bpf_log( log , "func '%s' arg%d has btf_id %d type %s '%s'\n" , tname, arg, info->btf_id, btf_kind_str[BTF_INFO_KIND(t->info)], __btf_name_by_offset(btf, t->name_off)); return true ; } |