diff options
Diffstat (limited to '0017-bpf-Don-t-redirect-packets-with-invalid-pkt_len.patch')
-rw-r--r-- | 0017-bpf-Don-t-redirect-packets-with-invalid-pkt_len.patch | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/0017-bpf-Don-t-redirect-packets-with-invalid-pkt_len.patch b/0017-bpf-Don-t-redirect-packets-with-invalid-pkt_len.patch new file mode 100644 index 000000000000..3eab5b5de836 --- /dev/null +++ b/0017-bpf-Don-t-redirect-packets-with-invalid-pkt_len.patch @@ -0,0 +1,77 @@ +From 72f2dc8993f10262092745a88cb2dd0fef094f23 Mon Sep 17 00:00:00 2001 +From: Zhengchao Shao <shaozhengchao@huawei.com> +Date: Fri, 15 Jul 2022 19:55:59 +0800 +Subject: [PATCH 17/73] bpf: Don't redirect packets with invalid pkt_len + +commit fd1894224407c484f652ad456e1ce423e89bb3eb upstream. + +Syzbot found an issue [1]: fq_codel_drop() try to drop a flow whitout any +skbs, that is, the flow->head is null. +The root cause, as the [2] says, is because that bpf_prog_test_run_skb() +run a bpf prog which redirects empty skbs. +So we should determine whether the length of the packet modified by bpf +prog or others like bpf_prog_test is valid before forwarding it directly. + +LINK: [1] https://syzkaller.appspot.com/bug?id=0b84da80c2917757915afa89f7738a9d16ec96c5 +LINK: [2] https://www.spinics.net/lists/netdev/msg777503.html + +Reported-by: syzbot+7a12909485b94426aceb@syzkaller.appspotmail.com +Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com> +Reviewed-by: Stanislav Fomichev <sdf@google.com> +Link: https://lore.kernel.org/r/20220715115559.139691-1-shaozhengchao@huawei.com +Signed-off-by: Alexei Starovoitov <ast@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/linux/skbuff.h | 8 ++++++++ + net/bpf/test_run.c | 3 +++ + net/core/dev.c | 1 + + 3 files changed, 12 insertions(+) + +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index d3d10556f0fa..2f41364a6791 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2624,6 +2624,14 @@ static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset) + + #endif /* NET_SKBUFF_DATA_USES_OFFSET */ + ++static inline void skb_assert_len(struct sk_buff *skb) ++{ ++#ifdef CONFIG_DEBUG_NET ++ if (WARN_ONCE(!skb->len, "%s\n", __func__)) ++ DO_ONCE_LITE(skb_dump, KERN_ERR, skb, false); ++#endif /* CONFIG_DEBUG_NET */ ++} ++ + /* + * Add data to an sk_buff + */ +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 56f059b3c242..42f8de4ebbd7 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -955,6 +955,9 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb) + { + struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb; + ++ if (!skb->len) ++ return -EINVAL; ++ + if (!__skb) + return 0; + +diff --git a/net/core/dev.c b/net/core/dev.c +index a77a979a4bf7..ecaeb3ef8e5c 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4168,6 +4168,7 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev) + bool again = false; + + skb_reset_mac_header(skb); ++ skb_assert_len(skb); + + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_SCHED_TSTAMP)) + __skb_tstamp_tx(skb, NULL, NULL, skb->sk, SCM_TSTAMP_SCHED); +-- +2.37.3 + |