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,
 |