Skip to content

Commit bdf5d13

Browse files
Nick Childkuba-moo
authored andcommitted
ibmvnic: Don't reference skb after sending to VIOS
Previously, after successfully flushing the xmit buffer to VIOS, the tx_bytes stat was incremented by the length of the skb. It is invalid to access the skb memory after sending the buffer to the VIOS because, at any point after sending, the VIOS can trigger an interrupt to free this memory. A race between reading skb->len and freeing the skb is possible (especially during LPM) and will result in use-after-free: ================================================================== BUG: KASAN: slab-use-after-free in ibmvnic_xmit+0x75c/0x1808 [ibmvnic] Read of size 4 at addr c00000024eb48a70 by task hxecom/14495 <...> Call Trace: [c000000118f66cf0] [c0000000018cba6c] dump_stack_lvl+0x84/0xe8 (unreliable) [c000000118f66d20] [c0000000006f0080] print_report+0x1a8/0x7f0 [c000000118f66df0] [c0000000006f08f0] kasan_report+0x128/0x1f8 [c000000118f66f00] [c0000000006f2868] __asan_load4+0xac/0xe0 [c000000118f66f20] [c0080000046eac84] ibmvnic_xmit+0x75c/0x1808 [ibmvnic] [c000000118f67340] [c0000000014be168] dev_hard_start_xmit+0x150/0x358 <...> Freed by task 0: kasan_save_stack+0x34/0x68 kasan_save_track+0x2c/0x50 kasan_save_free_info+0x64/0x108 __kasan_mempool_poison_object+0x148/0x2d4 napi_skb_cache_put+0x5c/0x194 net_tx_action+0x154/0x5b8 handle_softirqs+0x20c/0x60c do_softirq_own_stack+0x6c/0x88 <...> The buggy address belongs to the object at c00000024eb48a00 which belongs to the cache skbuff_head_cache of size 224 ================================================================== Fixes: 032c5e8 ("Driver for IBM System i/p VNIC protocol") Signed-off-by: Nick Child <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 915e34d commit bdf5d13

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/net/ethernet/ibm/ibmvnic.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2408,6 +2408,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
24082408
dma_addr_t data_dma_addr;
24092409
struct netdev_queue *txq;
24102410
unsigned long lpar_rc;
2411+
unsigned int skblen;
24112412
union sub_crq tx_crq;
24122413
unsigned int offset;
24132414
bool use_scrq_send_direct = false;
@@ -2522,6 +2523,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
25222523
tx_buff->skb = skb;
25232524
tx_buff->index = bufidx;
25242525
tx_buff->pool_index = queue_num;
2526+
skblen = skb->len;
25252527

25262528
memset(&tx_crq, 0, sizeof(tx_crq));
25272529
tx_crq.v1.first = IBMVNIC_CRQ_CMD;
@@ -2614,7 +2616,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
26142616
netif_stop_subqueue(netdev, queue_num);
26152617
}
26162618

2617-
tx_bytes += skb->len;
2619+
tx_bytes += skblen;
26182620
txq_trans_cond_update(txq);
26192621
ret = NETDEV_TX_OK;
26202622
goto out;

0 commit comments

Comments
 (0)