KASAN error in core.c:bpf_prog_get_file_line()

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

 



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():


  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?
[    2.457508] ==================================================================
[    2.457680] BUG: KASAN: slab-out-of-bounds in bpf_prog_get_file_line (kernel/bpf/core.c:3263 (discriminator 2)) 
[    2.457838] Read of size 4 at addr ffff888107f8f9a0 by task test_progs/150
[    2.457967] 
[    2.458035] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[    2.458037] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-4.fc42 04/01/2014
[    2.458038] Call Trace:
[    2.458040]  <TASK>
[    2.458042] dump_stack_lvl (lib/dump_stack.c:122) 
[    2.458048] print_report (mm/kasan/report.c:409 mm/kasan/report.c:521) 
[    2.458052] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458055] ? __virt_addr_valid (./include/linux/rcupdate.h:955 (discriminator 3) ./include/linux/mmzone.h:2168 (discriminator 3) arch/x86/mm/physaddr.c:65 (discriminator 3)) 
[    2.458060] ? bpf_prog_get_file_line (kernel/bpf/core.c:3263 (discriminator 2)) 
[    2.458062] kasan_report (mm/kasan/report.c:221 mm/kasan/report.c:636) 
[    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.458082] ? bpf_prog_0b95dbe6b5c648f2_subprog_with_may_goto+0x49/0x57 
[    2.458085] dump_stack_cb (kernel/bpf/stream.c:498) 
[    2.458087] ? find_held_lock (kernel/locking/lockdep.c:5353 (discriminator 1)) 
[    2.458091] ? __pfx_dump_stack_cb (kernel/bpf/stream.c:487) 
[    2.458094] ? __pfx_dump_stack_cb (kernel/bpf/stream.c:487) 
[    2.458096] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458097] ? lock_release (kernel/locking/lockdep.c:473 (discriminator 6) kernel/locking/lockdep.c:5894 (discriminator 6) kernel/locking/lockdep.c:5878 (discriminator 6)) 
[    2.458102] ? is_bpf_text_address (kernel/bpf/core.c:781) 
[    2.458104] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458106] ? kernel_text_address (kernel/extable.c:125 (discriminator 1) kernel/extable.c:94 (discriminator 1)) 
[    2.458112] ? bpf_prog_0b95dbe6b5c648f2_subprog_with_may_goto+0x49/0x57 
[    2.458114] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458117] ? __pfx_dump_stack_cb (kernel/bpf/stream.c:487) 
[    2.458119] arch_bpf_stack_walk (arch/x86/net/bpf_jit_comp.c:3843 (discriminator 1)) 
[    2.458123] ? __pfx_arch_bpf_stack_walk (arch/x86/net/bpf_jit_comp.c:3835) 
[    2.458127] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458129] ? lockdep_hardirqs_on_prepare (kernel/locking/lockdep.c:473 (discriminator 6) kernel/locking/lockdep.c:4414 (discriminator 6) kernel/locking/lockdep.c:4365 (discriminator 6)) 
[    2.458135] ? bpf_prog_0b95dbe6b5c648f2_subprog_with_may_goto+0x49/0x57 
[    2.458138] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458141] ? bpf_stream_stage_printk (./include/linux/llist.h:242 (discriminator 20) ./include/linux/llist.h:265 (discriminator 20) kernel/bpf/stream.c:195 (discriminator 20) kernel/bpf/stream.c:448 (discriminator 20)) 
[    2.458145] bpf_stream_stage_dump_stack (kernel/bpf/stream.c:523) 
[    2.458148] ? __pfx_bpf_stream_stage_dump_stack (kernel/bpf/stream.c:510) 
[    2.458151] ? __lock_acquire (kernel/locking/lockdep.c:4677 (discriminator 1) kernel/locking/lockdep.c:5194 (discriminator 1)) 
[    2.458156] bpf_prog_report_may_goto_violation (kernel/bpf/core.c:3180 (discriminator 3)) 
[    2.458159] ? __pfx_bpf_prog_report_may_goto_violation (kernel/bpf/core.c:3172) 
[    2.458161] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458164] ? lockdep_hardirqs_on (kernel/locking/lockdep.c:4476) 
[    2.458167] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458169] ? asm_sysvec_apic_timer_interrupt (./arch/x86/include/asm/idtentry.h:702) 
[    2.458172] ? ktime_get_mono_fast_ns (kernel/time/timekeeping.c:251 kernel/time/timekeeping.c:360 kernel/time/timekeeping.c:408 kernel/time/timekeeping.c:448) 
[    2.458177] bpf_check_timed_may_goto (kernel/bpf/core.c:3199) 
[    2.458180] arch_bpf_timed_may_goto (arch/x86/net/bpf_timed_may_goto.S:43) 
[    2.458184]  ? 0xffffffffc00006d4
[    2.458187] bpf_prog_0b95dbe6b5c648f2_subprog_with_may_goto+0x49/0x57 
[    2.458190] bpf_prog_aba1e8ae8c28e6af_ja_and_may_goto_subprog+0x19/0x1f 
[    2.458193] bpf_test_run (./include/linux/bpf.h:1322 ./include/linux/filter.h:718 ./include/linux/filter.h:725 net/bpf/test_run.c:434) 
[    2.458198] ? bpf_test_run (./include/linux/bottom_half.h:20 (discriminator 1) net/bpf/test_run.c:428 (discriminator 1)) 
[    2.458203] ? __pfx_bpf_test_run (net/bpf/test_run.c:402) 
[    2.458218] ? __pfx_eth_type_trans (net/ethernet/eth.c:156) 
[    2.458221] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458223] ? ksm_process_mergeable (mm/ksm.c:3279) 
[    2.458228] bpf_prog_test_run_skb (net/bpf/test_run.c:1099) 
[    2.458230] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458232] ? find_held_lock (kernel/locking/lockdep.c:5353 (discriminator 1)) 
[    2.458239] ? __pfx_bpf_prog_test_run_skb (net/bpf/test_run.c:986) 
[    2.458244] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458246] ? fput (./include/linux/preempt.h:481 (discriminator 5) ./include/linux/file_ref.h:150 (discriminator 5) fs/file_table.c:541 (discriminator 5)) 
[    2.458252] __sys_bpf (kernel/bpf/syscall.c:4578 kernel/bpf/syscall.c:6025) 
[    2.458256] ? __pfx___sys_bpf (kernel/bpf/syscall.c:5969) 
[    2.458258] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458260] ? mt_find (lib/maple_tree.c:6938 (discriminator 1)) 
[    2.458265] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458267] ? lock_acquire (kernel/locking/lockdep.c:473 kernel/locking/lockdep.c:5873 kernel/locking/lockdep.c:5828) 
[    2.458269] ? __might_fault (mm/memory.c:6971 (discriminator 4)) 
[    2.458273] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458275] ? lock_acquire (kernel/locking/lockdep.c:473 (discriminator 6) kernel/locking/lockdep.c:5873 (discriminator 6) kernel/locking/lockdep.c:5828 (discriminator 6)) 
[    2.458284] ? __pfx___up_read (kernel/locking/rwsem.c:1337) 
[    2.458288] ? __pfx___rseq_handle_notify_resume (kernel/rseq.c:425) 
[    2.458291] ? __pfx_fput_close_sync (fs/file_table.c:568) 
[    2.458297] __x64_sys_bpf (kernel/bpf/syscall.c:6115) 
[    2.458299] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458301] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:183) 
[    2.458303] ? lockdep_hardirqs_on (kernel/locking/lockdep.c:4476) 
[    2.458306] do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) 
[    2.458309] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) 
[    2.458312] RIP: 0033:0x7f23a12ffa8d
[ 2.458314] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 4b 63 0f 00 f7 d8 64 89 01 48
All code
========
   0:	ff c3                	inc    %ebx
   2:	66 2e 0f 1f 84 00 00 	cs nopw 0x0(%rax,%rax,1)
   9:	00 00 00 
   c:	90                   	nop
   d:	f3 0f 1e fa          	endbr64
  11:	48 89 f8             	mov    %rdi,%rax
  14:	48 89 f7             	mov    %rsi,%rdi
  17:	48 89 d6             	mov    %rdx,%rsi
  1a:	48 89 ca             	mov    %rcx,%rdx
  1d:	4d 89 c2             	mov    %r8,%r10
  20:	4d 89 c8             	mov    %r9,%r8
  23:	4c 8b 4c 24 08       	mov    0x8(%rsp),%r9
  28:	0f 05                	syscall
  2a:*	48 3d 01 f0 ff ff    	cmp    $0xfffffffffffff001,%rax		<-- trapping instruction
  30:	73 01                	jae    0x33
  32:	c3                   	ret
  33:	48 8b 0d 4b 63 0f 00 	mov    0xf634b(%rip),%rcx        # 0xf6385
  3a:	f7 d8                	neg    %eax
  3c:	64 89 01             	mov    %eax,%fs:(%rcx)
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	48 3d 01 f0 ff ff    	cmp    $0xfffffffffffff001,%rax
   6:	73 01                	jae    0x9
   8:	c3                   	ret
   9:	48 8b 0d 4b 63 0f 00 	mov    0xf634b(%rip),%rcx        # 0xf635b
  10:	f7 d8                	neg    %eax
  12:	64 89 01             	mov    %eax,%fs:(%rcx)
  15:	48                   	rex.W
