[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <e5d05e56bf41de82f10d33229b8a8f6b49290e98.1690332693.git.yan@cloudflare.com>
Date: Tue, 25 Jul 2023 18:08:17 -0700
From: Yan Zhai <yan@...udflare.com>
To: bpf@...r.kernel.org
Cc: Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Andrii Nakryiko <andrii@...nel.org>,
Martin KaFai Lau <martin.lau@...ux.dev>, Song Liu <song@...nel.org>,
Yonghong Song <yhs@...com>,
John Fastabend <john.fastabend@...il.com>,
KP Singh <kpsingh@...nel.org>, Stanislav Fomichev <sdf@...gle.com>,
Hao Luo <haoluo@...gle.com>, Jiri Olsa <jolsa@...nel.org>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>,
Mykola Lysenko <mykolal@...com>, Shuah Khan <shuah@...nel.org>,
Yan Zhai <yan@...udflare.com>, linux-kernel@...r.kernel.org,
netdev@...r.kernel.org, linux-kselftest@...r.kernel.org,
kernel-team@...udflare.com, Jordan Griege <jgriege@...udflare.com>,
Markus Elfring <Markus.Elfring@....de>,
Jakub Sitnicki <jakub@...udflare.com>
Subject: [PATCH v4 bpf 1/2] bpf: fix skb_do_redirect return values
skb_do_redirect returns various of values: error code (negative),
0 (success), and some positive status code, e.g. NET_XMIT_CN,
NET_RX_DROP. Commit 3a0af8fd61f9 ("bpf: BPF for lightweight tunnel
infrastructure") didn't check the return code correctly, so positive
values are propagated back along call chain:
ip_finish_output2
-> bpf_xmit
-> run_lwt_bpf
-> skb_do_redirect
Inside ip_finish_output2, redirected skb will continue to neighbor
subsystem as if LWTUNNEL_XMIT_CONTINUE is returned, despite that this
skb could have been freed. The bug can trigger use-after-free warning
and crashes kernel afterwards:
https://gist.github.com/zhaiyan920/8fbac245b261fe316a7ef04c9b1eba48
Convert positive statuses from skb_do_redirect eliminates this issue.
Fixes: 3a0af8fd61f9 ("bpf: BPF for lightweight tunnel infrastructure")
Tested-by: Jakub Sitnicki <jakub@...udflare.com>
Suggested-by: Markus Elfring <Markus.Elfring@....de>
Suggested-by: Stanislav Fomichev <sdf@...gle.com>
Reported-by: Jordan Griege <jgriege@...udflare.com>
Signed-off-by: Yan Zhai <yan@...udflare.com>
---
include/linux/netdevice.h | 2 ++
net/core/filter.c | 9 +++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b828c7a75be2..520d808eec15 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -87,6 +87,8 @@ void netdev_sw_irq_coalesce_default_on(struct net_device *dev);
#define NET_RX_SUCCESS 0 /* keep 'em coming, baby */
#define NET_RX_DROP 1 /* packet dropped */
+#define net_rx_errno(e) ((e) == NET_RX_DROP ? -ENOBUFS : (e))
+
#define MAX_NEST_DEV 8
/*
diff --git a/net/core/filter.c b/net/core/filter.c
index 06ba0e56e369..564104543737 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2095,7 +2095,9 @@ static const struct bpf_func_proto bpf_csum_level_proto = {
static inline int __bpf_rx_skb(struct net_device *dev, struct sk_buff *skb)
{
- return dev_forward_skb_nomtu(dev, skb);
+ int ret = dev_forward_skb_nomtu(dev, skb);
+
+ return net_rx_errno(ret);
}
static inline int __bpf_rx_skb_no_mac(struct net_device *dev,
@@ -2108,7 +2110,7 @@ static inline int __bpf_rx_skb_no_mac(struct net_device *dev,
ret = netif_rx(skb);
}
- return ret;
+ return net_rx_errno(ret);
}
static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb)
@@ -2129,6 +2131,9 @@ static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb)
ret = dev_queue_xmit(skb);
dev_xmit_recursion_dec();
+ if (unlikely(ret > 0))
+ ret = net_xmit_errno(ret);
+
return ret;
}
--
2.30.2
Powered by blists - more mailing lists