[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220525132115.896698-3-roberto.sassu@huawei.com>
Date: Wed, 25 May 2022 15:21:14 +0200
From: Roberto Sassu <roberto.sassu@...wei.com>
To: <ast@...nel.org>, <daniel@...earbox.net>, <andrii@...nel.org>,
<kpsingh@...nel.org>
CC: <bpf@...r.kernel.org>, <netdev@...r.kernel.org>,
<linux-kselftest@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
Roberto Sassu <roberto.sassu@...wei.com>
Subject: [PATCH 2/3] bpf: Introduce bpf_map_verified_data_size() helper
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@...wei.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
Powered by blists - more mailing lists