• Kumar Kartikeya Dwivedi's avatar
    bpf: Recognize lock and list fields in allocated objects · 8ffa5cc1
    Kumar Kartikeya Dwivedi authored
    Allow specifying bpf_spin_lock, bpf_list_head, bpf_list_node fields in a
    allocated object.
    
    Also update btf_struct_access to reject direct access to these special
    fields.
    
    A bpf_list_head allows implementing map-in-map style use cases, where an
    allocated object with bpf_list_head is linked into a list in a map
    value. This would require embedding a bpf_list_node, support for which
    is also included. The bpf_spin_lock is used to protect the bpf_list_head
    and other data.
    
    While we strictly don't require to hold a bpf_spin_lock while touching
    the bpf_list_head in such objects, as when have access to it, we have
    complete ownership of the object, the locking constraint is still kept
    and may be conditionally lifted in the future.
    
    Note that the specification of such types can be done just like map
    values, e.g.:
    
    struct bar {
    	struct bpf_list_node node;
    };
    
    struct foo {
    	struct bpf_spin_lock lock;
    	struct bpf_list_head head __contains(bar, node);
    	struct bpf_list_node node;
    };
    
    struct map_value {
    	struct bpf_spin_lock lock;
    	struct bpf_list_head head __contains(foo, node);
    };
    
    To recognize such types in user BTF, we build a btf_struct_metas array
    of metadata items corresponding to each BTF ID. This is done once during
    the btf_parse stage to avoid having to do it each time during the
    verification process's requirement to inspect the metadata.
    
    Moreover, the computed metadata needs to be passed to some helpers in
    future patches which requires allocating them and storing them in the
    BTF that is pinned by the program itself, so that valid access can be
    assumed to such data during program runtime.
    
    A key thing to note is that once a btf_struct_meta is available for a
    type, both the btf_record and btf_field_offs should be available. It is
    critical that btf_field_offs is available in case special fields are
    present, as we extensively rely on special fields being zeroed out in
    map values and allocated objects in later patches. The code ensures that
    by bailing out in case of errors and ensuring both are available
    together. If the record is not available, the special fields won't be
    recognized, so not having both is also fine (in terms of being a
    verification error and not a runtime bug).
    Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
    Link: https://lore.kernel.org/r/20221118015614.2013203-7-memxor@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    8ffa5cc1
btf.c 216 KB