Fix race between neigh_parms_release and neightbl_fill_parms
Subsystems (2)
PATCH 1/1 Fix race between neigh_parms_release and neightbl_fill_parms
The neightbl_fill_parms() is called under the write-locked tbl->lock and accesses the parms->dev. The negh_parm_release() calls the dev_put(parms->dev) without this lock. This creates a tiny race window on which the parms contains potentially stale dev pointer.
To fix this race it's enough to move the dev_put() upper under the tbl->lock, but note, that the parms are held by neighbors and thus can live after the neigh_parms_release() is called, so we still can have a parm with bad dev pointer.
I didn't find where the neigh->parms->dev is accessed, but still think that putting the dev is to be done in a place, where the parms are really freed. Am I right with that?
---
net/core/neighbour.c +2 -2
@@ -1316,8 +1316,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) *p = parms->next; parms->dead =1 ;write_unlock_bh (&tbl->lock); -if (parms->dev) -dev_put (parms->dev);call_rcu (&parms->rcu_head, neigh_rcu_free_parms);return ; }
@@ -1328,6 +1326,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)void neigh_parms_destroy (struct neigh_parms *parms) { +if (parms->dev) +dev_put (parms->dev);kfree (parms); }
David Miller
maintainerFrom: Pavel Emelyanov <[email protected]>
Date: Thu, 10 Jan 2008 13:56:53 +0300
Quoted 11 lines
The
neightbl_fill_parms()is called under the write-lockedtbl->lockand accesses theparms->dev. Thenegh_parm_release()calls thedev_put(parms->dev)without this lock. This creates a tiny race window on which the parms contains potentially stale dev pointer.To fix this race it's enough to move the
dev_put()upper under thetbl->lock, but note, that the parms are held by neighbors and thus can live after theneigh_parms_release()is called, so we still can have a parm with bad dev pointer.
Quoted 5 lines
I didn't find where the
neigh->parms->devis accessed, but still think that putting the dev is to be done in a place, where the parms are really freed. Am I right with that?Signed-off-by Pavel Emelyanov <[email protected]>
It is accessed in lookup_neigh_parms(), neightbl_fill_parms(), and neightbl_fill_info() (hmmm, that BUG_ON(tbl->parms.dev) is cute).
You fix looks correct, patch applied, thanks!
This patch causes messages like 'unregister_netdevice: waiting for ppp0 to become free. Usage count = 1' when I try 'ifdown ppp0'. This happens in all kernel versions containing this commit and doesn't happen in 2.6.24-rc8 with this commit reverted.
Signature · 1 line
WBR, wRAR (ALT Linux Team)