• Ilya Leoshkevich's avatar
    s390/bpf: Fix bpf_arch_text_poke() with new_addr == NULL · c730fce7
    Ilya Leoshkevich authored
    Thomas Richter reported a crash in linux-next with a backtrace similar
    to the following one:
    
    	 [<0000000000000000>] 0x0
    	([<000000000031a182>] bpf_trace_run4+0xc2/0x218)
    	 [<00000000001d59f4>] __bpf_trace_sched_switch+0x1c/0x28
    	 [<0000000000c44a3a>] __schedule+0x43a/0x890
    	 [<0000000000c44ef8>] schedule+0x68/0x110
    	 [<0000000000c4e5ca>] do_nanosleep+0xa2/0x168
    	 [<000000000026e7fe>] hrtimer_nanosleep+0xf6/0x1c0
    	 [<000000000026eb6e>] __s390x_sys_nanosleep+0xb6/0xf0
    	 [<0000000000c3b81c>] __do_syscall+0x1e4/0x208
    	 [<0000000000c50510>] system_call+0x70/0x98
    	Last Breaking-Event-Address:
    	 [<000003ff7fda1814>] bpf_prog_65e887c70a835bbf_on_switch+0x1a4/0x1f0
    
    The problem is that bpf_arch_text_poke() with new_addr == NULL is
    susceptible to the following race condition:
    
    	T1                 T2
            -----------------  -------------------
    	plt.target = NULL
    	                   entry: brcl 0xf,plt
    	entry.mask = 0
    	                   lgrl %r1,plt.target
    	                   br %r1
    
    Fix by setting PLT target to the instruction following `brcl 0xf,plt`
    instead of 0. This way T2 will simply resume the execution of the eBPF
    program, which is the desired effect of passing new_addr == NULL.
    
    Fixes: f1d5df84 ("s390/bpf: Implement bpf_arch_text_poke()")
    Reported-by: default avatarThomas Richter <tmricht@linux.ibm.com>
    Signed-off-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
    Link: https://lore.kernel.org/bpf/20230414154755.184502-1-iii@linux.ibm.com
    c730fce7
bpf_jit_comp.c 66.1 KB