@@ -190,9 +190,12 @@ enum bpf_arg_type {
ARG_CONST_SIZE, /* number of bytes accessed from memory */
ARG_CONST_SIZE_OR_ZERO, /* number of bytes accessed from memory or 0 */
+ ARG_CONST_SIZE32, /* Likewise, but size fits into 32-bit */
+ ARG_CONST_SIZE32_OR_ZERO, /* Ditto */
ARG_PTR_TO_CTX, /* pointer to context */
ARG_ANYTHING, /* any (initialized) argument is ok */
+ ARG_ANYTHING32, /* Likewise, but it is a 32-bit argument */
ARG_PTR_TO_SPIN_LOCK, /* pointer to bpf_spin_lock */
ARG_PTR_TO_SOCK_COMMON, /* pointer to sock_common */
};
@@ -2065,7 +2065,7 @@ const struct bpf_func_proto bpf_tail_call_proto = {
.ret_type = RET_VOID,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_CONST_MAP_PTR,
- .arg3_type = ARG_ANYTHING,
+ .arg3_type = ARG_ANYTHING32,
};
/* Stub for JITs that only support cBPF. eBPF programs are interpreted.
@@ -218,7 +218,7 @@ const struct bpf_func_proto bpf_get_current_comm_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_UNINIT_MEM,
- .arg2_type = ARG_CONST_SIZE,
+ .arg2_type = ARG_CONST_SIZE32,
};
#if defined(CONFIG_QUEUED_SPINLOCKS) || defined(CONFIG_BPF_ARCH_SPINLOCK)
@@ -2398,7 +2398,9 @@ static bool arg_type_is_mem_ptr(enum bpf_arg_type type)
static bool arg_type_is_mem_size(enum bpf_arg_type type)
{
return type == ARG_CONST_SIZE ||
- type == ARG_CONST_SIZE_OR_ZERO;
+ type == ARG_CONST_SIZE_OR_ZERO ||
+ type == ARG_CONST_SIZE32 ||
+ type == ARG_CONST_SIZE32_OR_ZERO;
}
static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
@@ -2416,10 +2418,12 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
if (err)
return err;
- /* arg_type doesn't differentiate 32 and 64-bit arg, always zext. */
- mark_insn_zext(env, cur_func(env), regno);
+ if (arg_type != ARG_ANYTHING32 &&
+ arg_type != ARG_CONST_SIZE32 &&
+ arg_type != ARG_CONST_SIZE32_OR_ZERO)
+ mark_insn_zext(env, cur_func(env), regno);
- if (arg_type == ARG_ANYTHING) {
+ if (arg_type == ARG_ANYTHING || arg_type == ARG_ANYTHING32) {
if (is_pointer_value(env, regno)) {
verbose(env, "R%d leaks addr into helper function\n",
regno);
@@ -2442,7 +2446,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
type != expected_type)
goto err_type;
} else if (arg_type == ARG_CONST_SIZE ||
- arg_type == ARG_CONST_SIZE_OR_ZERO) {
+ arg_type == ARG_CONST_SIZE_OR_ZERO ||
+ arg_type == ARG_CONST_SIZE32 ||
+ arg_type == ARG_CONST_SIZE32_OR_ZERO) {
expected_type = SCALAR_VALUE;
if (type != expected_type)
goto err_type;
@@ -2536,7 +2542,8 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
meta->map_ptr->value_size, false,
meta);
} else if (arg_type_is_mem_size(arg_type)) {
- bool zero_size_allowed = (arg_type == ARG_CONST_SIZE_OR_ZERO);
+ bool zero_size_allowed = (arg_type == ARG_CONST_SIZE_OR_ZERO ||
+ arg_type == ARG_CONST_SIZE32_OR_ZERO);
/* remember the mem_size which may be used later
* to refine return values.
@@ -1693,9 +1693,9 @@ static const struct bpf_func_proto bpf_skb_store_bytes_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
- .arg2_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING32,
.arg3_type = ARG_PTR_TO_MEM,
- .arg4_type = ARG_CONST_SIZE,
+ .arg4_type = ARG_CONST_SIZE32,
.arg5_type = ARG_ANYTHING,
};
@@ -1724,9 +1724,9 @@ static const struct bpf_func_proto bpf_skb_load_bytes_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
- .arg2_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING32,
.arg3_type = ARG_PTR_TO_UNINIT_MEM,
- .arg4_type = ARG_CONST_SIZE,
+ .arg4_type = ARG_CONST_SIZE32,
};
BPF_CALL_5(bpf_skb_load_bytes_relative, const struct sk_buff *, skb,
@@ -1875,7 +1875,7 @@ static const struct bpf_func_proto bpf_l3_csum_replace_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
- .arg2_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING32,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_ANYTHING,
.arg5_type = ARG_ANYTHING,
@@ -1928,7 +1928,7 @@ static const struct bpf_func_proto bpf_l4_csum_replace_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
- .arg2_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING32,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_ANYTHING,
.arg5_type = ARG_ANYTHING,
@@ -1967,9 +1967,9 @@ static const struct bpf_func_proto bpf_csum_diff_proto = {
.pkt_access = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_MEM_OR_NULL,
- .arg2_type = ARG_CONST_SIZE_OR_ZERO,
+ .arg2_type = ARG_CONST_SIZE32_OR_ZERO,
.arg3_type = ARG_PTR_TO_MEM_OR_NULL,
- .arg4_type = ARG_CONST_SIZE_OR_ZERO,
+ .arg4_type = ARG_CONST_SIZE32_OR_ZERO,
.arg5_type = ARG_ANYTHING,
};
@@ -2150,7 +2150,7 @@ static const struct bpf_func_proto bpf_redirect_proto = {
.func = bpf_redirect,
.gpl_only = false,
.ret_type = RET_INTEGER,
- .arg1_type = ARG_ANYTHING,
+ .arg1_type = ARG_ANYTHING32,
.arg2_type = ARG_ANYTHING,
};
@@ -2928,7 +2928,7 @@ static const struct bpf_func_proto bpf_skb_change_proto_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
- .arg2_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING32,
.arg3_type = ARG_ANYTHING,
};
@@ -2948,7 +2948,7 @@ static const struct bpf_func_proto bpf_skb_change_type_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
- .arg2_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING32,
};
static u32 bpf_skb_net_base_len(const struct sk_buff *skb)
@@ -3236,7 +3236,7 @@ static const struct bpf_func_proto bpf_skb_change_tail_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
- .arg2_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING32,
.arg3_type = ARG_ANYTHING,
};
@@ -3832,7 +3832,7 @@ static const struct bpf_func_proto bpf_skb_get_tunnel_key_proto = {
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_PTR_TO_UNINIT_MEM,
- .arg3_type = ARG_CONST_SIZE,
+ .arg3_type = ARG_CONST_SIZE32,
.arg4_type = ARG_ANYTHING,
};
@@ -3941,7 +3941,7 @@ static const struct bpf_func_proto bpf_skb_set_tunnel_key_proto = {
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_PTR_TO_MEM,
- .arg3_type = ARG_CONST_SIZE,
+ .arg3_type = ARG_CONST_SIZE32,
.arg4_type = ARG_ANYTHING,
};