Message ID | 20231211123144.3759488-1-aleksander.lobakin@intel.com (mailing list archive) |
---|---|
State | Awaiting Upstream |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [iwl-net,v2] idpf: fix corrupted frames and skb leaks in singleq mode | expand |
> -----Original Message----- > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of > Alexander Lobakin > Sent: Monday, December 11, 2023 4:32 AM > To: intel-wired-lan@lists.osuosl.org > Cc: Fijalkowski, Maciej <maciej.fijalkowski@intel.com>; Kitszel, Przemyslaw > <przemyslaw.kitszel@intel.com>; linux-kernel@vger.kernel.org; Lobakin, > Aleksander <aleksander.lobakin@intel.com>; Eric Dumazet > <edumazet@google.com>; Kubiak, Michal <michal.kubiak@intel.com>; > Simon Horman <horms@kernel.org>; netdev@vger.kernel.org; Jakub > Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; David S. > Miller <davem@davemloft.net> > Subject: [Intel-wired-lan] [PATCH iwl-net v2] idpf: fix corrupted frames and > skb leaks in singleq mode > > idpf_ring::skb serves only for keeping an incomplete frame between > several NAPI Rx polling cycles, as one cycle may end up before > processing the end of packet descriptor. The pointer is taken from > the ring onto the stack before entering the loop and gets written > there after the loop exits. When inside the loop, only the onstack > pointer is used. > For some reason, the logics is broken in the singleq mode, where the > pointer is taken from the ring each iteration. This means that if a > frame got fragmented into several descriptors, each fragment will have > its own skb, but only the last one will be passed up the stack > (containing garbage), leaving the rest leaked. > Then, on ifdown, rxq::skb is being freed only in the splitq mode, while > it can point to a valid skb in singleq as well. This can lead to a yet > another skb leak. > Just don't touch the ring skb field inside the polling loop, letting > the onstack skb pointer work as expected: build a new skb if it's the > first frame descriptor and attach a frag otherwise. On ifdown, free > rxq::skb unconditionally if the pointer is non-NULL. > > Fixes: a5ab9ee0df0b ("idpf: add singleq start_xmit and napi poll") > Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> > Reviewed-by: Michal Kubiak <michal.kubiak@intel.com> > Reviewed-by: Simon Horman <horms@kernel.org> > Reviewed-by: Eric Dumazet <edumazet@google.com> > Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com> > --- > Tony, please add it to dev-queue instead of the first revision. > > From v1[0]: > * fix the related skb leak on ifdown; > * fix subject prefix; > * pick Reviewed-bys. > > [0] https://lore.kernel.org/all/20231201143821.1091005-1- > aleksander.lobakin@intel.com > --- > drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c | 1 - > drivers/net/ethernet/intel/idpf/idpf_txrx.c | 2 +- > 2 files changed, 1 insertion(+), 2 deletions(-) Tested-by: Scott Register <scott.register@intel.com>
diff --git a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c index 81288a17da2a..20c4b3a64710 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c +++ b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c @@ -1044,7 +1044,6 @@ static int idpf_rx_singleq_clean(struct idpf_queue *rx_q, int budget) } idpf_rx_sync_for_cpu(rx_buf, fields.size); - skb = rx_q->skb; if (skb) idpf_rx_add_frag(rx_buf, skb, fields.size); else diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c index 1f728a9004d9..9e942e5baf39 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c @@ -396,7 +396,7 @@ static void idpf_rx_desc_rel(struct idpf_queue *rxq, bool bufq, s32 q_model) if (!rxq) return; - if (!bufq && idpf_is_queue_model_split(q_model) && rxq->skb) { + if (rxq->skb) { dev_kfree_skb_any(rxq->skb); rxq->skb = NULL; }