diff options
| author | Xin LI <delphij@FreeBSD.org> | 2014-04-08 18:27:46 +0000 |
|---|---|---|
| committer | Xin LI <delphij@FreeBSD.org> | 2014-04-08 18:27:46 +0000 |
| commit | cfc2b71ace0be209be7c22249f9f6af3fecf53d1 (patch) | |
| tree | 6def43c6815638db631e7fef76bd9ebaaeb421d5 /sys | |
| parent | e3ff8788aa4381f45f5c39efd99c9cbf1b174b5a (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/conf/newvers.sh | 2 | ||||
| -rw-r--r-- | sys/fs/nfsserver/nfs_nfsdserv.c | 25 |
2 files changed, 21 insertions, 6 deletions
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 53835c6b72be..b2067b2a3a77 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="10.0" -BRANCH="RELEASE" +BRANCH="RELEASE-p1" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 307b1f6cc5a3..bf2d7ed77e7b 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -1457,10 +1457,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram, nfsvno_relpathbuf(&fromnd); goto out; } + /* + * Unlock dp in this code section, so it is unlocked before + * tdp gets locked. This avoids a potential LOR if tdp is the + * parent directory of dp. + */ if (nd->nd_flag & ND_NFSV4) { tdp = todp; tnes = *toexp; - tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0); + if (dp != tdp) { + NFSVOPUNLOCK(dp, 0); + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 0); /* Might lock tdp. */ + } else { + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 1); + NFSVOPUNLOCK(dp, 0); + } } else { tfh.nfsrvfh_len = 0; error = nfsrv_mtofh(nd, &tfh); @@ -1481,10 +1494,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram, tnes = *exp; tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); + NFSVOPUNLOCK(dp, 0); } else { + NFSVOPUNLOCK(dp, 0); nd->nd_cred->cr_uid = nd->nd_saveduid; nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, - 0, p); + 0, p); /* Locks tdp. */ if (tdp) { tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); @@ -1499,7 +1514,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram, if (error) { if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1514,7 +1529,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram, } if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1523,7 +1538,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram, /* * Done parsing, now down to business. */ - nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp); + nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 0, exp, p, &fdirp); if (nd->nd_repstat) { if (nd->nd_flag & ND_NFSV3) { nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, |
