@@ -297,6 +297,9 @@ bool bpf_map_meta_equal(const struct bpf_map *meta0,
extern const struct bpf_map_ops bpf_map_offload_ops;
+/* argument may be null or zero */
+#define ARG_FLAG_MAYBE_NULL 1
+
/* function argument constraints */
struct bpf_arg_type {
enum {
@@ -309,7 +312,6 @@ struct bpf_arg_type {
ARG_PTR_TO_MAP_KEY, /* pointer to stack used as map key */
ARG_PTR_TO_MAP_VALUE, /* pointer to stack used as map value */
ARG_PTR_TO_UNINIT_MAP_VALUE, /* pointer to valid memory used to store a map value */
- ARG_PTR_TO_MAP_VALUE_OR_NULL, /* pointer to stack used as map value or NULL */
/* the following constraints used to prototype bpf_memcmp() and other
* functions that access data on eBPF program stack
@@ -345,6 +347,8 @@ struct bpf_arg_type {
ARG_PTR_TO_TIMER, /* pointer to bpf_timer */
__BPF_ARG_TYPE_MAX,
} type;
+
+ u8 flag;
};
/* type of values returned from helper functions */
@@ -265,7 +265,10 @@ const struct bpf_func_proto bpf_inode_storage_get_proto = {
.arg1 = { .type = ARG_CONST_MAP_PTR, }
.arg2 = { .type = ARG_PTR_TO_BTF_ID, }
.arg2_btf_id = &bpf_inode_storage_btf_ids[0],
- .arg3 = { .type = ARG_PTR_TO_MAP_VALUE_OR_NULL, }
+ .arg3 = {
+ .type = ARG_PTR_TO_MAP_VALUE,
+ .flag = ARG_FLAG_MAYBE_NULL,
+ }
.arg4_type = { .type = ARG_ANYTHING, }
};
@@ -324,7 +324,10 @@ const struct bpf_func_proto bpf_task_storage_get_proto = {
.arg1 = { .type = ARG_CONST_MAP_PTR },
.arg2 = { .type = ARG_PTR_TO_BTF_ID },
.arg2_btf_id = &btf_task_struct_ids[0],
- .arg3 = { .type = ARG_PTR_TO_MAP_VALUE_OR_NULL },
+ .arg3 = {
+ .type = ARG_PTR_TO_MAP_VALUE,
+ .flag = ARG_FLAG_MAYBE_NULL,
+ },
.arg4 = { .type = ARG_ANYTHING },
};
@@ -480,7 +480,7 @@ static bool arg_type_may_be_refcounted(struct bpf_arg_type arg)
static bool arg_type_may_be_null(struct bpf_arg_type arg)
{
- return arg.type == ARG_PTR_TO_MAP_VALUE_OR_NULL ||
+ return arg.flag & ARG_FLAG_MAYBE_NULL ||
arg.type == ARG_PTR_TO_MEM_OR_NULL ||
arg.type == ARG_PTR_TO_CTX_OR_NULL ||
arg.type == ARG_PTR_TO_SOCKET_OR_NULL ||
@@ -5089,7 +5089,6 @@ static const struct bpf_reg_types *compatible_reg_types[__BPF_ARG_TYPE_MAX] = {
[ARG_PTR_TO_MAP_KEY] = &map_key_value_types,
[ARG_PTR_TO_MAP_VALUE] = &map_key_value_types,
[ARG_PTR_TO_UNINIT_MAP_VALUE] = &map_key_value_types,
- [ARG_PTR_TO_MAP_VALUE_OR_NULL] = &map_key_value_types,
[ARG_CONST_SIZE] = &scalar_types,
[ARG_CONST_SIZE_OR_ZERO] = &scalar_types,
[ARG_CONST_ALLOC_SIZE_OR_ZERO] = &scalar_types,
@@ -5209,8 +5208,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg_num,
}
if (arg.type == ARG_PTR_TO_MAP_VALUE ||
- arg.type == ARG_PTR_TO_UNINIT_MAP_VALUE ||
- arg.type == ARG_PTR_TO_MAP_VALUE_OR_NULL) {
+ arg.type == ARG_PTR_TO_UNINIT_MAP_VALUE) {
err = resolve_map_arg_type(env, meta, &arg);
if (err)
return err;
@@ -5286,9 +5284,10 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg_num,
meta->map_ptr->key_size, false,
NULL);
} else if (arg.type == ARG_PTR_TO_MAP_VALUE ||
- (arg.type == ARG_PTR_TO_MAP_VALUE_OR_NULL &&
- !register_is_null(reg)) ||
arg.type == ARG_PTR_TO_UNINIT_MAP_VALUE) {
+ if ((arg.flag & ARG_FLAG_MAYBE_NULL) && register_is_null(reg))
+ return err;
+
/* bpf_map_xxx(..., map_ptr, ..., value) call:
* check [value, value + map->value_size) validity
*/
@@ -357,7 +357,10 @@ const struct bpf_func_proto bpf_sk_storage_get_proto = {
.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
.arg1 = { .type = ARG_CONST_MAP_PTR },
.arg2 = { .type = ARG_PTR_TO_BTF_ID_SOCK_COMMON },
- .arg3 = { .type = ARG_PTR_TO_MAP_VALUE_OR_NULL },
+ .arg3 = {
+ .type = ARG_PTR_TO_MAP_VALUE,
+ .flag = ARG_FLAG_MAYBE_NULL,
+ },
.arg4 = { .type = ARG_ANYTHING },
};
@@ -367,7 +370,10 @@ const struct bpf_func_proto bpf_sk_storage_get_cg_sock_proto = {
.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
.arg1 = { .type = ARG_CONST_MAP_PTR },
.arg2 = { .type = ARG_PTR_TO_CTX }, /* context is 'struct sock' */
- .arg3 = { .type = ARG_PTR_TO_MAP_VALUE_OR_NULL },
+ .arg3 = {
+ .type = ARG_PTR_TO_MAP_VALUE,
+ .flag = ARG_FLAG_MAYBE_NULL,
+ },
.arg4 = { .type = ARG_ANYTHING },
};
@@ -438,7 +444,10 @@ const struct bpf_func_proto bpf_sk_storage_get_tracing_proto = {
.arg1 = { .type = ARG_CONST_MAP_PTR },
.arg2 = { .type = ARG_PTR_TO_BTF_ID },
.arg2_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON],
- .arg3 = { .type = ARG_PTR_TO_MAP_VALUE_OR_NULL },
+ .arg3 = {
+ .type = ARG_PTR_TO_MAP_VALUE,
+ .flag = ARG_FLAG_MAYBE_NULL,
+ },
.arg4 = { .type = ARG_ANYTHING },
.allowed = bpf_sk_storage_tracing_allowed,
};
Remove ARG_PTR_TO_MAP_VALUE_OR_NULL and use flag to mark that the argument may be null. Signed-off-by: Hao Luo <haoluo@google.com> --- include/linux/bpf.h | 6 +++++- kernel/bpf/bpf_inode_storage.c | 5 ++++- kernel/bpf/bpf_task_storage.c | 5 ++++- kernel/bpf/verifier.c | 11 +++++------ net/core/bpf_sk_storage.c | 15 ++++++++++++--- 5 files changed, 30 insertions(+), 12 deletions(-)