Skip to content
This repository was archived by the owner on Sep 24, 2020. It is now read-only.

Commit 0e4a1bc

Browse files
Wei Liugregkh
authored andcommitted
xen-netback: disable rogue vif in kthread context
[ Upstream commit e9d8b2c ] When netback discovers frontend is sending malformed packet it will disables the interface which serves that frontend. However disabling a network interface involving taking a mutex which cannot be done in softirq context, so we need to defer this process to kthread context. This patch does the following: 1. introduce a flag to indicate the interface is disabled. 2. check that flag in TX path, don't do any work if it's true. 3. check that flag in RX path, turn off that interface if it's true. The reason to disable it in RX path is because RX uses kthread. After this change the behavior of netback is still consistent -- it won't do any TX work for a rogue frontend, and the interface will be eventually turned off. Also change a "continue" to "break" after xenvif_fatal_tx_err, as it doesn't make sense to continue processing packets if frontend is rogue. This is a fix for XSA-90. Reported-by: Török Edwin <[email protected]> Signed-off-by: Wei Liu <[email protected]> Cc: Ian Campbell <[email protected]> Reviewed-by: David Vrabel <[email protected]> Acked-by: Ian Campbell <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5c4f2fd commit 0e4a1bc

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

drivers/net/xen-netback/common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ struct xenvif {
113113
domid_t domid;
114114
unsigned int handle;
115115

116+
/* Is this interface disabled? True when backend discovers
117+
* frontend is rogue.
118+
*/
119+
bool disabled;
120+
116121
/* Use NAPI for guest TX */
117122
struct napi_struct napi;
118123
/* When feature-split-event-channels = 0, tx_irq = rx_irq. */

drivers/net/xen-netback/interface.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ static int xenvif_poll(struct napi_struct *napi, int budget)
6767
struct xenvif *vif = container_of(napi, struct xenvif, napi);
6868
int work_done;
6969

70+
/* This vif is rogue, we pretend we've there is nothing to do
71+
* for this vif to deschedule it from NAPI. But this interface
72+
* will be turned off in thread context later.
73+
*/
74+
if (unlikely(vif->disabled)) {
75+
napi_complete(napi);
76+
return 0;
77+
}
78+
7079
work_done = xenvif_tx_action(vif, budget);
7180

7281
if (work_done < budget) {
@@ -323,6 +332,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
323332
vif->ip_csum = 1;
324333
vif->dev = dev;
325334

335+
vif->disabled = false;
336+
326337
vif->credit_bytes = vif->remaining_credit = ~0UL;
327338
vif->credit_usec = 0UL;
328339
init_timer(&vif->credit_timeout);

drivers/net/xen-netback/netback.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,8 @@ static void xenvif_tx_err(struct xenvif *vif,
752752
static void xenvif_fatal_tx_err(struct xenvif *vif)
753753
{
754754
netdev_err(vif->dev, "fatal error; disabling device\n");
755-
xenvif_carrier_off(vif);
755+
vif->disabled = true;
756+
xenvif_kick_thread(vif);
756757
}
757758

758759
static int xenvif_count_requests(struct xenvif *vif,
@@ -1479,7 +1480,7 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif, int budget)
14791480
vif->tx.sring->req_prod, vif->tx.req_cons,
14801481
XEN_NETIF_TX_RING_SIZE);
14811482
xenvif_fatal_tx_err(vif);
1482-
continue;
1483+
break;
14831484
}
14841485

14851486
work_to_do = RING_HAS_UNCONSUMED_REQUESTS(&vif->tx);
@@ -1873,7 +1874,18 @@ int xenvif_kthread(void *data)
18731874
while (!kthread_should_stop()) {
18741875
wait_event_interruptible(vif->wq,
18751876
rx_work_todo(vif) ||
1877+
vif->disabled ||
18761878
kthread_should_stop());
1879+
1880+
/* This frontend is found to be rogue, disable it in
1881+
* kthread context. Currently this is only set when
1882+
* netback finds out frontend sends malformed packet,
1883+
* but we cannot disable the interface in softirq
1884+
* context so we defer it here.
1885+
*/
1886+
if (unlikely(vif->disabled && netif_carrier_ok(vif->dev)))
1887+
xenvif_carrier_off(vif);
1888+
18771889
if (kthread_should_stop())
18781890
break;
18791891

0 commit comments

Comments
 (0)