• Yonghong Song's avatar
    bpf: Emit better log message if bpf_iter ctx arg btf_id == 0 · d3621642
    Yonghong Song authored
    To avoid kernel build failure due to some missing .BTF-ids referenced
    functions/types, the patch ([1]) tries to fill btf_id 0 for
    these types.
    
    In bpf verifier, for percpu variable and helper returning btf_id cases,
    verifier already emitted proper warning with something like
      verbose(env, "Helper has invalid btf_id in R%d\n", regno);
      verbose(env, "invalid return type %d of func %s#%d\n",
              fn->ret_type, func_id_name(func_id), func_id);
    
    But this is not the case for bpf_iter context arguments.
    I hacked resolve_btfids to encode btf_id 0 for struct task_struct.
    With `./test_progs -n 7/5`, I got,
      0: (79) r2 = *(u64 *)(r1 +0)
      func 'bpf_iter_task' arg0 has btf_id 29739 type STRUCT 'bpf_iter_meta'
      ; struct seq_file *seq = ctx->meta->seq;
      1: (79) r6 = *(u64 *)(r2 +0)
      ; struct task_struct *task = ctx->task;
      2: (79) r7 = *(u64 *)(r1 +8)
      ; if (task == (void *)0) {
      3: (55) if r7 != 0x0 goto pc+11
      ...
      ; BPF_SEQ_PRINTF(seq, "%8d %8d\n", task->tgid, task->pid);
      26: (61) r1 = *(u32 *)(r7 +1372)
      Type '(anon)' is not a struct
    
    Basically, verifier will return btf_id 0 for task_struct.
    Later on, when the code tries to access task->tgid, the
    verifier correctly complains the type is '(anon)' and it is
    not a struct. Users still need to backtrace to find out
    what is going on.
    
    Let us catch the invalid btf_id 0 earlier
    and provide better message indicating btf_id is wrong.
    The new error message looks like below:
      R1 type=ctx expected=fp
      ; struct seq_file *seq = ctx->meta->seq;
      0: (79) r2 = *(u64 *)(r1 +0)
      func 'bpf_iter_task' arg0 has btf_id 29739 type STRUCT 'bpf_iter_meta'
      ; struct seq_file *seq = ctx->meta->seq;
      1: (79) r6 = *(u64 *)(r2 +0)
      ; struct task_struct *task = ctx->task;
      2: (79) r7 = *(u64 *)(r1 +8)
      invalid btf_id for context argument offset 8
      invalid bpf_context access off=8 size=8
    
    [1] https://lore.kernel.org/bpf/20210727132532.2473636-1-hengqi.chen@gmail.com/Signed-off-by: default avatarYonghong Song <yhs@fb.com>
    Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Link: https://lore.kernel.org/bpf/20210728183025.1461750-1-yhs@fb.com
    d3621642
btf.c 159 KB