• Gianluca Borello's avatar
    bpf: allow helpers access to map element values · 5722569b
    Gianluca Borello authored
    Enable helpers to directly access a map element value by passing a
    register type PTR_TO_MAP_VALUE (or PTR_TO_MAP_VALUE_ADJ) to helper
    arguments ARG_PTR_TO_STACK or ARG_PTR_TO_RAW_STACK.
    
    This enables several use cases. For example, a typical tracing program
    might want to capture pathnames passed to sys_open() with:
    
    struct trace_data {
    	char pathname[PATHLEN];
    };
    
    SEC("kprobe/sys_open")
    void bpf_sys_open(struct pt_regs *ctx)
    {
    	struct trace_data data;
    	bpf_probe_read(data.pathname, sizeof(data.pathname), ctx->di);
    
    	/* consume data.pathname, for example via
    	 * bpf_trace_printk() or bpf_perf_event_output()
    	 */
    }
    
    Such a program could easily hit the stack limit in case PATHLEN needs to
    be large or more local variables need to exist, both of which are quite
    common scenarios. Allowing direct helper access to map element values,
    one could do:
    
    struct bpf_map_def SEC("maps") scratch_map = {
    	.type = BPF_MAP_TYPE_PERCPU_ARRAY,
    	.key_size = sizeof(u32),
    	.value_size = sizeof(struct trace_data),
    	.max_entries = 1,
    };
    
    SEC("kprobe/sys_open")
    int bpf_sys_open(struct pt_regs *ctx)
    {
    	int id = 0;
    	struct trace_data *p = bpf_map_lookup_elem(&scratch_map, &id);
    	if (!p)
    		return;
    	bpf_probe_read(p->pathname, sizeof(p->pathname), ctx->di);
    
    	/* consume p->pathname, for example via
    	 * bpf_trace_printk() or bpf_perf_event_output()
    	 */
    }
    
    And wouldn't risk exhausting the stack.
    
    Code changes are loosely modeled after commit 6841de8b ("bpf: allow
    helpers access the packet directly"). Unlike with PTR_TO_PACKET, these
    changes just work with ARG_PTR_TO_STACK and ARG_PTR_TO_RAW_STACK (not
    ARG_PTR_TO_MAP_KEY, ARG_PTR_TO_MAP_VALUE, ...): adding those would be
    trivial, but since there is not currently a use case for that, it's
    reasonable to limit the set of changes.
    
    Also, add new tests to make sure accesses to map element values from
    helpers never go out of boundary, even when adjusted.
    Signed-off-by: default avatarGianluca Borello <g.borello@gmail.com>
    Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    5722569b
test_verifier.c 105 KB