diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2012-01-04 18:11:52 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2012-01-04 18:11:52 +0000 |
commit | 0fcc00c17440350cee1f4d494b8b312125e0f2e7 (patch) | |
tree | b6c5bfbe58e079a8e5247d079ee58a2cd42f221d /sys | |
parent | ed330b1b2bc29ed5af74d2fff88eddcc0c2e7967 (diff) |
Fix use after free in cache_lookup() - found by Pedro
fix is to manipulate the name cache structures before
potentially sleeping on a vn_lock(). This avoids the race of
the ncp entry being recycled while we are asleep.
run in snaps and on ftp.openbsd.org for months
ok thib@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_cache.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index bc53930b5df..f4ded2324e1 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_cache.c,v 1.33 2010/05/19 08:31:23 thib Exp $ */ +/* $OpenBSD: vfs_cache.c,v 1.34 2012/01/04 18:11:51 beck Exp $ */ /* $NetBSD: vfs_cache.c,v 1.13 1996/02/04 02:18:09 christos Exp $ */ /* @@ -188,6 +188,14 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, goto remove; } + /* + * Move this slot to end of the regular LRU chain. + */ + if (TAILQ_NEXT(ncp, nc_lru) != NULL) { + TAILQ_REMOVE(&nclruhead, ncp, nc_lru); + TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); + } + vp = ncp->nc_vp; vpid = vp->v_id; if (vp == dvp) { /* lookup on "." */ @@ -245,13 +253,6 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, } nchstats.ncs_goodhits++; - /* - * Move this slot to end of the regular LRU chain. - */ - if (TAILQ_NEXT(ncp, nc_lru) != NULL) { - TAILQ_REMOVE(&nclruhead, ncp, nc_lru); - TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); - } *vpp = vp; return (0); |