@@ -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
@@ -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;
}
@@ -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
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(+)