bpf: Rename MEM_ALLOC to MEM_RINGBUF
Currently, verifier uses MEM_ALLOC type tag to specially tag memory returned from bpf_ringbuf_reserve helper. However, this is currently only used for this purpose and there is an implicit assumption that it only refers to ringbuf memory (e.g. the check for ARG_PTR_TO_ALLOC_MEM in check_func_arg_reg_off). Hence, rename MEM_ALLOC to MEM_RINGBUF to indicate this special relationship and instead open the use of MEM_ALLOC for more generic allocations made for user types. Also, since ARG_PTR_TO_ALLOC_MEM_OR_NULL is unused, simply drop it. Finally, update selftests using 'alloc_' verifier string to 'ringbuf_'. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20221114191547.1694267-7-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
2de2669b4e
commit
894f2a8b16
@ -488,10 +488,8 @@ enum bpf_type_flag {
|
|||||||
*/
|
*/
|
||||||
MEM_RDONLY = BIT(1 + BPF_BASE_TYPE_BITS),
|
MEM_RDONLY = BIT(1 + BPF_BASE_TYPE_BITS),
|
||||||
|
|
||||||
/* MEM was "allocated" from a different helper, and cannot be mixed
|
/* MEM points to BPF ring buffer reservation. */
|
||||||
* with regular non-MEM_ALLOC'ed MEM types.
|
MEM_RINGBUF = BIT(2 + BPF_BASE_TYPE_BITS),
|
||||||
*/
|
|
||||||
MEM_ALLOC = BIT(2 + BPF_BASE_TYPE_BITS),
|
|
||||||
|
|
||||||
/* MEM is in user address space. */
|
/* MEM is in user address space. */
|
||||||
MEM_USER = BIT(3 + BPF_BASE_TYPE_BITS),
|
MEM_USER = BIT(3 + BPF_BASE_TYPE_BITS),
|
||||||
@ -565,7 +563,7 @@ enum bpf_arg_type {
|
|||||||
ARG_PTR_TO_LONG, /* pointer to long */
|
ARG_PTR_TO_LONG, /* pointer to long */
|
||||||
ARG_PTR_TO_SOCKET, /* pointer to bpf_sock (fullsock) */
|
ARG_PTR_TO_SOCKET, /* pointer to bpf_sock (fullsock) */
|
||||||
ARG_PTR_TO_BTF_ID, /* pointer to in-kernel struct */
|
ARG_PTR_TO_BTF_ID, /* pointer to in-kernel struct */
|
||||||
ARG_PTR_TO_ALLOC_MEM, /* pointer to dynamically allocated memory */
|
ARG_PTR_TO_RINGBUF_MEM, /* pointer to dynamically reserved ringbuf memory */
|
||||||
ARG_CONST_ALLOC_SIZE_OR_ZERO, /* number of allocated bytes requested */
|
ARG_CONST_ALLOC_SIZE_OR_ZERO, /* number of allocated bytes requested */
|
||||||
ARG_PTR_TO_BTF_ID_SOCK_COMMON, /* pointer to in-kernel sock_common or bpf-mirrored bpf_sock */
|
ARG_PTR_TO_BTF_ID_SOCK_COMMON, /* pointer to in-kernel sock_common or bpf-mirrored bpf_sock */
|
||||||
ARG_PTR_TO_PERCPU_BTF_ID, /* pointer to in-kernel percpu type */
|
ARG_PTR_TO_PERCPU_BTF_ID, /* pointer to in-kernel percpu type */
|
||||||
@ -582,7 +580,6 @@ enum bpf_arg_type {
|
|||||||
ARG_PTR_TO_MEM_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_MEM,
|
ARG_PTR_TO_MEM_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_MEM,
|
||||||
ARG_PTR_TO_CTX_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_CTX,
|
ARG_PTR_TO_CTX_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_CTX,
|
||||||
ARG_PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_SOCKET,
|
ARG_PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_SOCKET,
|
||||||
ARG_PTR_TO_ALLOC_MEM_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_ALLOC_MEM,
|
|
||||||
ARG_PTR_TO_STACK_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_STACK,
|
ARG_PTR_TO_STACK_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_STACK,
|
||||||
ARG_PTR_TO_BTF_ID_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_BTF_ID,
|
ARG_PTR_TO_BTF_ID_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_BTF_ID,
|
||||||
/* pointer to memory does not need to be initialized, helper function must fill
|
/* pointer to memory does not need to be initialized, helper function must fill
|
||||||
@ -617,7 +614,7 @@ enum bpf_return_type {
|
|||||||
RET_PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_SOCKET,
|
RET_PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_SOCKET,
|
||||||
RET_PTR_TO_TCP_SOCK_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_TCP_SOCK,
|
RET_PTR_TO_TCP_SOCK_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_TCP_SOCK,
|
||||||
RET_PTR_TO_SOCK_COMMON_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_SOCK_COMMON,
|
RET_PTR_TO_SOCK_COMMON_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_SOCK_COMMON,
|
||||||
RET_PTR_TO_ALLOC_MEM_OR_NULL = PTR_MAYBE_NULL | MEM_ALLOC | RET_PTR_TO_MEM,
|
RET_PTR_TO_RINGBUF_MEM_OR_NULL = PTR_MAYBE_NULL | MEM_RINGBUF | RET_PTR_TO_MEM,
|
||||||
RET_PTR_TO_DYNPTR_MEM_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_MEM,
|
RET_PTR_TO_DYNPTR_MEM_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_MEM,
|
||||||
RET_PTR_TO_BTF_ID_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_BTF_ID,
|
RET_PTR_TO_BTF_ID_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_BTF_ID,
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ BPF_CALL_3(bpf_ringbuf_reserve, struct bpf_map *, map, u64, size, u64, flags)
|
|||||||
|
|
||||||
const struct bpf_func_proto bpf_ringbuf_reserve_proto = {
|
const struct bpf_func_proto bpf_ringbuf_reserve_proto = {
|
||||||
.func = bpf_ringbuf_reserve,
|
.func = bpf_ringbuf_reserve,
|
||||||
.ret_type = RET_PTR_TO_ALLOC_MEM_OR_NULL,
|
.ret_type = RET_PTR_TO_RINGBUF_MEM_OR_NULL,
|
||||||
.arg1_type = ARG_CONST_MAP_PTR,
|
.arg1_type = ARG_CONST_MAP_PTR,
|
||||||
.arg2_type = ARG_CONST_ALLOC_SIZE_OR_ZERO,
|
.arg2_type = ARG_CONST_ALLOC_SIZE_OR_ZERO,
|
||||||
.arg3_type = ARG_ANYTHING,
|
.arg3_type = ARG_ANYTHING,
|
||||||
@ -490,7 +490,7 @@ BPF_CALL_2(bpf_ringbuf_submit, void *, sample, u64, flags)
|
|||||||
const struct bpf_func_proto bpf_ringbuf_submit_proto = {
|
const struct bpf_func_proto bpf_ringbuf_submit_proto = {
|
||||||
.func = bpf_ringbuf_submit,
|
.func = bpf_ringbuf_submit,
|
||||||
.ret_type = RET_VOID,
|
.ret_type = RET_VOID,
|
||||||
.arg1_type = ARG_PTR_TO_ALLOC_MEM | OBJ_RELEASE,
|
.arg1_type = ARG_PTR_TO_RINGBUF_MEM | OBJ_RELEASE,
|
||||||
.arg2_type = ARG_ANYTHING,
|
.arg2_type = ARG_ANYTHING,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -503,7 +503,7 @@ BPF_CALL_2(bpf_ringbuf_discard, void *, sample, u64, flags)
|
|||||||
const struct bpf_func_proto bpf_ringbuf_discard_proto = {
|
const struct bpf_func_proto bpf_ringbuf_discard_proto = {
|
||||||
.func = bpf_ringbuf_discard,
|
.func = bpf_ringbuf_discard,
|
||||||
.ret_type = RET_VOID,
|
.ret_type = RET_VOID,
|
||||||
.arg1_type = ARG_PTR_TO_ALLOC_MEM | OBJ_RELEASE,
|
.arg1_type = ARG_PTR_TO_RINGBUF_MEM | OBJ_RELEASE,
|
||||||
.arg2_type = ARG_ANYTHING,
|
.arg2_type = ARG_ANYTHING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -577,8 +577,8 @@ static const char *reg_type_str(struct bpf_verifier_env *env,
|
|||||||
|
|
||||||
if (type & MEM_RDONLY)
|
if (type & MEM_RDONLY)
|
||||||
strncpy(prefix, "rdonly_", 32);
|
strncpy(prefix, "rdonly_", 32);
|
||||||
if (type & MEM_ALLOC)
|
if (type & MEM_RINGBUF)
|
||||||
strncpy(prefix, "alloc_", 32);
|
strncpy(prefix, "ringbuf_", 32);
|
||||||
if (type & MEM_USER)
|
if (type & MEM_USER)
|
||||||
strncpy(prefix, "user_", 32);
|
strncpy(prefix, "user_", 32);
|
||||||
if (type & MEM_PERCPU)
|
if (type & MEM_PERCPU)
|
||||||
@ -5785,7 +5785,7 @@ static const struct bpf_reg_types mem_types = {
|
|||||||
PTR_TO_MAP_KEY,
|
PTR_TO_MAP_KEY,
|
||||||
PTR_TO_MAP_VALUE,
|
PTR_TO_MAP_VALUE,
|
||||||
PTR_TO_MEM,
|
PTR_TO_MEM,
|
||||||
PTR_TO_MEM | MEM_ALLOC,
|
PTR_TO_MEM | MEM_RINGBUF,
|
||||||
PTR_TO_BUF,
|
PTR_TO_BUF,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -5803,7 +5803,7 @@ static const struct bpf_reg_types int_ptr_types = {
|
|||||||
static const struct bpf_reg_types fullsock_types = { .types = { PTR_TO_SOCKET } };
|
static const struct bpf_reg_types fullsock_types = { .types = { PTR_TO_SOCKET } };
|
||||||
static const struct bpf_reg_types scalar_types = { .types = { SCALAR_VALUE } };
|
static const struct bpf_reg_types scalar_types = { .types = { SCALAR_VALUE } };
|
||||||
static const struct bpf_reg_types context_types = { .types = { PTR_TO_CTX } };
|
static const struct bpf_reg_types context_types = { .types = { PTR_TO_CTX } };
|
||||||
static const struct bpf_reg_types alloc_mem_types = { .types = { PTR_TO_MEM | MEM_ALLOC } };
|
static const struct bpf_reg_types ringbuf_mem_types = { .types = { PTR_TO_MEM | MEM_RINGBUF } };
|
||||||
static const struct bpf_reg_types const_map_ptr_types = { .types = { CONST_PTR_TO_MAP } };
|
static const struct bpf_reg_types const_map_ptr_types = { .types = { CONST_PTR_TO_MAP } };
|
||||||
static const struct bpf_reg_types btf_ptr_types = { .types = { PTR_TO_BTF_ID } };
|
static const struct bpf_reg_types btf_ptr_types = { .types = { PTR_TO_BTF_ID } };
|
||||||
static const struct bpf_reg_types spin_lock_types = { .types = { PTR_TO_MAP_VALUE } };
|
static const struct bpf_reg_types spin_lock_types = { .types = { PTR_TO_MAP_VALUE } };
|
||||||
@ -5836,7 +5836,7 @@ static const struct bpf_reg_types *compatible_reg_types[__BPF_ARG_TYPE_MAX] = {
|
|||||||
[ARG_PTR_TO_BTF_ID] = &btf_ptr_types,
|
[ARG_PTR_TO_BTF_ID] = &btf_ptr_types,
|
||||||
[ARG_PTR_TO_SPIN_LOCK] = &spin_lock_types,
|
[ARG_PTR_TO_SPIN_LOCK] = &spin_lock_types,
|
||||||
[ARG_PTR_TO_MEM] = &mem_types,
|
[ARG_PTR_TO_MEM] = &mem_types,
|
||||||
[ARG_PTR_TO_ALLOC_MEM] = &alloc_mem_types,
|
[ARG_PTR_TO_RINGBUF_MEM] = &ringbuf_mem_types,
|
||||||
[ARG_PTR_TO_INT] = &int_ptr_types,
|
[ARG_PTR_TO_INT] = &int_ptr_types,
|
||||||
[ARG_PTR_TO_LONG] = &int_ptr_types,
|
[ARG_PTR_TO_LONG] = &int_ptr_types,
|
||||||
[ARG_PTR_TO_PERCPU_BTF_ID] = &percpu_btf_ptr_types,
|
[ARG_PTR_TO_PERCPU_BTF_ID] = &percpu_btf_ptr_types,
|
||||||
@ -5957,14 +5957,14 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env,
|
|||||||
case PTR_TO_MAP_VALUE:
|
case PTR_TO_MAP_VALUE:
|
||||||
case PTR_TO_MEM:
|
case PTR_TO_MEM:
|
||||||
case PTR_TO_MEM | MEM_RDONLY:
|
case PTR_TO_MEM | MEM_RDONLY:
|
||||||
case PTR_TO_MEM | MEM_ALLOC:
|
case PTR_TO_MEM | MEM_RINGBUF:
|
||||||
case PTR_TO_BUF:
|
case PTR_TO_BUF:
|
||||||
case PTR_TO_BUF | MEM_RDONLY:
|
case PTR_TO_BUF | MEM_RDONLY:
|
||||||
case SCALAR_VALUE:
|
case SCALAR_VALUE:
|
||||||
/* Some of the argument types nevertheless require a
|
/* Some of the argument types nevertheless require a
|
||||||
* zero register offset.
|
* zero register offset.
|
||||||
*/
|
*/
|
||||||
if (base_type(arg_type) != ARG_PTR_TO_ALLOC_MEM)
|
if (base_type(arg_type) != ARG_PTR_TO_RINGBUF_MEM)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
/* All the rest must be rejected, except PTR_TO_BTF_ID which allows
|
/* All the rest must be rejected, except PTR_TO_BTF_ID which allows
|
||||||
|
@ -17,7 +17,7 @@ static struct {
|
|||||||
{"ringbuf_missing_release2", "Unreleased reference id=2"},
|
{"ringbuf_missing_release2", "Unreleased reference id=2"},
|
||||||
{"ringbuf_missing_release_callback", "Unreleased reference id"},
|
{"ringbuf_missing_release_callback", "Unreleased reference id"},
|
||||||
{"use_after_invalid", "Expected an initialized dynptr as arg #3"},
|
{"use_after_invalid", "Expected an initialized dynptr as arg #3"},
|
||||||
{"ringbuf_invalid_api", "type=mem expected=alloc_mem"},
|
{"ringbuf_invalid_api", "type=mem expected=ringbuf_mem"},
|
||||||
{"add_dynptr_to_map1", "invalid indirect read from stack"},
|
{"add_dynptr_to_map1", "invalid indirect read from stack"},
|
||||||
{"add_dynptr_to_map2", "invalid indirect read from stack"},
|
{"add_dynptr_to_map2", "invalid indirect read from stack"},
|
||||||
{"data_slice_out_of_bounds_ringbuf", "value is outside of the allowed memory range"},
|
{"data_slice_out_of_bounds_ringbuf", "value is outside of the allowed memory range"},
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
},
|
},
|
||||||
.fixup_map_ringbuf = { 1 },
|
.fixup_map_ringbuf = { 1 },
|
||||||
.result = REJECT,
|
.result = REJECT,
|
||||||
.errstr = "dereference of modified alloc_mem ptr R1",
|
.errstr = "dereference of modified ringbuf_mem ptr R1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ringbuf: invalid reservation offset 2",
|
"ringbuf: invalid reservation offset 2",
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
},
|
},
|
||||||
.fixup_map_ringbuf = { 1 },
|
.fixup_map_ringbuf = { 1 },
|
||||||
.result = REJECT,
|
.result = REJECT,
|
||||||
.errstr = "R0 pointer arithmetic on alloc_mem_or_null prohibited",
|
.errstr = "R0 pointer arithmetic on ringbuf_mem_or_null prohibited",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"check corrupted spill/fill",
|
"check corrupted spill/fill",
|
||||||
|
Loading…
Reference in New Issue
Block a user