Skip to content

Commit f4e6064

Browse files
lategoodbyekuba-moo
authored andcommitted
qca_debug: Prevent crash on TX ring changes
The qca_spi driver stop and restart the SPI kernel thread (via ndo_stop & ndo_open) in case of TX ring changes. This is a big issue because it allows userspace to prevent restart of the SPI kernel thread (via signals). A subsequent change of TX ring wrongly assume a valid spi_thread pointer which result in a crash. So prevent this by stopping the network traffic handling and temporary park the SPI thread. Fixes: 291ab06 ("net: qualcomm: new Ethernet over SPI driver for QCA7000") Signed-off-by: Stefan Wahren <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a1664b9 commit f4e6064

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

drivers/net/ethernet/qualcomm/qca_debug.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,22 +263,21 @@ qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring,
263263
struct kernel_ethtool_ringparam *kernel_ring,
264264
struct netlink_ext_ack *extack)
265265
{
266-
const struct net_device_ops *ops = dev->netdev_ops;
267266
struct qcaspi *qca = netdev_priv(dev);
268267

269268
if ((ring->rx_pending) ||
270269
(ring->rx_mini_pending) ||
271270
(ring->rx_jumbo_pending))
272271
return -EINVAL;
273272

274-
if (netif_running(dev))
275-
ops->ndo_stop(dev);
273+
if (qca->spi_thread)
274+
kthread_park(qca->spi_thread);
276275

277276
qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN);
278277
qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
279278

280-
if (netif_running(dev))
281-
ops->ndo_open(dev);
279+
if (qca->spi_thread)
280+
kthread_unpark(qca->spi_thread);
282281

283282
return 0;
284283
}

drivers/net/ethernet/qualcomm/qca_spi.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,18 @@ qcaspi_spi_thread(void *data)
580580
netdev_info(qca->net_dev, "SPI thread created\n");
581581
while (!kthread_should_stop()) {
582582
set_current_state(TASK_INTERRUPTIBLE);
583+
if (kthread_should_park()) {
584+
netif_tx_disable(qca->net_dev);
585+
netif_carrier_off(qca->net_dev);
586+
qcaspi_flush_tx_ring(qca);
587+
kthread_parkme();
588+
if (qca->sync == QCASPI_SYNC_READY) {
589+
netif_carrier_on(qca->net_dev);
590+
netif_wake_queue(qca->net_dev);
591+
}
592+
continue;
593+
}
594+
583595
if ((qca->intr_req == qca->intr_svc) &&
584596
!qca->txr.skb[qca->txr.head])
585597
schedule();

0 commit comments

Comments
 (0)