|
@@ -1844,14 +1844,15 @@ BPF_CALL_4(bpf_sk_redirect_map, struct sk_buff *, skb,
|
|
|
{
|
|
|
struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
|
|
|
|
|
|
+ /* If user passes invalid input drop the packet. */
|
|
|
if (unlikely(flags))
|
|
|
- return SK_ABORTED;
|
|
|
+ return SK_DROP;
|
|
|
|
|
|
tcb->bpf.key = key;
|
|
|
tcb->bpf.flags = flags;
|
|
|
tcb->bpf.map = map;
|
|
|
|
|
|
- return SK_REDIRECT;
|
|
|
+ return SK_PASS;
|
|
|
}
|
|
|
|
|
|
struct sock *do_sk_redirect_map(struct sk_buff *skb)
|
|
@@ -4243,6 +4244,31 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
|
|
|
return insn - insn_buf;
|
|
|
}
|
|
|
|
|
|
+static u32 sk_skb_convert_ctx_access(enum bpf_access_type type,
|
|
|
+ const struct bpf_insn *si,
|
|
|
+ struct bpf_insn *insn_buf,
|
|
|
+ struct bpf_prog *prog, u32 *target_size)
|
|
|
+{
|
|
|
+ struct bpf_insn *insn = insn_buf;
|
|
|
+ int off;
|
|
|
+
|
|
|
+ switch (si->off) {
|
|
|
+ case offsetof(struct __sk_buff, data_end):
|
|
|
+ off = si->off;
|
|
|
+ off -= offsetof(struct __sk_buff, data_end);
|
|
|
+ off += offsetof(struct sk_buff, cb);
|
|
|
+ off += offsetof(struct tcp_skb_cb, bpf.data_end);
|
|
|
+ *insn++ = BPF_LDX_MEM(BPF_SIZEOF(void *), si->dst_reg,
|
|
|
+ si->src_reg, off);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return bpf_convert_ctx_access(type, si, insn_buf, prog,
|
|
|
+ target_size);
|
|
|
+ }
|
|
|
+
|
|
|
+ return insn - insn_buf;
|
|
|
+}
|
|
|
+
|
|
|
const struct bpf_verifier_ops sk_filter_prog_ops = {
|
|
|
.get_func_proto = sk_filter_func_proto,
|
|
|
.is_valid_access = sk_filter_is_valid_access,
|
|
@@ -4301,7 +4327,7 @@ const struct bpf_verifier_ops sock_ops_prog_ops = {
|
|
|
const struct bpf_verifier_ops sk_skb_prog_ops = {
|
|
|
.get_func_proto = sk_skb_func_proto,
|
|
|
.is_valid_access = sk_skb_is_valid_access,
|
|
|
- .convert_ctx_access = bpf_convert_ctx_access,
|
|
|
+ .convert_ctx_access = sk_skb_convert_ctx_access,
|
|
|
.gen_prologue = sk_skb_prologue,
|
|
|
};
|
|
|
|