hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add bpf_set_ingress_dst kfunc to set the receive dst entry of sock to ingress skb. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- kernel/bpf/verifier.c | 24 ++++++++++++++++++++++++ net/core/filter.c | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 1b7799a7ac71..67ff1bcfb277 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -10811,6 +10811,9 @@ enum special_kfunc_type { KF_bpf_dynptr_slice, KF_bpf_dynptr_slice_rdwr, KF_bpf_dynptr_clone, +#ifdef CONFIG_HISOCK + KF_bpf_set_ingress_dst, +#endif }; BTF_SET_START(special_kfunc_set) @@ -10831,6 +10834,9 @@ BTF_ID(func, bpf_dynptr_from_xdp) BTF_ID(func, bpf_dynptr_slice) BTF_ID(func, bpf_dynptr_slice_rdwr) BTF_ID(func, bpf_dynptr_clone) +#ifdef CONFIG_HISOCK +BTF_ID(func, bpf_set_ingress_dst) +#endif BTF_SET_END(special_kfunc_set) BTF_ID_LIST(special_kfunc_list) @@ -10853,6 +10859,9 @@ BTF_ID(func, bpf_dynptr_from_xdp) BTF_ID(func, bpf_dynptr_slice) BTF_ID(func, bpf_dynptr_slice_rdwr) BTF_ID(func, bpf_dynptr_clone) +#ifdef CONFIG_HISOCK +BTF_ID(func, bpf_set_ingress_dst) +#endif static bool is_kfunc_ret_null(struct bpf_kfunc_call_arg_meta *meta) { @@ -11829,6 +11838,16 @@ static int fetch_kfunc_meta(struct bpf_verifier_env *env, return 0; } +static int check_atype_kfunc_compatibility(struct bpf_verifier_env *env, u32 func_id) +{ +#ifdef CONFIG_HISOCK + if (func_id == special_kfunc_list[KF_bpf_set_ingress_dst] && + env->prog->expected_attach_type != BPF_HISOCK_INGRESS) + return -EACCES; +#endif + return 0; +} + static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, int *insn_idx_p) { @@ -11858,6 +11877,11 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, insn_aux->is_iter_next = is_iter_next_kfunc(&meta); + if (check_atype_kfunc_compatibility(env, meta.func_id)) { + verbose(env, "calling kernel function %s is not allowed\n", func_name); + return -EACCES; + } + if (is_kfunc_destructive(&meta) && !capable(CAP_SYS_BOOT)) { verbose(env, "destructive kfunc calls require CAP_SYS_BOOT capability\n"); return -EACCES; diff --git a/net/core/filter.c b/net/core/filter.c index acf1d574c3cb..ff0ec4621cc0 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -12186,6 +12186,29 @@ __bpf_kfunc int bpf_xdp_set_ingress_dst(struct xdp_md *xdp_ctx, void *dst__ign) return 0; } +__bpf_kfunc int bpf_set_ingress_dst(struct __sk_buff *skb_ctx, unsigned long _sk) +{ + struct sk_buff *skb = (struct sk_buff *)skb_ctx; + struct sock *sk = (struct sock *)_sk; + struct dst_entry *dst; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + if (!sk || !virt_addr_valid(sk)) + return -EFAULT; + + if (!sk_fullsock(sk)) + return -EINVAL; + + dst = rcu_dereference(sk->sk_rx_dst); + if (dst) + dst = dst_check(dst, 0); + if (dst && sk->sk_rx_dst_ifindex == skb->skb_iif) + skb_dst_set_noref(skb, dst); + + return 0; +} + __bpf_kfunc int bpf_xdp_change_dev(struct xdp_md *xdp_ctx, u32 ifindex) { struct xdp_buff *xdp = (struct xdp_buff *)xdp_ctx; @@ -12258,6 +12281,7 @@ BTF_ID_FLAGS(func, bpf_skops_get_ingress_dst, KF_RET_NULL) BTF_SET8_END(bpf_kfunc_check_set_sock_ops) BTF_SET8_START(bpf_kfunc_check_set_hisock) +BTF_ID_FLAGS(func, bpf_set_ingress_dst) BTF_ID_FLAGS(func, bpf_skb_change_dev) BTF_SET8_END(bpf_kfunc_check_set_hisock) #endif -- 2.34.1