bpf: Allow specifying a BTF ID per argument in function protos
Function prototypes using ARG_PTR_TO_BTF_ID currently use two ways to signal which BTF IDs are acceptable. First, bpf_func_proto.btf_id is an array of IDs, one for each argument. This array is only accessed up to the highest numbered argument that uses ARG_PTR_TO_BTF_ID and may therefore be less than five arguments long. It usually points at a BTF_ID_LIST. Second, check_btf_id is a function pointer that is called by the verifier if present. It gets the actual BTF ID of the register, and the argument number we're currently checking. It turns out that the only user check_arg_btf_id ignores the argument, and is simply used to check whether the BTF ID has a struct sock_common at it's start. Replace both of these mechanisms with an explicit BTF ID for each argument in a function proto. Thanks to btf_struct_ids_match this is very flexible: check_arg_btf_id can be replaced by requiring struct sock_common. Signed-off-by: Lorenz Bauer <lmb@cloudflare.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Martin KaFai Lau <kafai@fb.com> Link: https://lore.kernel.org/bpf/20200921121227.255763-5-lmb@cloudflare.com
This commit is contained in:
committed by
Alexei Starovoitov
parent
27774b7073
commit
9436ef6e86
@ -378,19 +378,15 @@ const struct bpf_func_proto bpf_sk_storage_delete_proto = {
|
||||
.arg2_type = ARG_PTR_TO_SOCKET,
|
||||
};
|
||||
|
||||
BTF_ID_LIST(sk_storage_btf_ids)
|
||||
BTF_ID_UNUSED
|
||||
BTF_ID(struct, sock)
|
||||
|
||||
const struct bpf_func_proto sk_storage_get_btf_proto = {
|
||||
.func = bpf_sk_storage_get,
|
||||
.gpl_only = false,
|
||||
.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
|
||||
.arg1_type = ARG_CONST_MAP_PTR,
|
||||
.arg2_type = ARG_PTR_TO_BTF_ID,
|
||||
.arg2_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK],
|
||||
.arg3_type = ARG_PTR_TO_MAP_VALUE_OR_NULL,
|
||||
.arg4_type = ARG_ANYTHING,
|
||||
.btf_id = sk_storage_btf_ids,
|
||||
};
|
||||
|
||||
const struct bpf_func_proto sk_storage_delete_btf_proto = {
|
||||
@ -399,7 +395,7 @@ const struct bpf_func_proto sk_storage_delete_btf_proto = {
|
||||
.ret_type = RET_INTEGER,
|
||||
.arg1_type = ARG_CONST_MAP_PTR,
|
||||
.arg2_type = ARG_PTR_TO_BTF_ID,
|
||||
.btf_id = sk_storage_btf_ids,
|
||||
.arg2_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK],
|
||||
};
|
||||
|
||||
struct bpf_sk_storage_diag {
|
||||
|
@ -3803,19 +3803,18 @@ static const struct bpf_func_proto bpf_skb_event_output_proto = {
|
||||
.arg5_type = ARG_CONST_SIZE_OR_ZERO,
|
||||
};
|
||||
|
||||
BTF_ID_LIST(bpf_skb_output_btf_ids)
|
||||
BTF_ID(struct, sk_buff)
|
||||
BTF_ID_LIST_SINGLE(bpf_skb_output_btf_ids, struct, sk_buff)
|
||||
|
||||
const struct bpf_func_proto bpf_skb_output_proto = {
|
||||
.func = bpf_skb_event_output,
|
||||
.gpl_only = true,
|
||||
.ret_type = RET_INTEGER,
|
||||
.arg1_type = ARG_PTR_TO_BTF_ID,
|
||||
.arg1_btf_id = &bpf_skb_output_btf_ids[0],
|
||||
.arg2_type = ARG_CONST_MAP_PTR,
|
||||
.arg3_type = ARG_ANYTHING,
|
||||
.arg4_type = ARG_PTR_TO_MEM,
|
||||
.arg5_type = ARG_CONST_SIZE_OR_ZERO,
|
||||
.btf_id = bpf_skb_output_btf_ids,
|
||||
};
|
||||
|
||||
static unsigned short bpf_tunnel_key_af(u64 flags)
|
||||
@ -4199,19 +4198,18 @@ static const struct bpf_func_proto bpf_xdp_event_output_proto = {
|
||||
.arg5_type = ARG_CONST_SIZE_OR_ZERO,
|
||||
};
|
||||
|
||||
BTF_ID_LIST(bpf_xdp_output_btf_ids)
|
||||
BTF_ID(struct, xdp_buff)
|
||||
BTF_ID_LIST_SINGLE(bpf_xdp_output_btf_ids, struct, xdp_buff)
|
||||
|
||||
const struct bpf_func_proto bpf_xdp_output_proto = {
|
||||
.func = bpf_xdp_event_output,
|
||||
.gpl_only = true,
|
||||
.ret_type = RET_INTEGER,
|
||||
.arg1_type = ARG_PTR_TO_BTF_ID,
|
||||
.arg1_btf_id = &bpf_xdp_output_btf_ids[0],
|
||||
.arg2_type = ARG_CONST_MAP_PTR,
|
||||
.arg3_type = ARG_ANYTHING,
|
||||
.arg4_type = ARG_PTR_TO_MEM,
|
||||
.arg5_type = ARG_CONST_SIZE_OR_ZERO,
|
||||
.btf_id = bpf_xdp_output_btf_ids,
|
||||
};
|
||||
|
||||
BPF_CALL_1(bpf_get_socket_cookie, struct sk_buff *, skb)
|
||||
@ -9897,17 +9895,6 @@ BTF_SOCK_TYPE_xxx
|
||||
u32 btf_sock_ids[MAX_BTF_SOCK_TYPE];
|
||||
#endif
|
||||
|
||||
static bool check_arg_btf_id(u32 btf_id, u32 arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* only one argument, no need to check arg */
|
||||
for (i = 0; i < MAX_BTF_SOCK_TYPE; i++)
|
||||
if (btf_sock_ids[i] == btf_id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
BPF_CALL_1(bpf_skc_to_tcp6_sock, struct sock *, sk)
|
||||
{
|
||||
/* tcp6_sock type is not generated in dwarf and hence btf,
|
||||
@ -9926,7 +9913,7 @@ const struct bpf_func_proto bpf_skc_to_tcp6_sock_proto = {
|
||||
.gpl_only = false,
|
||||
.ret_type = RET_PTR_TO_BTF_ID_OR_NULL,
|
||||
.arg1_type = ARG_PTR_TO_BTF_ID,
|
||||
.check_btf_id = check_arg_btf_id,
|
||||
.arg1_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON],
|
||||
.ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_TCP6],
|
||||
};
|
||||
|
||||
@ -9943,7 +9930,7 @@ const struct bpf_func_proto bpf_skc_to_tcp_sock_proto = {
|
||||
.gpl_only = false,
|
||||
.ret_type = RET_PTR_TO_BTF_ID_OR_NULL,
|
||||
.arg1_type = ARG_PTR_TO_BTF_ID,
|
||||
.check_btf_id = check_arg_btf_id,
|
||||
.arg1_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON],
|
||||
.ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_TCP],
|
||||
};
|
||||
|
||||
@ -9967,7 +9954,7 @@ const struct bpf_func_proto bpf_skc_to_tcp_timewait_sock_proto = {
|
||||
.gpl_only = false,
|
||||
.ret_type = RET_PTR_TO_BTF_ID_OR_NULL,
|
||||
.arg1_type = ARG_PTR_TO_BTF_ID,
|
||||
.check_btf_id = check_arg_btf_id,
|
||||
.arg1_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON],
|
||||
.ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_TCP_TW],
|
||||
};
|
||||
|
||||
@ -9991,7 +9978,7 @@ const struct bpf_func_proto bpf_skc_to_tcp_request_sock_proto = {
|
||||
.gpl_only = false,
|
||||
.ret_type = RET_PTR_TO_BTF_ID_OR_NULL,
|
||||
.arg1_type = ARG_PTR_TO_BTF_ID,
|
||||
.check_btf_id = check_arg_btf_id,
|
||||
.arg1_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON],
|
||||
.ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_TCP_REQ],
|
||||
};
|
||||
|
||||
@ -10013,6 +10000,6 @@ const struct bpf_func_proto bpf_skc_to_udp6_sock_proto = {
|
||||
.gpl_only = false,
|
||||
.ret_type = RET_PTR_TO_BTF_ID_OR_NULL,
|
||||
.arg1_type = ARG_PTR_TO_BTF_ID,
|
||||
.check_btf_id = check_arg_btf_id,
|
||||
.arg1_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON],
|
||||
.ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_UDP6],
|
||||
};
|
||||
|
Reference in New Issue
Block a user