On 18/06/2023 14:08, Jiri Olsa wrote: > On Fri, Jun 16, 2023 at 06:17:22PM +0100, Alan Maguire wrote: > > SNIP > >> static int btf_sec_info_cmp(const void *a, const void *b) >> @@ -5193,32 +5246,37 @@ static int btf_check_sec_info(struct btf_verifier_env *env, >> u32 btf_data_size) >> { >> struct btf_sec_info secs[ARRAY_SIZE(btf_sec_info_offset)]; >> - u32 total, expected_total, i; >> + u32 nr_secs = ARRAY_SIZE(btf_sec_info_offset); >> + u32 total, expected_total, gap, i; >> const struct btf_header *hdr; >> const struct btf *btf; >> >> btf = env->btf; >> hdr = &btf->hdr; >> >> + if (hdr->hdr_len < sizeof(struct btf_header)) >> + nr_secs--; >> + >> /* Populate the secs from hdr */ >> - for (i = 0; i < ARRAY_SIZE(btf_sec_info_offset); i++) >> + for (i = 0; i < nr_secs; i++) >> secs[i] = *(struct btf_sec_info *)((void *)hdr + >> btf_sec_info_offset[i]); >> >> - sort(secs, ARRAY_SIZE(btf_sec_info_offset), >> + sort(secs, nr_secs, >> sizeof(struct btf_sec_info), btf_sec_info_cmp, NULL); >> >> /* Check for gaps and overlap among sections */ >> total = 0; >> expected_total = btf_data_size - hdr->hdr_len; >> - for (i = 0; i < ARRAY_SIZE(btf_sec_info_offset); i++) { >> + for (i = 0; i < nr_secs; i++) { >> if (expected_total < secs[i].off) { >> btf_verifier_log(env, "Invalid section offset"); >> return -EINVAL; >> } >> - if (total < secs[i].off) { >> - /* gap */ >> - btf_verifier_log(env, "Unsupported section found"); >> + gap = secs[i].off - total; >> + if (gap >= 4) { >> + /* gap larger than alignment gap */ >> + btf_verifier_log(env, "Unsupported section gap found"); >> return -EINVAL; > > this sems to break several btf header tests with: > > do_test_raw:PASS:check 0 nsec > do_test_raw:FAIL:check expected err_str:Unsupported section found > > magic: 0xeb9f > version: 1 > flags: 0x0 > hdr_len: 40 > type_off: 4 > type_len: 16 > str_off: 16 > str_len: 5 > btf_total_size: 61 > Unsupported section gap found > #23/48 btf/btf_header test. Gap between hdr and type:FAIL > > thanks for spotting this Jiri! I've reworked the logic and the messages for v3 (in progress), and these pass now. Alan > jirka > >> } >> if (total > secs[i].off) { >> @@ -5230,7 +5288,7 @@ static int btf_check_sec_info(struct btf_verifier_env *env, >> "Total section length too long"); >> return -EINVAL; >> } >> - total += secs[i].len; >> + total += secs[i].len + gap; >> } >> >> /* There is data other than hdr and known sections */ >> @@ -5293,7 +5351,7 @@ static int btf_parse_hdr(struct btf_verifier_env *env) >> return -ENOTSUPP; >> } >> >> - if (hdr->flags) { >> + if (hdr->flags & ~(BTF_FLAG_CRC_SET | BTF_FLAG_BASE_CRC_SET)) { >> btf_verifier_log(env, "Unsupported flags"); >> return -ENOTSUPP; >> } >> @@ -5530,6 +5588,10 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat >> if (err) >> goto errout; >> >> + err = btf_parse_kind_layout_sec(env); >> + if (err) >> + goto errout; >> + >> err = btf_parse_type_sec(env); >> if (err) >> goto errout; >> -- >> 2.39.3 >>