.. | .. |
---|
604 | 604 | offset < btf->hdr.str_len; |
---|
605 | 605 | } |
---|
606 | 606 | |
---|
607 | | -static bool __btf_name_char_ok(char c, bool first, bool dot_ok) |
---|
| 607 | +static bool __btf_name_char_ok(char c, bool first) |
---|
608 | 608 | { |
---|
609 | 609 | if ((first ? !isalpha(c) : |
---|
610 | 610 | !isalnum(c)) && |
---|
611 | 611 | c != '_' && |
---|
612 | | - ((c == '.' && !dot_ok) || |
---|
613 | | - c != '.')) |
---|
| 612 | + c != '.') |
---|
614 | 613 | return false; |
---|
615 | 614 | return true; |
---|
616 | 615 | } |
---|
617 | 616 | |
---|
618 | | -static bool __btf_name_valid(const struct btf *btf, u32 offset, bool dot_ok) |
---|
| 617 | +static bool __btf_name_valid(const struct btf *btf, u32 offset) |
---|
619 | 618 | { |
---|
620 | 619 | /* offset must be valid */ |
---|
621 | 620 | const char *src = &btf->strings[offset]; |
---|
622 | 621 | const char *src_limit; |
---|
623 | 622 | |
---|
624 | | - if (!__btf_name_char_ok(*src, true, dot_ok)) |
---|
| 623 | + if (!__btf_name_char_ok(*src, true)) |
---|
625 | 624 | return false; |
---|
626 | 625 | |
---|
627 | 626 | /* set a limit on identifier length */ |
---|
628 | 627 | src_limit = src + KSYM_NAME_LEN; |
---|
629 | 628 | src++; |
---|
630 | 629 | while (*src && src < src_limit) { |
---|
631 | | - if (!__btf_name_char_ok(*src, false, dot_ok)) |
---|
| 630 | + if (!__btf_name_char_ok(*src, false)) |
---|
632 | 631 | return false; |
---|
633 | 632 | src++; |
---|
634 | 633 | } |
---|
.. | .. |
---|
636 | 635 | return !*src; |
---|
637 | 636 | } |
---|
638 | 637 | |
---|
639 | | -/* Only C-style identifier is permitted. This can be relaxed if |
---|
640 | | - * necessary. |
---|
641 | | - */ |
---|
642 | 638 | static bool btf_name_valid_identifier(const struct btf *btf, u32 offset) |
---|
643 | 639 | { |
---|
644 | | - return __btf_name_valid(btf, offset, false); |
---|
| 640 | + return __btf_name_valid(btf, offset); |
---|
645 | 641 | } |
---|
646 | 642 | |
---|
647 | 643 | static bool btf_name_valid_section(const struct btf *btf, u32 offset) |
---|
648 | 644 | { |
---|
649 | | - return __btf_name_valid(btf, offset, true); |
---|
| 645 | + return __btf_name_valid(btf, offset); |
---|
650 | 646 | } |
---|
651 | 647 | |
---|
652 | 648 | static const char *__btf_name_by_offset(const struct btf *btf, u32 offset) |
---|
.. | .. |
---|
3417 | 3413 | } |
---|
3418 | 3414 | |
---|
3419 | 3415 | if (!t->name_off || |
---|
3420 | | - !__btf_name_valid(env->btf, t->name_off, true)) { |
---|
| 3416 | + !__btf_name_valid(env->btf, t->name_off)) { |
---|
3421 | 3417 | btf_verifier_log_type(env, t, "Invalid name"); |
---|
3422 | 3418 | return -EINVAL; |
---|
3423 | 3419 | } |
---|
.. | .. |
---|
3541 | 3537 | struct btf *btf = env->btf; |
---|
3542 | 3538 | u16 i; |
---|
3543 | 3539 | |
---|
| 3540 | + env->resolve_mode = RESOLVE_TBD; |
---|
3544 | 3541 | for_each_vsi_from(i, v->next_member, v->t, vsi) { |
---|
3545 | 3542 | u32 var_type_id = vsi->type, type_id, type_size = 0; |
---|
3546 | 3543 | const struct btf_type *var_type = btf_type_by_id(env->btf, |
---|
.. | .. |
---|
3673 | 3670 | btf_verifier_log_type(env, t, "Invalid arg#%u", i + 1); |
---|
3674 | 3671 | err = -EINVAL; |
---|
3675 | 3672 | break; |
---|
| 3673 | + } |
---|
| 3674 | + |
---|
| 3675 | + if (btf_type_is_resolve_source_only(arg_type)) { |
---|
| 3676 | + btf_verifier_log_type(env, t, "Invalid arg#%u", i + 1); |
---|
| 3677 | + return -EINVAL; |
---|
3676 | 3678 | } |
---|
3677 | 3679 | |
---|
3678 | 3680 | if (args[i].name_off && |
---|
.. | .. |
---|
4268 | 4270 | if (!ctx_struct) |
---|
4269 | 4271 | /* should not happen */ |
---|
4270 | 4272 | return NULL; |
---|
| 4273 | +again: |
---|
4271 | 4274 | ctx_tname = btf_name_by_offset(btf_vmlinux, ctx_struct->name_off); |
---|
4272 | 4275 | if (!ctx_tname) { |
---|
4273 | 4276 | /* should not happen */ |
---|
.. | .. |
---|
4281 | 4284 | * int socket_filter_bpf_prog(struct __sk_buff *skb) |
---|
4282 | 4285 | * { // no fields of skb are ever used } |
---|
4283 | 4286 | */ |
---|
4284 | | - if (strcmp(ctx_tname, tname)) |
---|
4285 | | - return NULL; |
---|
| 4287 | + if (strcmp(ctx_tname, tname)) { |
---|
| 4288 | + /* bpf_user_pt_regs_t is a typedef, so resolve it to |
---|
| 4289 | + * underlying struct and check name again |
---|
| 4290 | + */ |
---|
| 4291 | + if (!btf_type_is_modifier(ctx_struct)) |
---|
| 4292 | + return NULL; |
---|
| 4293 | + while (btf_type_is_modifier(ctx_struct)) |
---|
| 4294 | + ctx_struct = btf_type_by_id(btf_vmlinux, ctx_struct->type); |
---|
| 4295 | + goto again; |
---|
| 4296 | + } |
---|
4286 | 4297 | return ctx_type; |
---|
4287 | 4298 | } |
---|
4288 | 4299 | |
---|