Re: [PATCH v4 bpf-next 08/14] bpf: introduce the bpf_get_local_storage() helper function

From: Daniel Borkmann
Date: Tue Jul 31 2018 - 06:34:14 EST


Hi Roman,

On 07/27/2018 11:52 PM, Roman Gushchin wrote:
> The bpf_get_local_storage() helper function is used
> to get a pointer to the bpf local storage from a bpf program.
>
> It takes a pointer to a storage map and flags as arguments.
> Right now it accepts only cgroup storage maps, and flags
> argument has to be 0. Further it can be extended to support
> other types of local storage: e.g. thread local storage etc.
>
> Signed-off-by: Roman Gushchin <guro@xxxxxx>
> Cc: Alexei Starovoitov <ast@xxxxxxxxxx>
> Cc: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
> Acked-by: Martin KaFai Lau <kafai@xxxxxx>
> ---
> include/linux/bpf.h | 2 ++
> include/uapi/linux/bpf.h | 13 ++++++++++++-
> kernel/bpf/cgroup.c | 2 ++
> kernel/bpf/core.c | 1 +
> kernel/bpf/helpers.c | 20 ++++++++++++++++++++
> kernel/bpf/verifier.c | 18 ++++++++++++++++++
> net/core/filter.c | 23 ++++++++++++++++++++++-
> 7 files changed, 77 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index ca4ac2a39def..cd8790d2c6ed 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -788,6 +788,8 @@ extern const struct bpf_func_proto bpf_sock_map_update_proto;
> extern const struct bpf_func_proto bpf_sock_hash_update_proto;
> extern const struct bpf_func_proto bpf_get_current_cgroup_id_proto;
>
> +extern const struct bpf_func_proto bpf_get_local_storage_proto;
> +
> /* Shared helpers among cBPF and eBPF. */
> void bpf_user_rnd_init_once(void);
> u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index a0aa53148763..495180f229ee 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -2081,6 +2081,16 @@ union bpf_attr {
> * Return
> * A 64-bit integer containing the current cgroup id based
> * on the cgroup within which the current task is running.
> + *
> + * void* get_local_storage(void *map, u64 flags)
> + * Description
> + * Get the pointer to the local storage area.
> + * The type and the size of the local storage is defined
> + * by the *map* argument.
> + * The *flags* meaning is specific for each map type,
> + * and has to be 0 for cgroup local storage.
> + * Return
> + * Pointer to the local storage area.
> */

I think it would be crucial to clarify what underlying assumption the
program writer can make with regards to concurrent access to this storage.

E.g. in this context, can _only_ BPF_XADD be used for counters as otherwise
any other type of access may race in parallel, or are we protected by the
socket lock and can safely override all data in this buffer via normal stores
(e.g. for socket related progs)? What about other types?

Right now nothing is mentioned here, but I think it must be clarified to
avoid any surprises. E.g. in normal htab case program can at least use the
map update there for atomic value updates, but those are disallowed from
the cgroup local storage, hence my question. Btw, no need to resend, I can
also update the paragraph there.

Thanks,
Daniel