summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2007-02-14 22:30:33 +0000
committerColin Percival <cperciva@FreeBSD.org>2007-02-14 22:30:33 +0000
commit9c37cbe4f808be95501415234d39111370cb664f (patch)
treed9c3f5c67e9ca1232cff7488e251c44517d2106c
parent05362dd7032e8f88a504d5fcb3ff8e4919375b6b (diff)
downloadsrc-test2-9c37cbe4f808be95501415234d39111370cb664f.tar.gz
src-test2-9c37cbe4f808be95501415234d39111370cb664f.zip
Notes
-rw-r--r--UPDATING4
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/nfsserver/nfs_serv.c30
-rw-r--r--sys/nfsserver/nfs_srvsubs.c22
-rw-r--r--sys/nfsserver/nfsm_subs.h3
5 files changed, 53 insertions, 8 deletions
diff --git a/UPDATING b/UPDATING
index 2a5933a89c61..ca09ccccefa3 100644
--- a/UPDATING
+++ b/UPDATING
@@ -8,6 +8,10 @@ Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before running
portupgrade.
+20070214: p14 FreeBSD-EN-07:01.nfs
+ Correct problems with locking, namei leakage, and symlink
+ creation in the NFS subsystem.
+
20070209: p13 FreeBSD-SA-07:02.bind
Correct two remote denials of service in BIND involving DNSSEC and
recursive DNS queries respectively.
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 9d3c0bdcc95c..baf2f54b4f42 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="6.1"
-BRANCH="RELEASE-p13"
+BRANCH="RELEASE-p14"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index 2e21a43f107a..38e74663b145 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -569,6 +569,10 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
error = lookup(&ind);
ind.ni_dvp = NULL;
+ if (ind.ni_cnd.cn_flags & GIANTHELD) {
+ mtx_unlock(&Giant);
+ ind.ni_cnd.cn_flags &= ~GIANTHELD;
+ }
if (error == 0) {
/*
@@ -1915,6 +1919,10 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
error = lookup(&nd);
nd.ni_dvp = NULL;
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
+ mtx_unlock(&Giant);
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
+ }
if (error)
goto ereply;
@@ -2141,6 +2149,10 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
error = lookup(&nd);
nd.ni_dvp = NULL;
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
+ mtx_unlock(&Giant);
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
+ }
if (error)
goto out;
@@ -2514,8 +2526,8 @@ out:
tond.ni_dvp = NULL;
tond.ni_vp = NULL;
if (error) {
- fromnd.ni_cnd.cn_flags &= ~HASBUF;
- tond.ni_cnd.cn_flags &= ~HASBUF;
+ NDFREE(&fromnd, NDF_ONLY_PNBUF);
+ NDFREE(&tond, NDF_ONLY_PNBUF);
}
} else {
if (error == -1)
@@ -2809,6 +2821,12 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART;
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
+ if (error == 0) {
+ VATTR_NULL(vap);
+ if (v3)
+ nfsm_srvsattr(vap);
+ nfsm_srvpathsiz(len2);
+ }
NFSD_UNLOCK();
mtx_lock(&Giant); /* VFS */
if (dirp && !v3) {
@@ -2818,10 +2836,6 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
if (error)
goto out;
- VATTR_NULL(vap);
- if (v3)
- nfsm_srvsattr(vap);
- nfsm_srvpathsiz(len2);
MALLOC(pathcp, caddr_t, len2 + 1, M_TEMP, M_WAITOK);
iv.iov_base = pathcp;
iv.iov_len = len2;
@@ -2878,6 +2892,10 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
error = lookup(&nd);
nd.ni_dvp = NULL;
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
+ mtx_unlock(&Giant);
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
+ }
if (error == 0) {
bzero((caddr_t)fhp, sizeof(nfh));
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index 71afd1214a4c..c6ad450fe5db 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -875,6 +875,10 @@ nfs_namei(struct nameidata *ndp, fhandle_t *fhp, int len,
}
if (!lockleaf)
cnp->cn_flags &= ~LOCKLEAF;
+ if (cnp->cn_flags & GIANTHELD) {
+ mtx_unlock(&Giant);
+ cnp->cn_flags &= ~GIANTHELD;
+ }
/*
* nfs_namei() guarentees that fields will not contain garbage
@@ -1331,6 +1335,24 @@ nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
return 0;
}
+int
+nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
+{
+ u_int32_t *tl;
+
+ NFSD_LOCK_DONTCARE();
+
+ tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
+ if (tl == NULL)
+ return EBADRPC;
+ *s = fxdr_unsigned(int32_t, *tl);
+ if (*s > m)
+ return NFSERR_NAMETOL;
+ if (*s < 0)
+ return EBADRPC;
+ return 0;
+}
+
void
nfsm_clget_xx(u_int32_t **tl, struct mbuf *mb, struct mbuf **mp,
char **bp, char **be, caddr_t bpos, int droplock)
diff --git a/sys/nfsserver/nfsm_subs.h b/sys/nfsserver/nfsm_subs.h
index 82e7e25bb284..b605c5df7b20 100644
--- a/sys/nfsserver/nfsm_subs.h
+++ b/sys/nfsserver/nfsm_subs.h
@@ -74,6 +74,7 @@
int nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
int nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
+int nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
int nfsm_srvmtofh_xx(fhandle_t *f, struct nfsrv_descript *nfsd,
struct mbuf **md, caddr_t *dpos);
int nfsm_srvsattr_xx(struct vattr *a, struct mbuf **md, caddr_t *dpos);
@@ -101,7 +102,7 @@ do { \
#define nfsm_srvpathsiz(s) \
do { \
int t1; \
- t1 = nfsm_srvnamesiz_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
+ t1 = nfsm_srvnamesiz0_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
if (t1) { \
error = t1; \
nfsm_reply(0); \