• J
    bpf: disallow arithmetic operations on context pointer · 28e33f9d
    Jakub Kicinski 提交于
    Commit f1174f77 ("bpf/verifier: rework value tracking")
    removed the crafty selection of which pointer types are
    allowed to be modified.  This is OK for most pointer types
    since adjust_ptr_min_max_vals() will catch operations on
    immutable pointers.  One exception is PTR_TO_CTX which is
    now allowed to be offseted freely.
    
    The intent of aforementioned commit was to allow context
    access via modified registers.  The offset passed to
    ->is_valid_access() verifier callback has been adjusted
    by the value of the variable offset.
    
    What is missing, however, is taking the variable offset
    into account when the context register is used.  Or in terms
    of the code adding the offset to the value passed to the
    ->convert_ctx_access() callback.  This leads to the following
    eBPF user code:
    
         r1 += 68
         r0 = *(u32 *)(r1 + 8)
         exit
    
    being translated to this in kernel space:
    
       0: (07) r1 += 68
       1: (61) r0 = *(u32 *)(r1 +180)
       2: (95) exit
    
    Offset 8 is corresponding to 180 in the kernel, but offset
    76 is valid too.  Verifier will "accept" access to offset
    68+8=76 but then "convert" access to offset 8 as 180.
    Effective access to offset 248 is beyond the kernel context.
    (This is a __sk_buff example on a debug-heavy kernel -
    packet mark is 8 -> 180, 76 would be data.)
    
    Dereferencing the modified context pointer is not as easy
    as dereferencing other types, because we have to translate
    the access to reading a field in kernel structures which is
    usually at a different offset and often of a different size.
    To allow modifying the pointer we would have to make sure
    that given eBPF instruction will always access the same
    field or the fields accessed are "compatible" in terms of
    offset and size...
    
    Disallow dereferencing modified context pointers and add
    to selftests the test case described here.
    
    Fixes: f1174f77 ("bpf/verifier: rework value tracking")
    Signed-off-by: NJakub Kicinski <jakub.kicinski@netronome.com>
    Acked-by: NDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: NAlexei Starovoitov <ast@kernel.org>
    Acked-by: NEdward Cree <ecree@solarflare.com>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    28e33f9d
test_verifier.c 207.6 KB