History

bpf: Small BPF verifier log improvements

In particular these include: 1) Remove output of inv for scalars in print_verifier_state 2) Replace inv with scalar in verifier error messages 3) Remove _value suffixes for umin/umax/s32_min/etc (except map_value) 4) Remove output of id=0 5) Remove output of ref_obj_id=0

Mykola Lysenko committed 4 years ago

Commit 7df50721 parent 41332d620 files · +203 −197Browse files

Showing the changes to kernel (1 of 20 files). Show all

Unified · Split

kernel/bpf/verifier.c+35−29
@@ -539,7 +539,7 @@ static const char *reg_type_str(struct bpf_verifier_env *env, · 538 unmodified lines
539 char postfix[16] = {0}, prefix[32] = {0};539 char postfix[16] = {0}, prefix[32] = {0};
540 static const char * const str[] = {540 static const char * const str[] = {
541 [NOT_INIT] = "?",541 [NOT_INIT] = "?",
542 [SCALAR_VALUE] = "inv",542 [SCALAR_VALUE] = "scalar",
543 [PTR_TO_CTX] = "ctx",543 [PTR_TO_CTX] = "ctx",
544 [CONST_PTR_TO_MAP] = "map_ptr",544 [CONST_PTR_TO_MAP] = "map_ptr",
545 [PTR_TO_MAP_VALUE] = "map_value",545 [PTR_TO_MAP_VALUE] = "map_value",
@@ -685,74 +685,80 @@ static void print_verifier_state(struct bpf_verifier_env *env, · 139 unmodified lines
685 continue;685 continue;
686 verbose(env, " R%d", i);686 verbose(env, " R%d", i);
687 print_liveness(env, reg->live);687 print_liveness(env, reg->live);
688 verbose(env, "=%s", reg_type_str(env, t));688 verbose(env, "=");
689 if (t == SCALAR_VALUE && reg->precise)689 if (t == SCALAR_VALUE && reg->precise)
690 verbose(env, "P");690 verbose(env, "P");
691 if ((t == SCALAR_VALUE || t == PTR_TO_STACK) &&691 if ((t == SCALAR_VALUE || t == PTR_TO_STACK) &&
692 tnum_is_const(reg->var_off)) {692 tnum_is_const(reg->var_off)) {
693 /* reg->off should be 0 for SCALAR_VALUE */693 /* reg->off should be 0 for SCALAR_VALUE */
694 verbose(env, "%s", t == SCALAR_VALUE ? "" : reg_type_str(env, t));
694 verbose(env, "%lld", reg->var_off.value + reg->off);695 verbose(env, "%lld", reg->var_off.value + reg->off);
695 } else {696 } else {
697 const char *sep = "";
698
699 verbose(env, "%s", reg_type_str(env, t));
696 if (base_type(t) == PTR_TO_BTF_ID ||700 if (base_type(t) == PTR_TO_BTF_ID ||
697 base_type(t) == PTR_TO_PERCPU_BTF_ID)701 base_type(t) == PTR_TO_PERCPU_BTF_ID)
698 verbose(env, "%s", kernel_type_name(reg->btf, reg->btf_id));702 verbose(env, "%s", kernel_type_name(reg->btf, reg->btf_id));
699 verbose(env, "(id=%d", reg->id);703 verbose(env, "(");
700 if (reg_type_may_be_refcounted_or_null(t))704/*
701 verbose(env, ",ref_obj_id=%d", reg->ref_obj_id);705 * _a stands for append, was shortened to avoid multiline statements below.
706 * This macro is used to output a comma separated list of attributes.
707 */
708#define verbose_a(fmt, ...) ({ verbose(env, "%s" fmt, sep, __VA_ARGS__); sep = ","; })
709
710 if (reg->id)
711 verbose_a("id=%d", reg->id);
712 if (reg_type_may_be_refcounted_or_null(t) && reg->ref_obj_id)
713 verbose_a("ref_obj_id=%d", reg->ref_obj_id);
702 if (t != SCALAR_VALUE)714 if (t != SCALAR_VALUE)
703 verbose(env, ",off=%d", reg->off);715 verbose_a("off=%d", reg->off);
704 if (type_is_pkt_pointer(t))716 if (type_is_pkt_pointer(t))
705 verbose(env, ",r=%d", reg->range);717 verbose_a("r=%d", reg->range);
706 else if (base_type(t) == CONST_PTR_TO_MAP ||718 else if (base_type(t) == CONST_PTR_TO_MAP ||
707 base_type(t) == PTR_TO_MAP_KEY ||719 base_type(t) == PTR_TO_MAP_KEY ||
708 base_type(t) == PTR_TO_MAP_VALUE)720 base_type(t) == PTR_TO_MAP_VALUE)
709 verbose(env, ",ks=%d,vs=%d",721 verbose_a("ks=%d,vs=%d",
710 reg->map_ptr->key_size,722 reg->map_ptr->key_size,
711 reg->map_ptr->value_size);723 reg->map_ptr->value_size);
712 if (tnum_is_const(reg->var_off)) {724 if (tnum_is_const(reg->var_off)) {
713 /* Typically an immediate SCALAR_VALUE, but725 /* Typically an immediate SCALAR_VALUE, but
714 * could be a pointer whose offset is too big726 * could be a pointer whose offset is too big
715 * for reg->off727 * for reg->off
716 */728 */
717 verbose(env, ",imm=%llx", reg->var_off.value);729 verbose_a("imm=%llx", reg->var_off.value);
718 } else {730 } else {
719 if (reg->smin_value != reg->umin_value &&731 if (reg->smin_value != reg->umin_value &&
720 reg->smin_value != S64_MIN)732 reg->smin_value != S64_MIN)
721 verbose(env, ",smin_value=%lld",733 verbose_a("smin=%lld", (long long)reg->smin_value);
722 (long long)reg->smin_value);
723 if (reg->smax_value != reg->umax_value &&734 if (reg->smax_value != reg->umax_value &&
724 reg->smax_value != S64_MAX)735 reg->smax_value != S64_MAX)
725 verbose(env, ",smax_value=%lld",736 verbose_a("smax=%lld", (long long)reg->smax_value);
726 (long long)reg->smax_value);
727 if (reg->umin_value != 0)737 if (reg->umin_value != 0)
728 verbose(env, ",umin_value=%llu",738 verbose_a("umin=%llu", (unsigned long long)reg->umin_value);
729 (unsigned long long)reg->umin_value);
730 if (reg->umax_value != U64_MAX)739 if (reg->umax_value != U64_MAX)
731 verbose(env, ",umax_value=%llu",740 verbose_a("umax=%llu", (unsigned long long)reg->umax_value);
732 (unsigned long long)reg->umax_value);
733 if (!tnum_is_unknown(reg->var_off)) {741 if (!tnum_is_unknown(reg->var_off)) {
734 char tn_buf[48];742 char tn_buf[48];
735 743
736 tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);744 tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
737 verbose(env, ",var_off=%s", tn_buf);745 verbose_a("var_off=%s", tn_buf);
738 }746 }
739 if (reg->s32_min_value != reg->smin_value &&747 if (reg->s32_min_value != reg->smin_value &&
740 reg->s32_min_value != S32_MIN)748 reg->s32_min_value != S32_MIN)
741 verbose(env, ",s32_min_value=%d",749 verbose_a("s32_min=%d", (int)(reg->s32_min_value));
742 (int)(reg->s32_min_value));
743 if (reg->s32_max_value != reg->smax_value &&750 if (reg->s32_max_value != reg->smax_value &&
744 reg->s32_max_value != S32_MAX)751 reg->s32_max_value != S32_MAX)
745 verbose(env, ",s32_max_value=%d",752 verbose_a("s32_max=%d", (int)(reg->s32_max_value));
746 (int)(reg->s32_max_value));
747 if (reg->u32_min_value != reg->umin_value &&753 if (reg->u32_min_value != reg->umin_value &&
748 reg->u32_min_value != U32_MIN)754 reg->u32_min_value != U32_MIN)
749 verbose(env, ",u32_min_value=%d",755 verbose_a("u32_min=%d", (int)(reg->u32_min_value));
750 (int)(reg->u32_min_value));
751 if (reg->u32_max_value != reg->umax_value &&756 if (reg->u32_max_value != reg->umax_value &&
752 reg->u32_max_value != U32_MAX)757 reg->u32_max_value != U32_MAX)
753 verbose(env, ",u32_max_value=%d",758 verbose_a("u32_max=%d", (int)(reg->u32_max_value));
754 (int)(reg->u32_max_value));
755 }759 }
760#undef verbose_a
761
756 verbose(env, ")");762 verbose(env, ")");
757 }763 }
758 }764 }
@@ -777,7 +783,7 @@ static void print_verifier_state(struct bpf_verifier_env *env, · 18 unmodified lines
777 if (is_spilled_reg(&state->stack[i])) {783 if (is_spilled_reg(&state->stack[i])) {
778 reg = &state->stack[i].spilled_ptr;784 reg = &state->stack[i].spilled_ptr;
779 t = reg->type;785 t = reg->type;
780 verbose(env, "=%s", reg_type_str(env, t));786 verbose(env, "=%s", t == SCALAR_VALUE ? "" : reg_type_str(env, t));
781 if (t == SCALAR_VALUE && reg->precise)787 if (t == SCALAR_VALUE && reg->precise)
782 verbose(env, "P");788 verbose(env, "P");
783 if (t == SCALAR_VALUE && tnum_is_const(reg->var_off))789 if (t == SCALAR_VALUE && tnum_is_const(reg->var_off))