mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 04:21:09 -04:00
net: airoha: Do not read uninitialized fragment address in airoha_dev_xmit()
The transmit loop in airoha_dev_xmit() reads fragment address and length
during its final iteration, when the loop index equals
skb_shinfo(skb)->nr_frags, at which point the fragment data is
uninitialized. While these values are never consumed, the read itself is
unsafe and may trigger a page fault. Fix this by avoiding the fragment
read on the last iteration.
Additionally, move the skb pointer from the first to the last used packet
descriptor, so that airoha_qdma_tx_napi_poll() defers freeing the skb
until the final descriptor is processed.
Fixes: 23020f0493 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260424-airoha-xmit-fix-read-frag-v1-1-fdc0a83c79e8@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
e070aac63b
commit
bde34e84ed
@@ -2007,8 +2007,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
struct netdev_queue *txq;
|
||||
struct airoha_queue *q;
|
||||
LIST_HEAD(tx_list);
|
||||
int i = 0, qid;
|
||||
void *data;
|
||||
int i, qid;
|
||||
u16 index;
|
||||
u8 fport;
|
||||
|
||||
@@ -2067,7 +2067,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
list);
|
||||
index = e - q->entry;
|
||||
|
||||
for (i = 0; i < nr_frags; i++) {
|
||||
while (true) {
|
||||
struct airoha_qdma_desc *desc = &q->desc[index];
|
||||
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
|
||||
dma_addr_t addr;
|
||||
@@ -2079,7 +2079,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
goto error_unmap;
|
||||
|
||||
list_move_tail(&e->list, &tx_list);
|
||||
e->skb = i ? NULL : skb;
|
||||
e->skb = i == nr_frags - 1 ? skb : NULL;
|
||||
e->dma_addr = addr;
|
||||
e->dma_len = len;
|
||||
|
||||
@@ -2098,6 +2098,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
|
||||
WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
|
||||
|
||||
if (++i == nr_frags)
|
||||
break;
|
||||
|
||||
data = skb_frag_address(frag);
|
||||
len = skb_frag_size(frag);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user