From 2d45e41adbdf1d5e7760fc2791b929707767978a Mon Sep 17 00:00:00 2001 From: yamt Date: Fri, 28 Mar 2003 13:05:47 +0000 Subject: [PATCH] reply ENAMETOOLONG properly instead of discarding request as BADRPC. my own PR20791. --- sys/nfs/nfs_serv.c | 47 ++++++++++++++++++++++++++++++++++----------- sys/nfs/nfs_subs.c | 6 +++--- sys/nfs/nfsm_subs.h | 16 +++++++-------- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c index 973139276893..af207a57294c 100644 --- a/sys/nfs/nfs_serv.c +++ b/sys/nfs/nfs_serv.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_serv.c,v 1.67 2003/02/26 06:31:18 matt Exp $ */ +/* $NetBSD: nfs_serv.c,v 1.68 2003/03/28 13:05:47 yamt Exp $ */ /* * Copyright (c) 1989, 1993 @@ -59,7 +59,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.67 2003/02/26 06:31:18 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.68 2003/03/28 13:05:47 yamt Exp $"); #include #include @@ -364,7 +364,8 @@ nfsrv_lookup(nfsd, slp, procp, mrq) u_int32_t *tl; int32_t t1; caddr_t bpos; - int error = 0, cache, len, dirattr_ret = 1; + int error = 0, cache, dirattr_ret = 1; + uint32_t len; int v3 = (nfsd->nd_flag & ND_NFSV3), pubflag; char *cp2; struct mbuf *mb, *mreq; @@ -587,7 +588,8 @@ nfsrv_read(nfsd, slp, procp, mrq) int i; caddr_t bpos; int error = 0, rdonly, cache, cnt, len, left, siz, tlen, getret; - int v3 = (nfsd->nd_flag & ND_NFSV3), reqlen; + int v3 = (nfsd->nd_flag & ND_NFSV3); + uint32_t reqlen; char *cp2; struct mbuf *mb, *mreq; struct mbuf *m2; @@ -1732,7 +1734,8 @@ nfsrv_rename(nfsd, slp, procp, mrq) u_int32_t *tl; int32_t t1; caddr_t bpos; - int error = 0, cache, len, len2, fdirfor_ret = 1, fdiraft_ret = 1; + int error = 0, cache, fdirfor_ret = 1, fdiraft_ret = 1; + uint32_t len, len2; int tdirfor_ret = 1, tdiraft_ret = 1; int v3 = (nfsd->nd_flag & ND_NFSV3); char *cp2; @@ -1784,7 +1787,15 @@ nfsrv_rename(nfsd, slp, procp, mrq) } fvp = fromnd.ni_vp; nfsm_srvmtofh(tfhp); - nfsm_strsiz(len2, NFS_MAXNAMLEN); + if (v3) { + nfsm_dissect(tl, uint32_t *, NFSX_UNSIGNED); + len2 = fxdr_unsigned(uint32_t, *tl); + /* len2 will be checked by nfs_namei */ + } + else { + /* NFSv2 */ + nfsm_strsiz(len2, NFS_MAXNAMLEN); + } cred->cr_uid = saved_uid; tond.ni_cnd.cn_cred = cred; tond.ni_cnd.cn_nameiop = RENAME; @@ -2042,7 +2053,8 @@ nfsrv_symlink(nfsd, slp, procp, mrq) char *bpos, *pathcp = NULL, *cp2; struct uio io; struct iovec iv; - int error = 0, cache, len, len2, dirfor_ret = 1, diraft_ret = 1; + int error = 0, cache, dirfor_ret = 1, diraft_ret = 1; + uint32_t len, len2; int v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mreq; struct vnode *dirp = (struct vnode *)0; @@ -2071,9 +2083,20 @@ nfsrv_symlink(nfsd, slp, procp, mrq) if (error) goto out; VATTR_NULL(&va); - if (v3) + if (v3) { nfsm_srvsattr(&va); - nfsm_strsiz(len2, NFS_MAXPATHLEN); + nfsm_dissect(tl, uint32_t *, NFSX_UNSIGNED); + len2 = fxdr_unsigned(uint32_t, *tl); + if (len2 > PATH_MAX) { + /* XXX should check _PC_NO_TRUNC */ + error = ENAMETOOLONG; + goto abortop; + } + } + else { + /* NFSv2 */ + nfsm_strsiz(len2, NFS_MAXPATHLEN); + } pathcp = malloc(len2 + 1, M_TEMP, M_WAITOK); iv.iov_base = pathcp; iv.iov_len = len2; @@ -2091,13 +2114,15 @@ nfsrv_symlink(nfsd, slp, procp, mrq) } *(pathcp + len2) = '\0'; if (nd.ni_vp) { + error = EEXIST; +abortop: VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); if (nd.ni_dvp == nd.ni_vp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); - vrele(nd.ni_vp); - error = EEXIST; + if (nd.ni_vp) + vrele(nd.ni_vp); goto out; } nqsrv_getl(nd.ni_dvp, ND_WRITE); diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index e54a1647751e..6e6e857c7889 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_subs.c,v 1.109 2003/02/26 06:31:19 matt Exp $ */ +/* $NetBSD: nfs_subs.c,v 1.110 2003/03/28 13:05:48 yamt Exp $ */ /* * Copyright (c) 1989, 1993 @@ -74,7 +74,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.109 2003/02/26 06:31:19 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.110 2003/03/28 13:05:48 yamt Exp $"); #include "fs_nfs.h" #include "opt_nfs.h" @@ -1880,7 +1880,7 @@ int nfs_namei(ndp, fhp, len, slp, nam, mdp, dposp, retdirp, p, kerbflag, pubflag) struct nameidata *ndp; fhandle_t *fhp; - int len; + uint32_t len; struct nfssvc_sock *slp; struct mbuf *nam; struct mbuf **mdp; diff --git a/sys/nfs/nfsm_subs.h b/sys/nfs/nfsm_subs.h index 6f255f010aa6..6b65ed5e6074 100644 --- a/sys/nfs/nfsm_subs.h +++ b/sys/nfs/nfsm_subs.h @@ -1,4 +1,4 @@ -/* $NetBSD: nfsm_subs.h,v 1.24 2003/02/26 07:33:57 matt Exp $ */ +/* $NetBSD: nfsm_subs.h,v 1.25 2003/03/28 13:05:48 yamt Exp $ */ /* * Copyright (c) 1989, 1993 @@ -296,26 +296,24 @@ #define nfsm_strsiz(s,m) \ - { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \ + { nfsm_dissect(tl,uint32_t *,NFSX_UNSIGNED); \ + if (((s) = fxdr_unsigned(uint32_t,*tl)) > (m)) { \ m_freem(mrep); \ error = EBADRPC; \ goto nfsmout; \ } } #define nfsm_srvstrsiz(s,m) \ - { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \ + { nfsm_dissect(tl,uint32_t *,NFSX_UNSIGNED); \ + if (((s) = fxdr_unsigned(uint32_t,*tl)) > (m) || (s) <= 0) { \ error = EBADRPC; \ nfsm_reply(0); \ } } #define nfsm_srvnamesiz(s) \ - { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \ + { nfsm_dissect(tl,uint32_t *,NFSX_UNSIGNED); \ + if (((s) = fxdr_unsigned(uint32_t,*tl)) > NFS_MAXNAMLEN) \ error = NFSERR_NAMETOL; \ - if ((s) <= 0) \ - error = EBADRPC; \ if (error) \ nfsm_reply(0); \ }