On Thu, Jun 13, 2019 at 01:16:21PM +0200, Ján Tomko wrote:
On Thu, Apr 25, 2019 at 09:44:20AM +0200, Pavel Hrdina wrote:
> This function loads the BPF prog with prepared map into kernel and
> attaches it into guest cgroup. It can be also used to replace existing
> program in the cgroup if we need to resize BPF map to store more rules
> for devices. The old program will be closed and removed from kernel.
>
> There are two possible ways how to create BPF program:
>
> - One way is to write simple C-like code which can by compiled into
> BPF object file which can be loaded into kernel using elfutils.
>
> - The second way is to define macros which looks like assembler
s/looks/look/
> instructions and can be used directly to create BPF program that
> can be directly loaded into kernel.
>
> Since the program is not too complex we can use the second option.
I can live with that, since it saves us the dependency on clang,
and it probably won't require many changes, but please include all
the steps necessary to regenerate it (see below).
>
> If there is no program, all devices are allowed, if there is some
> program it is executed and based on the exit status the access is
> denied for 0 and allowed for 1.
>
> Our program will follow these rules:
>
> - first it will try to look for the specific key using major and
> minor to see if there is any rule for that specific device
>
> - if there is no specific rule it will try to look for any rule that
> matches only major of the device
>
> - if there is no match with major it will try the same but with
> minor of the device
>
> - as the last attempt it will try to look for rule for all devices
> and if there is no match it will return 0 to deny that access
>
> Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
> ---
> src/libvirt_private.syms | 1 +
> src/util/vircgrouppriv.h | 10 ++
> src/util/vircgroupv2devices.c | 276 ++++++++++++++++++++++++++++++++++
> src/util/vircgroupv2devices.h | 5 +
> 4 files changed, 292 insertions(+)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 9eac05009c..24a783840f 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1653,6 +1653,7 @@ virCgroupV1Register;
> virCgroupV2Register;
>
> # util/vircgroupv2devices.h
> +virCgroupV2DevicesAttachProg;
> virCgroupV2DevicesAvailable;
>
> # util/virclosecallbacks.h
> diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
> index 9110c77297..7eba4ade23 100644
> --- a/src/util/vircgrouppriv.h
> +++ b/src/util/vircgrouppriv.h
> @@ -41,10 +41,20 @@ struct _virCgroupV1Controller {
> typedef struct _virCgroupV1Controller virCgroupV1Controller;
> typedef virCgroupV1Controller *virCgroupV1ControllerPtr;
>
> +struct _virCgroupV2Devices {
> + int mapfd;
> + int progfd;
> + ssize_t count;
> + ssize_t max;
> +};
> +typedef struct _virCgroupV2Devices virCgroupV2Devices;
> +typedef virCgroupV2Devices *virCgroupV2DevicesPtr;
> +
> struct _virCgroupV2Controller {
> int controllers;
> char *mountPoint;
> char *placement;
> + virCgroupV2Devices devices;
> };
> typedef struct _virCgroupV2Controller virCgroupV2Controller;
> typedef virCgroupV2Controller *virCgroupV2ControllerPtr;
> diff --git a/src/util/vircgroupv2devices.c b/src/util/vircgroupv2devices.c
> index 10080d4fff..c8686e8768 100644
> --- a/src/util/vircgroupv2devices.c
> +++ b/src/util/vircgroupv2devices.c
> @@ -30,6 +30,7 @@
> #define LIBVIRT_VIRCGROUPPRIV_H_ALLOW
> #include "vircgrouppriv.h"
>
> +#include "viralloc.h"
> #include "virbpf.h"
> #include "vircgroup.h"
> #include "vircgroupv2devices.h"
> @@ -64,10 +65,285 @@ virCgroupV2DevicesAvailable(virCgroupPtr group)
> VIR_FORCE_CLOSE(cgroupfd);
> return ret;
> }
> +
> +
> +/* Steps to get assembly version of devices BPF program:
> + *
> + * Save the following program into bpfprog.c, compile it using clang:
It would be nicer to have the file separate, with this comment there,
to save the developer the trouble of stripping the asterisks.
Sure, I can move that into a separate file, I just wanted to have it
closer to the assembly-like code.
> + *
> + * clang -O2 -Wall -target bpf -c bpfprog.c -o bpfprog.o
> + *
> + * Now you can use llvm-objdump to get the list if instructions:
> + *
> + * llvm-objdump -S -no-show-raw-insn bpfprog.o
> + *
> + * which can be converted into program using VIR_BPF_* macros.
Did you convert them manually? Can you share the script here?
Yes, it was done manually as I did not create any script to do it.
Pavel