mbox series

[0/3] bpf: Add support for maps with authenticated values

Message ID 20220525132115.896698-1-roberto.sassu@huawei.com (mailing list archive)
Headers show
Series bpf: Add support for maps with authenticated values | expand

Message

Roberto Sassu May 25, 2022, 1:21 p.m. UTC
One of the desirable features in security is the ability to restrict import
of data to a given system based on data authenticity. If data import can be
restricted, it would be possible to enforce a system-wide policy based on
the signing keys the system owner trusts.

This feature is widely used in the kernel. For example, if the restriction
is enabled, kernel modules can be plugged in only if they are signed with a
key whose public part is in the primary or secondary keyring.

For eBPF, it can be useful as well. For example, it might be useful to
authenticate data an eBPF program makes security decisions on.

The initial idea for this feature was to provide an helper that eBPF
programs might call to authenticate data whenever necessary. However, this
restricts the ability to use that helper only in sleepable programs (due to
crypto operations). Furthermore, data authentication would have been
responsibility of eBPF programs.

The proposed implementation instead shifts the responsibility of data
authentication to the eBPF subsystem, upon request by the users. Whenever
the users desire such feature, they just have to set a new map flag called
BPF_F_VERIFY_ELEM. The eBPF subsystem ensures that only authenticated data
can be added to the map. The check is performed during the execution of the
bpf() system call when the commands are BPF_MAP_UPDATE_ELEM or
BPF_MAP_UPDATE_BATCH. Since memory regions are not verified, usage of the
BPF_F_MMAPABLE map flag is forbidden when BPF_F_VERIFY_ELEM is set.

An advantage of shifting the responsibility of data authentication to the
eBPF subsystem is that it can be offered to any kind of eBPF programs, not
only the sleepable ones.

When the new map flag BPF_F_VERIFY_ELEM is set, users have to provide a map
value in the following format:

+-------------------------------+---------------+-----+-----------------+
| verified data+sig size (be32) | verified data | sig | unverified data |
+-------------------------------+---------------+-----+-----------------+

This is mostly the same format adopted for kernel modules, with the
exception of the first field, as the size cannot be determined otherwise
due to the fixed map value size. More details can be found in patch 1.

Since the kernel already parses the format above, it was convenient to
introduce also a new helper, called bpf_map_verified_data_size(), to
return the size of verified data to the caller. This is done in patch 2.

Finally, the added functionality is tested in patch 3.

Roberto Sassu (3):
  bpf: Add BPF_F_VERIFY_ELEM to require signature verification on map
    values
  bpf: Introduce bpf_map_verified_data_size() helper
  bpf: Add tests for signed map values

 include/linux/bpf.h                           |   7 +
 include/uapi/linux/bpf.h                      |  11 +
 kernel/bpf/arraymap.c                         |   2 +-
 kernel/bpf/helpers.c                          |  15 ++
 kernel/bpf/syscall.c                          |  70 ++++++
 tools/include/uapi/linux/bpf.h                |  11 +
 .../bpf/prog_tests/test_map_value_sig.c       | 212 ++++++++++++++++++
 .../selftests/bpf/progs/map_value_sig.c       |  50 +++++
 8 files changed, 377 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/test_map_value_sig.c
 create mode 100644 tools/testing/selftests/bpf/progs/map_value_sig.c