• Kumar Kartikeya Dwivedi's avatar
    bpf: Rework process_dynptr_func · 27060531
    Kumar Kartikeya Dwivedi authored
    Recently, user ringbuf support introduced a PTR_TO_DYNPTR register type
    for use in callback state, because in case of user ringbuf helpers,
    there is no dynptr on the stack that is passed into the callback. To
    reflect such a state, a special register type was created.
    
    However, some checks have been bypassed incorrectly during the addition
    of this feature. First, for arg_type with MEM_UNINIT flag which
    initialize a dynptr, they must be rejected for such register type.
    Secondly, in the future, there are plans to add dynptr helpers that
    operate on the dynptr itself and may change its offset and other
    properties.
    
    In all of these cases, PTR_TO_DYNPTR shouldn't be allowed to be passed
    to such helpers, however the current code simply returns 0.
    
    The rejection for helpers that release the dynptr is already handled.
    
    For fixing this, we take a step back and rework existing code in a way
    that will allow fitting in all classes of helpers and have a coherent
    model for dealing with the variety of use cases in which dynptr is used.
    
    First, for ARG_PTR_TO_DYNPTR, it can either be set alone or together
    with a DYNPTR_TYPE_* constant that denotes the only type it accepts.
    
    Next, helpers which initialize a dynptr use MEM_UNINIT to indicate this
    fact. To make the distinction clear, use MEM_RDONLY flag to indicate
    that the helper only operates on the memory pointed to by the dynptr,
    not the dynptr itself. In C parlance, it would be equivalent to taking
    the dynptr as a point to const argument.
    
    When either of these flags are not present, the helper is allowed to
    mutate both the dynptr itself and also the memory it points to.
    Currently, the read only status of the memory is not tracked in the
    dynptr, but it would be trivial to add this support inside dynptr state
    of the register.
    
    With these changes and renaming PTR_TO_DYNPTR to CONST_PTR_TO_DYNPTR to
    better reflect its usage, it can no longer be passed to helpers that
    initialize a dynptr, i.e. bpf_dynptr_from_mem, bpf_ringbuf_reserve_dynptr.
    
    A note to reviewers is that in code that does mark_stack_slots_dynptr,
    and unmark_stack_slots_dynptr, we implicitly rely on the fact that
    PTR_TO_STACK reg is the only case that can reach that code path, as one
    cannot pass CONST_PTR_TO_DYNPTR to helpers that don't set MEM_RDONLY. In
    both cases such helpers won't be setting that flag.
    
    The next patch will add a couple of selftest cases to make sure this
    doesn't break.
    
    Fixes: 20571567 ("bpf: Add bpf_user_ringbuf_drain() helper")
    Acked-by: default avatarJoanne Koong <joannelkoong@gmail.com>
    Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
    Link: https://lore.kernel.org/r/20221207204141.308952-4-memxor@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    27060531
bpf_doc.py 31.7 KB