- Introduce a new macro, since that's what nfs loves, called
nfsm_srvpathsiz. This macro plucks a length out of an rpc request and verifies that its size does not exceed NFS_MAXPATHLEN. If it does it generates an ENAMETOOLONG response. - Use this macro, and the existing nfsm_srvnamsiz macro in two places where we deal with paths passed in by the client. This fixes a linux interoperability bug. Linux was sending oversized path components which would cause us to ignore the request all together. This causes linux to hang indefinitly while it waits for a response. This could still happen in other cases where we error out with EBADRPC. Sponsored by: Isilon Systems, Inc. Reviewed by: alfred, fabbri@isilon.com, neal@isilon.com
This commit is contained in:
parent
bfccaa1df2
commit
24b50116ed
@ -2221,7 +2221,7 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
}
|
||||
fvp = fromnd.ni_vp;
|
||||
nfsm_srvmtofh(tfhp);
|
||||
nfsm_strsiz(len2, NFS_MAXNAMLEN);
|
||||
nfsm_srvnamesiz(len2);
|
||||
cred->cr_uid = saved_uid;
|
||||
tond.ni_cnd.cn_cred = cred;
|
||||
tond.ni_cnd.cn_nameiop = RENAME;
|
||||
@ -2550,7 +2550,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
VATTR_NULL(vap);
|
||||
if (v3)
|
||||
nfsm_srvsattr(vap);
|
||||
nfsm_strsiz(len2, NFS_MAXPATHLEN);
|
||||
nfsm_srvpathsiz(len2);
|
||||
MALLOC(pathcp, caddr_t, len2 + 1, M_TEMP, M_WAITOK);
|
||||
iv.iov_base = pathcp;
|
||||
iv.iov_len = len2;
|
||||
|
@ -1263,7 +1263,7 @@ nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
|
||||
}
|
||||
|
||||
int
|
||||
nfsm_srvnamesiz_xx(int *s, struct mbuf **md, caddr_t *dpos)
|
||||
nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
|
||||
{
|
||||
u_int32_t *tl;
|
||||
|
||||
@ -1271,7 +1271,7 @@ nfsm_srvnamesiz_xx(int *s, struct mbuf **md, caddr_t *dpos)
|
||||
if (tl == NULL)
|
||||
return EBADRPC;
|
||||
*s = fxdr_unsigned(int32_t, *tl);
|
||||
if (*s > NFS_MAXNAMLEN)
|
||||
if (*s > m)
|
||||
return NFSERR_NAMETOL;
|
||||
if (*s <= 0)
|
||||
return EBADRPC;
|
||||
|
@ -77,7 +77,7 @@
|
||||
/* Dissection phase macros */
|
||||
|
||||
int nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
|
||||
int nfsm_srvnamesiz_xx(int *s, struct mbuf **md, caddr_t *dpos);
|
||||
int nfsm_srvnamesiz_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);
|
||||
@ -95,7 +95,17 @@ do { \
|
||||
#define nfsm_srvnamesiz(s) \
|
||||
do { \
|
||||
int t1; \
|
||||
t1 = nfsm_srvnamesiz_xx(&(s), &md, &dpos); \
|
||||
t1 = nfsm_srvnamesiz_xx(&(s), NFS_MAXNAMLEN, &md, &dpos); \
|
||||
if (t1) { \
|
||||
error = t1; \
|
||||
nfsm_reply(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define nfsm_srvpathsiz(s) \
|
||||
do { \
|
||||
int t1; \
|
||||
t1 = nfsm_srvnamesiz_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
|
||||
if (t1) { \
|
||||
error = t1; \
|
||||
nfsm_reply(0); \
|
||||
|
Loading…
x
Reference in New Issue
Block a user