lkml.org 
[lkml]   [2022]   [May]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 2/3] bpf: Introduce bpf_map_verified_data_size() helper
Date
Introduce the bpf_map_verified_data_size() helper to get the verified data
size from a signed map value, as parsed by the kernel with
bpf_map_verify_value_sig().

The same information might be provided by user space tools as well without
any helper, for example by adding a second unsigned integer after the
verified data+sig size field.

However, this alternative seems to increase the code complexity: the kernel
has to parse two unsigned integers and check their consistency; user space
tools have to parse the module-style appended signature to get the verified
data size.

Alternatively, each eBPF program could parse the module-style signature by
itself, but this would cause duplication of the code.

Adding a new helper seems the best choice, it only needs to call the
existing function bpf_map_verify_value_sig() and pass the result to the
caller.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
include/uapi/linux/bpf.h | 8 ++++++++
kernel/bpf/helpers.c | 15 +++++++++++++++
tools/include/uapi/linux/bpf.h | 8 ++++++++
3 files changed, 31 insertions(+)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index a8e7803d2593..4a05caa49419 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -5252,6 +5252,13 @@ union bpf_attr {
* Pointer to the underlying dynptr data, NULL if the dynptr is
* read-only, if the dynptr is invalid, or if the offset and length
* is out of bounds.
+ *
+ * long bpf_map_verified_data_size(const void *value, u32 value_size)
+ * Description
+ * Parse signed map value in *value* with size *value_size*.
+ * Return
+ * The size of verified data on success, or a negative error in
+ * case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -5458,6 +5465,7 @@ union bpf_attr {
FN(dynptr_read), \
FN(dynptr_write), \
FN(dynptr_data), \
+ FN(bpf_map_verified_data_size), \
/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 225806a02efb..78c29c4e5d3f 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -1575,6 +1575,19 @@ const struct bpf_func_proto bpf_dynptr_data_proto = {
.arg3_type = ARG_CONST_ALLOC_SIZE_OR_ZERO,
};

+BPF_CALL_2(bpf_map_verified_data_size, const void *, value, u32, value_size)
+{
+ return bpf_map_verify_value_sig(value, value_size, false);
+}
+
+const struct bpf_func_proto bpf_map_verified_data_size_proto = {
+ .func = bpf_map_verified_data_size,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_MEM,
+ .arg2_type = ARG_CONST_SIZE_OR_ZERO,
+};
+
const struct bpf_func_proto bpf_get_current_task_proto __weak;
const struct bpf_func_proto bpf_get_current_task_btf_proto __weak;
const struct bpf_func_proto bpf_probe_read_user_proto __weak;
@@ -1643,6 +1656,8 @@ bpf_base_func_proto(enum bpf_func_id func_id)
return &bpf_dynptr_write_proto;
case BPF_FUNC_dynptr_data:
return &bpf_dynptr_data_proto;
+ case BPF_FUNC_bpf_map_verified_data_size:
+ return &bpf_map_verified_data_size_proto;
default:
break;
}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index a8e7803d2593..4a05caa49419 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -5252,6 +5252,13 @@ union bpf_attr {
* Pointer to the underlying dynptr data, NULL if the dynptr is
* read-only, if the dynptr is invalid, or if the offset and length
* is out of bounds.
+ *
+ * long bpf_map_verified_data_size(const void *value, u32 value_size)
+ * Description
+ * Parse signed map value in *value* with size *value_size*.
+ * Return
+ * The size of verified data on success, or a negative error in
+ * case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -5458,6 +5465,7 @@ union bpf_attr {
FN(dynptr_read), \
FN(dynptr_write), \
FN(dynptr_data), \
+ FN(bpf_map_verified_data_size), \
/* */

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
--
2.25.1
\
 
 \ /
  Last update: 2022-05-25 15:24    [W:0.262 / U:0.220 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site