From: Jan Kiszka <[email protected]>

An rtsbk that successfully went through rtdev_map_rtskb is either on
rtskb_mapped_list or rtskb_mapwait_list. On rtdev_unmap_rtskb, we
therefore have to remove the rtskb unconditionally from a list,
otherwise we corrupt its state.

This bug was easily triggerable via running smokey tests against the
loopback device.

Signed-off-by: Jan Kiszka <[email protected]>
---
 kernel/drivers/net/stack/rtdev.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/kernel/drivers/net/stack/rtdev.c b/kernel/drivers/net/stack/rtdev.c
index b2d0687daf..93a8e212bf 100644
--- a/kernel/drivers/net/stack/rtdev.c
+++ b/kernel/drivers/net/stack/rtdev.c
@@ -510,17 +510,16 @@ void rtdev_unmap_rtskb(struct rtskb *skb)
     struct rtnet_device *rtdev;
     int i;

-    if (skb->buf_dma_addr == RTSKB_UNMAPPED)
-       return;
-
     mutex_lock(&rtnet_devices_nrt_lock);

     list_del(&skb->entry);

-    for (i = 0; i < MAX_RT_DEVICES; i++) {
-       rtdev = rtnet_devices[i];
-       if (rtdev && rtdev->unmap_rtskb) {
-           rtdev->unmap_rtskb(rtdev, skb);
+    if (skb->buf_dma_addr != RTSKB_UNMAPPED) {
+       for (i = 0; i < MAX_RT_DEVICES; i++) {
+           rtdev = rtnet_devices[i];
+           if (rtdev && rtdev->unmap_rtskb) {
+               rtdev->unmap_rtskb(rtdev, skb);
+           }
        }
     }

--
2.16.4

Reply via email to