• Jakub Kicinski's avatar
    nfp: bpf: protect against mis-initializing atomic counters · 527db74b
    Jakub Kicinski authored
    Atomic operations on the NFP are currently always in big endian.
    The driver keeps track of regions of memory storing atomic values
    and byte swaps them accordingly.  There are corner cases where
    the map values may be initialized before the driver knows they
    are used as atomic counters.  This can happen either when the
    datapath is performing the update and the stack contents are
    unknown or when map is updated before the program which will
    use it for atomic values is loaded.
    
    To avoid situation where user initializes the value to 0 1 2 3
    and then after loading a program which uses the word as an atomic
    counter starts reading 3 2 1 0 - only allow atomic counters to be
    initialized to endian-neutral values.
    
    For updates from the datapath the stack information may not be
    as precise, so just allow initializing such values to 0.
    
    Example code which would break:
    struct bpf_map_def SEC("maps") rxcnt = {
           .type = BPF_MAP_TYPE_HASH,
           .key_size = sizeof(__u32),
           .value_size = sizeof(__u64),
           .max_entries = 1,
    };
    
    int xdp_prog1()
    {
          	__u64 nonzeroval = 3;
    	__u32 key = 0;
    	__u64 *value;
    
    	value = bpf_map_lookup_elem(&rxcnt, &key);
    	if (!value)
    		bpf_map_update_elem(&rxcnt, &key, &nonzeroval, BPF_ANY);
    	else
    		__sync_fetch_and_add(value, 1);
    
    	return XDP_PASS;
    }
    
    $ offload bpftool map dump
    key: 00 00 00 00 value: 00 00 00 03 00 00 00 00
    
    should be:
    
    $ offload bpftool map dump
    key: 00 00 00 00 value: 03 00 00 00 00 00 00 00
    Reported-by: default avatarDavid Beckett <david.beckett@netronome.com>
    Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
    Reviewed-by: default avatarQuentin Monnet <quentin.monnet@netronome.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    527db74b
verifier.c 22.2 KB