Re: KASAN error in core.c:bpf_prog_get_file_line()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 5 Jul 2025 at 04:47, Eduard Zingerman <eddyz87@xxxxxxxxx> wrote:
>
> Hi Kumar,
>
> I hit a KASAN error when running verifier_iterating_callbacks/ja_and_may_goto_subprog test case.
> (CC'ing mailing list in case anyone else runs into it before fix).
> The error is within the function kernel/bpf/core.c:bpf_prog_get_file_line():

Thanks, I'll take a look and send a fix.

>
>
>   int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char **filep,
>                              const char **linep, int *nump)
>   {
>         ...
>         struct bpf_line_info *linfo;
>         ...
>         linfo = prog->aux->linfo;
>         ...
>         linfo = &prog->aux->linfo[prog->aux->linfo_idx];
>         ...
>         for (int i = 0; i < prog->aux->nr_linfo &&
> --->         linfo[i].insn_off >= insn_start && linfo[i].insn_off < insn_end; i++) {
>                 if (jited_linfo[i] >= (void *)ip)
>                         break;
>                 idx = i;
>         }
>         ...
>   }
>
> The error is reported at the marked line. Full report is in the
> attachment, main part is here:
>
> [    2.457680] BUG: KASAN: slab-out-of-bounds in bpf_prog_get_file_line (kernel/bpf/core.c:3263 (discriminator 2))
> ...
> [    2.458068] ? bpf_prog_get_file_line (kernel/bpf/core.c:3263 (discriminator 2))
> [    2.458074] bpf_prog_get_file_line (kernel/bpf/core.c:3263 (discriminator 2))
> [    2.458078] ? bpf_prog_0b95dbe6b5c648f2_subprog_with_may_goto+0x49/0x57
> [    2.466754] Allocated by task 150:
> ...
> [    2.467122] check_btf_line (./include/linux/slab.h:1065 kernel/bpf/verifier.c:18118)
> [    2.467190] bpf_check (kernel/bpf/verifier.c:18332 kernel/bpf/verifier.c:24611)
> [    2.467258] bpf_prog_load (kernel/bpf/syscall.c:2972 (discriminator 1))
> [    2.467325] __sys_bpf (kernel/bpf/syscall.c:6007)
> [    2.467392] __x64_sys_bpf (kernel/bpf/syscall.c:6115)
> [    2.467459] do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
> [    2.467527] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
> [    2.467615]
> [    2.467660] The buggy address belongs to the object at ffff888107f8f980
> [    2.467660]  which belongs to the cache kmalloc-cg-32 of size 32
> [    2.467873] The buggy address is located 0 bytes to the right of
> [    2.467873]  allocated 32-byte region [ffff888107f8f980, ffff888107f8f9a0)
> [    2.468094]
>
> Note the following part of the verifier.c:jit_subprogs:
>
>   static int jit_subprogs(struct bpf_verifier_env *env)
>   {
>         ...
>         for (i = 0; i < env->subprog_cnt; i++) {
>                 ...
>                 func[i]->aux->linfo = prog->aux->linfo;
>                 func[i]->aux->nr_linfo = prog->aux->nr_linfo;
>                 ...
>                 func[i]->aux->linfo_idx = env->subprog_info[i].linfo_idx;
>                 ...
>   }
>
> Given the above initialization, I think bpf_prog_get_file_line() has
> to be fixed as follows:
>
> --- 8< -------------------------------------------
>
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index fe8a53f3c5bc..061ff34e0f53 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -3253,13 +3253,13 @@ int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char *
>                 return -EINVAL;
>         len = prog->aux->func ? prog->aux->func[prog->aux->func_idx]->len : prog->len;
>
> -       linfo = &prog->aux->linfo[prog->aux->linfo_idx];
> -       jited_linfo = &prog->aux->jited_linfo[prog->aux->linfo_idx];
> +       linfo = prog->aux->linfo;
> +       jited_linfo = prog->aux->jited_linfo;
>
>         insn_start = linfo[0].insn_off;
>         insn_end = insn_start + len;
>
> -       for (int i = 0; i < prog->aux->nr_linfo &&
> +       for (int i = prog->aux->linfo_idx; i < prog->aux->nr_linfo &&
>              linfo[i].insn_off >= insn_start && linfo[i].insn_off < insn_end; i++) {
>                 if (jited_linfo[i] >= (void *)ip)
>                         break;
>
> ------------------------------------------- >8 ---
>
> Could you please take a look?




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux