mbox series

[bpf-next,0/2] libbpf: add support for privileged/unprivileged control separation

Message ID 20201104094626.3406-1-mariuszx.dudek@intel.com
Headers show
Series libbpf: add support for privileged/unprivileged control separation | expand

Message

Mariusz Dudek Nov. 4, 2020, 9:46 a.m. UTC
From: Mariusz Dudek <mariuszx.dudek@intel.com>

	This patch series adds support for separation of eBPF program
	load and xsk socket creation. In for example a Kubernetes
	environment you can have an AF_XDP CNI or daemonset that is 
	responsible for launching pods that execute an application 
	using AF_XDP sockets. It is desirable that the pod runs with
	as low privileges as possible, CAP_NET_RAW in this case, 
	and that all operations that require privileges are contained
	in the CNI or daemonset.
	
	In this case, you have to be able separate ePBF program load from
	xsk socket creation.

	Currently, this will not work with the xsk_socket__create APIs
	because you need to have CAP_NET_ADMIN privileges to load eBPF
	program and CAP_SYS_ADMIN privileges to create update xsk_bpf_maps.
	To be exact xsk_set_bpf_maps does not need those privileges but
	it takes the prog_fd and xsks_map_fd and those are known only to
	process that was loading eBPF program. The api bpf_prog_get_fd_by_id
	that looks up the fd of the prog using an prog_id and
	bpf_map_get_fd_by_id that looks for xsks_map_fd usinb map_id both
	requires CAP_SYS_ADMIN.

	With this patch, the pod can be run with CAP_NET_RAW capability
	only. In case your umem is larger or equal process limit for
	MEMLOCK you need either increase the limit or CAP_IPC_LOCK capability. 
	Without this patch in case of insufficient rights ENOPERM is
	returned by xsk_socket__create.

	To resolve this privileges issue two new APIs are introduced:
	- xsk_setup_xdp_prog - prepares bpf program if given and
	loads it on a selected network interface or loads the built in
	XDP program, if no XDP program is supplied. It can also return
	xsks_map_fd which is needed by unprivileged process to update
	xsks_map with AF_XDP socket "fd"
	- xsk_update_xskmap - inserts an AF_XDP socket into an xskmap for a
	particular xsk_socket

	Usage example:
	int xsk_setup_xdp_prog(int ifindex, struct bpf_prog_cfg *cfg,
			int *xsks_map_fd)

	if cfg == NULL, then the default program is loaded.

	Instead of NULL user can pass pointer to struct
	bpf_prog_cfg and provide own bpf program. 

	int xsk_update_xskmap(struct xsk_socket *xsk, int xsks_map_fd);

	Inserts AF_XDP socket "fd" into the xskmap.

	The first patch introduces the new APIs. The second patch provides
	a new sample applications working as control and modification to
	existing xdpsock application to work with less privileges.

	This patch set is based on bpf-next commit cb5dc5b062a9
	("Merge branch 'bpf: safeguard hashtab locking in NMI context')

Mariusz Dudek (2):
  libbpf: separate XDP program load with xsk socket creation
  samples/bpf: sample application for eBPF load and socket creation
    split

 samples/bpf/Makefile            |   4 +-
 samples/bpf/xdpsock.h           |   8 ++
 samples/bpf/xdpsock_ctrl_proc.c | 184 ++++++++++++++++++++++++++++++++
 samples/bpf/xdpsock_user.c      | 146 +++++++++++++++++++++++--
 tools/lib/bpf/libbpf.map        |   2 +
 tools/lib/bpf/xsk.c             | 157 ++++++++++++++++++++++-----
 tools/lib/bpf/xsk.h             |  13 +++
 7 files changed, 478 insertions(+), 36 deletions(-)
 create mode 100644 samples/bpf/xdpsock_ctrl_proc.c

Comments

Andrii Nakryiko Nov. 4, 2020, 9:07 p.m. UTC | #1
On Wed, Nov 4, 2020 at 1:47 AM <mariusz.dudek@gmail.com> wrote:
>
> From: Mariusz Dudek <mariuszx.dudek@intel.com>
>
>         Add support for separation of eBPF program load and xsk socket
>         creation.
>
>         This is needed for use-case when you want to privide as little
>         privileges as possible to the data plane application that will
>         handle xsk socket creation and incoming traffic.
>
>         With this patch the data entity container can be run with only
>         CAP_NET_RAW capability to fulfill its purpose of creating xsk
>         socket and handling packages. In case your umem is larger or
>         equal process limit for MEMLOCK you need either increase the
>         limit or CAP_IPC_LOCK capability.
>
>         To resolve privileges issue two APIs are introduced:
>
>         - xsk_setup_xdp_prog - prepares bpf program if given and
>         loads it on a selected network interface or loads the built in
>         XDP program, if no XDP program is supplied. It can also return
>         xsks_map_fd which is needed by unprivileged process to update
>         xsks_map with AF_XDP socket "fd"
>
>         - xsk_update_xskmap - inserts an AF_XDP socket into an xskmap
>         for a particular xsk_socket
>

Your commit message seems to be heavily shifted right...


> Signed-off-by: Mariusz Dudek <mariuszx.dudek@intel.com>
> ---
>  tools/lib/bpf/libbpf.map |   2 +
>  tools/lib/bpf/xsk.c      | 157 ++++++++++++++++++++++++++++++++-------
>  tools/lib/bpf/xsk.h      |  13 ++++
>  3 files changed, 146 insertions(+), 26 deletions(-)
>

[...]

> diff --git a/tools/lib/bpf/xsk.h b/tools/lib/bpf/xsk.h
> index 1069c46364ff..c42b91935d3c 100644
> --- a/tools/lib/bpf/xsk.h
> +++ b/tools/lib/bpf/xsk.h
> @@ -201,6 +201,19 @@ struct xsk_umem_config {
>         __u32 flags;
>  };
>
> +struct bpf_prog_cfg {
> +       struct bpf_insn *prog;
> +       const char *license;
> +       size_t insns_cnt;
> +       int xsks_map_fd;
> +};

This config will have problems with backward/forward compatibility.
Please check how xxx_opts are done and use them for extensible options
structs.


> +
> +LIBBPF_API int xsk_setup_xdp_prog(int ifindex,
> +                                 struct bpf_prog_cfg *cfg,
> +                                 int *xsks_map_fd);
> +LIBBPF_API int xsk_update_xskmap(struct xsk_socket *xsk,
> +                                int xsks_map_fd);

this should be called xsk_socket__update_map? BTW, what's xskmap? Is
that a special BPF map type?

> +
>  /* Flags for the libbpf_flags field. */
>  #define XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD (1 << 0)
>
> --
> 2.20.1
>
Mariusz Dudek Nov. 5, 2020, 1:58 p.m. UTC | #2
On Wed, Nov 4, 2020 at 10:07 PM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>

> On Wed, Nov 4, 2020 at 1:47 AM <mariusz.dudek@gmail.com> wrote:

> >

> > From: Mariusz Dudek <mariuszx.dudek@intel.com>

> >

> >         Add support for separation of eBPF program load and xsk socket

> >         creation.

> >

> >         This is needed for use-case when you want to privide as little

> >         privileges as possible to the data plane application that will

> >         handle xsk socket creation and incoming traffic.

> >

> >         With this patch the data entity container can be run with only

> >         CAP_NET_RAW capability to fulfill its purpose of creating xsk

> >         socket and handling packages. In case your umem is larger or

> >         equal process limit for MEMLOCK you need either increase the

> >         limit or CAP_IPC_LOCK capability.

> >

> >         To resolve privileges issue two APIs are introduced:

> >

> >         - xsk_setup_xdp_prog - prepares bpf program if given and

> >         loads it on a selected network interface or loads the built in

> >         XDP program, if no XDP program is supplied. It can also return

> >         xsks_map_fd which is needed by unprivileged process to update

> >         xsks_map with AF_XDP socket "fd"

> >

> >         - xsk_update_xskmap - inserts an AF_XDP socket into an xskmap

> >         for a particular xsk_socket

> >

>

> Your commit message seems to be heavily shifted right...

>

Will be fixed
>

> > Signed-off-by: Mariusz Dudek <mariuszx.dudek@intel.com>

> > ---

> >  tools/lib/bpf/libbpf.map |   2 +

> >  tools/lib/bpf/xsk.c      | 157 ++++++++++++++++++++++++++++++++-------

> >  tools/lib/bpf/xsk.h      |  13 ++++

> >  3 files changed, 146 insertions(+), 26 deletions(-)

> >

>

> [...]

>

> > diff --git a/tools/lib/bpf/xsk.h b/tools/lib/bpf/xsk.h

> > index 1069c46364ff..c42b91935d3c 100644

> > --- a/tools/lib/bpf/xsk.h

> > +++ b/tools/lib/bpf/xsk.h

> > @@ -201,6 +201,19 @@ struct xsk_umem_config {

> >         __u32 flags;

> >  };

> >

> > +struct bpf_prog_cfg {

> > +       struct bpf_insn *prog;

> > +       const char *license;

> > +       size_t insns_cnt;

> > +       int xsks_map_fd;

> > +};

>

> This config will have problems with backward/forward compatibility.

> Please check how xxx_opts are done and use them for extensible options

> structs.

>

I will add struct size as first parameter and #define for __last_field
to be inline with xxx_opts
>

> > +

> > +LIBBPF_API int xsk_setup_xdp_prog(int ifindex,

> > +                                 struct bpf_prog_cfg *cfg,

> > +                                 int *xsks_map_fd);

> > +LIBBPF_API int xsk_update_xskmap(struct xsk_socket *xsk,

> > +                                int xsks_map_fd);

>

> this should be called xsk_socket__update_map? BTW, what's xskmap? Is

> that a special BPF map type?

>

I will change the API name as you suggested. XSKMAP is a special
BPF_MAP_TYPE_XSKMAP.
It defines how packets are being distributed from an XDP program to the XSKs.
> > +

> >  /* Flags for the libbpf_flags field. */

> >  #define XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD (1 << 0)

> >

> > --

> > 2.20.1

> >