mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-26 14:17:26 -04:00
bpf: Introduce ARG_PTR_TO_{INT,LONG} arg types
Currently the way to pass result from BPF helper to BPF program is to provide memory area defined by pointer and size: func(void *, size_t). It works great for generic use-case, but for simple types, such as int, it's overkill and consumes two arguments when it could use just one. Introduce new argument types ARG_PTR_TO_INT and ARG_PTR_TO_LONG to be able to pass result from helper to program via pointer to int and long correspondingly: func(int *) or func(long *). New argument types are similar to ARG_PTR_TO_MEM with the following differences: * they don't require corresponding ARG_CONST_SIZE argument, predefined access sizes are used instead (32bit for int, 64bit for long); * it's possible to use more than one such an argument in a helper; * provided pointers have to be aligned. It's easy to introduce similar ARG_PTR_TO_CHAR and ARG_PTR_TO_SHORT argument types. It's not done due to lack of use-case though. Signed-off-by: Andrey Ignatov <rdna@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
9a1027e525
commit
57c3bb725a
2 changed files with 31 additions and 0 deletions
|
@ -202,6 +202,8 @@ enum bpf_arg_type {
|
||||||
ARG_ANYTHING, /* any (initialized) argument is ok */
|
ARG_ANYTHING, /* any (initialized) argument is ok */
|
||||||
ARG_PTR_TO_SPIN_LOCK, /* pointer to bpf_spin_lock */
|
ARG_PTR_TO_SPIN_LOCK, /* pointer to bpf_spin_lock */
|
||||||
ARG_PTR_TO_SOCK_COMMON, /* pointer to sock_common */
|
ARG_PTR_TO_SOCK_COMMON, /* pointer to sock_common */
|
||||||
|
ARG_PTR_TO_INT, /* pointer to int */
|
||||||
|
ARG_PTR_TO_LONG, /* pointer to long */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* type of values returned from helper functions */
|
/* type of values returned from helper functions */
|
||||||
|
|
|
@ -2462,6 +2462,22 @@ static bool arg_type_is_mem_size(enum bpf_arg_type type)
|
||||||
type == ARG_CONST_SIZE_OR_ZERO;
|
type == ARG_CONST_SIZE_OR_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool arg_type_is_int_ptr(enum bpf_arg_type type)
|
||||||
|
{
|
||||||
|
return type == ARG_PTR_TO_INT ||
|
||||||
|
type == ARG_PTR_TO_LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int int_ptr_type_to_size(enum bpf_arg_type type)
|
||||||
|
{
|
||||||
|
if (type == ARG_PTR_TO_INT)
|
||||||
|
return sizeof(u32);
|
||||||
|
else if (type == ARG_PTR_TO_LONG)
|
||||||
|
return sizeof(u64);
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
|
static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
|
||||||
enum bpf_arg_type arg_type,
|
enum bpf_arg_type arg_type,
|
||||||
struct bpf_call_arg_meta *meta)
|
struct bpf_call_arg_meta *meta)
|
||||||
|
@ -2554,6 +2570,12 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
|
||||||
type != expected_type)
|
type != expected_type)
|
||||||
goto err_type;
|
goto err_type;
|
||||||
meta->raw_mode = arg_type == ARG_PTR_TO_UNINIT_MEM;
|
meta->raw_mode = arg_type == ARG_PTR_TO_UNINIT_MEM;
|
||||||
|
} else if (arg_type_is_int_ptr(arg_type)) {
|
||||||
|
expected_type = PTR_TO_STACK;
|
||||||
|
if (!type_is_pkt_pointer(type) &&
|
||||||
|
type != PTR_TO_MAP_VALUE &&
|
||||||
|
type != expected_type)
|
||||||
|
goto err_type;
|
||||||
} else {
|
} else {
|
||||||
verbose(env, "unsupported arg_type %d\n", arg_type);
|
verbose(env, "unsupported arg_type %d\n", arg_type);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -2635,6 +2657,13 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
|
||||||
err = check_helper_mem_access(env, regno - 1,
|
err = check_helper_mem_access(env, regno - 1,
|
||||||
reg->umax_value,
|
reg->umax_value,
|
||||||
zero_size_allowed, meta);
|
zero_size_allowed, meta);
|
||||||
|
} else if (arg_type_is_int_ptr(arg_type)) {
|
||||||
|
int size = int_ptr_type_to_size(arg_type);
|
||||||
|
|
||||||
|
err = check_helper_mem_access(env, regno, size, false, meta);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
err = check_ptr_alignment(env, reg, 0, size, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue