]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/core/neighbour.c
neigh: fix rcu splat in neigh_update()
[mirror_ubuntu-bionic-kernel.git] / net / core / neighbour.c
index 4002261f20d13db6e80ed331272e5bbf0f2eb8d5..909ecb3c2a3344077332bfc9fb66fd7f0bfa8031 100644 (file)
@@ -1168,10 +1168,14 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                        struct dst_entry *dst = skb_dst(skb);
                        struct neighbour *n2, *n1 = neigh;
                        write_unlock_bh(&neigh->lock);
+
+                       rcu_read_lock();
                        /* On shaper/eql skb->dst->neighbour != neigh :( */
                        if (dst && (n2 = dst_get_neighbour(dst)) != NULL)
                                n1 = n2;
                        n1->output(n1, skb);
+                       rcu_read_unlock();
+
                        write_lock_bh(&neigh->lock);
                }
                skb_queue_purge(&neigh->arp_queue);
@@ -1331,11 +1335,15 @@ static void neigh_proxy_process(unsigned long arg)
 
                if (tdif <= 0) {
                        struct net_device *dev = skb->dev;
+
                        __skb_unlink(skb, &tbl->proxy_queue);
-                       if (tbl->proxy_redo && netif_running(dev))
+                       if (tbl->proxy_redo && netif_running(dev)) {
+                               rcu_read_lock();
                                tbl->proxy_redo(skb);
-                       else
+                               rcu_read_unlock();
+                       } else {
                                kfree_skb(skb);
+                       }
 
                        dev_put(dev);
                } else if (!sched_next || tdif < sched_next)