• Puranjay Mohan's avatar
    bpf, x86: Fix PROBE_MEM runtime load check · b599d7d2
    Puranjay Mohan authored
    When a load is marked PROBE_MEM - e.g. due to PTR_UNTRUSTED access - the
    address being loaded from is not necessarily valid. The BPF jit sets up
    exception handlers for each such load which catch page faults and 0 out
    the destination register.
    
    If the address for the load is outside kernel address space, the load
    will escape the exception handling and crash the kernel. To prevent this
    from happening, the emits some instruction to verify that addr is > end
    of userspace addresses.
    
    x86 has a legacy vsyscall ABI where a page at address 0xffffffffff600000
    is mapped with user accessible permissions. The addresses in this page
    are considered userspace addresses by the fault handler. Therefore, a
    BPF program accessing this page will crash the kernel.
    
    This patch fixes the runtime checks to also check that the PROBE_MEM
    address is below VSYSCALL_ADDR.
    
    Example BPF program:
    
     SEC("fentry/tcp_v4_connect")
     int BPF_PROG(fentry_tcp_v4_connect, struct sock *sk)
     {
    	*(volatile unsigned long *)&sk->sk_tsq_flags;
    	return 0;
     }
    
    BPF Assembly:
    
     0: (79) r1 = *(u64 *)(r1 +0)
     1: (79) r1 = *(u64 *)(r1 +344)
     2: (b7) r0 = 0
     3: (95) exit
    
    			       x86-64 JIT
    			       ==========
    
                BEFORE                                    AFTER
    	    ------                                    -----
    
     0:   nopl   0x0(%rax,%rax,1)             0:   nopl   0x0(%rax,%rax,1)
     5:   xchg   %ax,%ax                      5:   xchg   %ax,%ax
     7:   push   %rbp                         7:   push   %rbp
     8:   mov    %rsp,%rbp                    8:   mov    %rsp,%rbp
     b:   mov    0x0(%rdi),%rdi               b:   mov    0x0(%rdi),%rdi
    -------------------------------------------------------------------------------
     f:   movabs $0x100000000000000,%r11      f:   movabs $0xffffffffff600000,%r10
    19:   add    $0x2a0,%rdi                 19:   mov    %rdi,%r11
    20:   cmp    %r11,%rdi                   1c:   add    $0x2a0,%r11
    23:   jae    0x0000000000000029          23:   sub    %r10,%r11
    25:   xor    %edi,%edi                   26:   movabs $0x100000000a00000,%r10
    27:   jmp    0x000000000000002d          30:   cmp    %r10,%r11
    29:   mov    0x0(%rdi),%rdi              33:   ja     0x0000000000000039
    --------------------------------\        35:   xor    %edi,%edi
    2d:   xor    %eax,%eax           \       37:   jmp    0x0000000000000040
    2f:   leave                       \      39:   mov    0x2a0(%rdi),%rdi
    30:   ret                          \--------------------------------------------
                                             40:   xor    %eax,%eax
                                             42:   leave
                                             43:   ret
    Signed-off-by: default avatarPuranjay Mohan <puranjay@kernel.org>
    Link: https://lore.kernel.org/r/20240424100210.11982-3-puranjay@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    b599d7d2
bpf_jit_comp.c 93.4 KB