NDFREE(): Fix unlocking for LOCKPARENT|LOCKLEAF and ndp->ni_dvp == ndp->ni_vp.
NDFREE() calculates unlock_dvp after ndp->ni_vp is unlocked and zeroed out. This makes the comparision of ni_dvp with ni_vp always fail. Move the calculation of unlock_dvp right after unlock_vp, so that the code sees correct ni_vp value. Reproduced by chdir("/usr"); open("/..", O_BENEATH | O_RDONLY); Reported by: syzkaller Reviewed by: markj, mckusick Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D20304
This commit is contained in:
parent
b5aa188649
commit
c84facbfbd
@ -1332,6 +1332,10 @@ NDFREE(struct nameidata *ndp, const u_int flags)
|
||||
if (!(flags & NDF_NO_VP_UNLOCK) &&
|
||||
(ndp->ni_cnd.cn_flags & LOCKLEAF) && ndp->ni_vp)
|
||||
unlock_vp = 1;
|
||||
if (!(flags & NDF_NO_DVP_UNLOCK) &&
|
||||
(ndp->ni_cnd.cn_flags & LOCKPARENT) &&
|
||||
ndp->ni_dvp != ndp->ni_vp)
|
||||
unlock_dvp = 1;
|
||||
if (!(flags & NDF_NO_VP_RELE) && ndp->ni_vp) {
|
||||
if (unlock_vp) {
|
||||
vput(ndp->ni_vp);
|
||||
@ -1342,10 +1346,6 @@ NDFREE(struct nameidata *ndp, const u_int flags)
|
||||
}
|
||||
if (unlock_vp)
|
||||
VOP_UNLOCK(ndp->ni_vp, 0);
|
||||
if (!(flags & NDF_NO_DVP_UNLOCK) &&
|
||||
(ndp->ni_cnd.cn_flags & LOCKPARENT) &&
|
||||
ndp->ni_dvp != ndp->ni_vp)
|
||||
unlock_dvp = 1;
|
||||
if (!(flags & NDF_NO_DVP_RELE) &&
|
||||
(ndp->ni_cnd.cn_flags & (LOCKPARENT|WANTPARENT))) {
|
||||
if (unlock_dvp) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user