Fix NFS server deadlock vulnerability. [SA-14:05] Fix OpenSSL multiple vulnerabilities. [SA-14:06]
70 lines
2.2 KiB
Diff
70 lines
2.2 KiB
Diff
Index: sys/fs/nfsserver/nfs_nfsdserv.c
|
|
===================================================================
|
|
--- sys/fs/nfsserver/nfs_nfsdserv.c (revision 264251)
|
|
+++ sys/fs/nfsserver/nfs_nfsdserv.c (working copy)
|
|
@@ -1457,10 +1457,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr
|
|
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 isdgr
|
|
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 isdgr
|
|
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 isdgr
|
|
}
|
|
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 isdgr
|
|
/*
|
|
* 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,
|