[    2.458316] RSP: 002b:00007ffc242cace8 EFLAGS: 00000206 ORIG_RAX: 0000000000000141
[    2.458319] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f23a12ffa8d
[    2.458321] RDX: 0000000000000050 RSI: 00007ffc242cad20 RDI: 000000000000000a
[    2.458322] RBP: 00007ffc242cad00 R08: 0000000000000000 R09: 00007ffc242cad20
[    2.458324] R10: 0000000000000000 R11: 0000000000000206 R12: 00007ffc242cb738
[    2.458325] R13: 0000000000000003 R14: 00007f23a194e000 R15: 000000000374fee0
[    2.458333]  </TASK>
[    2.458334] 
[    2.466754] Allocated by task 150:
[    2.466822] kasan_save_stack (mm/kasan/common.c:48) 
[    2.466892] kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1)) 
[    2.466959] __kasan_kmalloc (mm/kasan/common.c:398) 
[    2.467032] __kvmalloc_node_noprof (./include/linux/kasan.h:260 mm/slub.c:4328 mm/slub.c:5015) 
[    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] 
[    2.468139] The buggy address belongs to the physical page:
[    2.468227] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x107f8f
[    2.468361] flags: 0x2fffe0000000000(node=0|zone=2|lastcpupid=0x7fff)
[    2.468474] page_type: f5(slab)
[    2.468546] raw: 02fffe0000000000 ffff888100049900 dead000000000122 0000000000000000
[    2.468678] raw: 0000000000000000 0000000080400040 00000000f5000000 0000000000000000
[    2.468811] page dumped because: kasan: bad access detected
[    2.468898] 
[    2.468943] Memory state around the buggy address:
[    2.469033]  ffff888107f8f880: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc
[    2.469164]  ffff888107f8f900: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc
[    2.469295] >ffff888107f8f980: 00 00 00 00 fc fc fc fc fa fb fb fb fc fc fc fc
[    2.469424]                                ^
[    2.469512]  ffff888107f8fa00: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc
[    2.469642]  ffff888107f8fa80: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc
[    2.469773] ==================================================================
[    2.469917] Disabling lock debugging due to kernel taint
#520/18  verifier_iterating_callbacks/ja_and_may_goto_subprog:OK
#520     verifier_iterating_callbacks:OK
Summary: 1/1 PASSED, 0 SKIPPED, 0 FAILED

[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