mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
unionfs_lookup(): fix wild accesses to vnode private data
There are a few spots in which unionfs_lookup() accesses unionfs vnode private data without holding the corresponding vnode lock or interlock. Reviewed by: kib, olce Differential Revision: https://reviews.freebsd.org/D44601 (cherry picked from commit b18029bc59d2ed6b0eeeb233189cf713b34b467c)
This commit is contained in:
parent
d776dd5fbd
commit
c8d6c9351a
1 changed files with 15 additions and 7 deletions
|
|
@ -81,7 +81,7 @@
|
|||
static int
|
||||
unionfs_lookup(struct vop_cachedlookup_args *ap)
|
||||
{
|
||||
struct unionfs_node *dunp;
|
||||
struct unionfs_node *dunp, *unp;
|
||||
struct vnode *dvp, *udvp, *ldvp, *vp, *uvp, *lvp, *dtmpvp;
|
||||
struct vattr va;
|
||||
struct componentname *cnp;
|
||||
|
|
@ -141,6 +141,9 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
|
|||
if (dtmpvp == udvp && ldvp != NULLVP) {
|
||||
VOP_UNLOCK(udvp);
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
dunp = VTOUNIONFS(dvp);
|
||||
if (error == 0 && dunp == NULL)
|
||||
error = ENOENT;
|
||||
}
|
||||
|
||||
if (error == 0) {
|
||||
|
|
@ -154,14 +157,15 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
|
|||
VOP_UNLOCK(vp);
|
||||
vrele(vp);
|
||||
|
||||
dtmpvp = dunp->un_dvp;
|
||||
vref(dtmpvp);
|
||||
VOP_UNLOCK(dvp);
|
||||
*(ap->a_vpp) = dunp->un_dvp;
|
||||
vref(dunp->un_dvp);
|
||||
*(ap->a_vpp) = dtmpvp;
|
||||
|
||||
if (nameiop == DELETE || nameiop == RENAME)
|
||||
vn_lock(dunp->un_dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
vn_lock(dtmpvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
else if (cnp->cn_lkflags & LK_TYPE_MASK)
|
||||
vn_lock(dunp->un_dvp, cnp->cn_lkflags |
|
||||
vn_lock(dtmpvp, cnp->cn_lkflags |
|
||||
LK_RETRY);
|
||||
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
|
|
@ -274,8 +278,12 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
|
|||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
lockflag = 1;
|
||||
}
|
||||
error = unionfs_mkshadowdir(MOUNTTOUNIONFSMOUNT(dvp->v_mount),
|
||||
udvp, VTOUNIONFS(vp), cnp, td);
|
||||
unp = VTOUNIONFS(vp);
|
||||
if (unp == NULL)
|
||||
error = ENOENT;
|
||||
else
|
||||
error = unionfs_mkshadowdir(MOUNTTOUNIONFSMOUNT(dvp->v_mount),
|
||||
udvp, unp, cnp, td);
|
||||
if (lockflag != 0)
|
||||
VOP_UNLOCK(vp);
|
||||
if (error != 0) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue