diff options
Diffstat (limited to 'sys/fs')
| -rw-r--r-- | sys/fs/fuse/fuse_ipc.c | 2 | ||||
| -rw-r--r-- | sys/fs/fuse/fuse_vnops.c | 2 | ||||
| -rw-r--r-- | sys/fs/nfs/nfs_commonsubs.c | 16 | ||||
| -rw-r--r-- | sys/fs/nfsclient/nfs_clrpcops.c | 36 | ||||
| -rw-r--r-- | sys/fs/nfsclient/nfs_clvfsops.c | 8 | ||||
| -rw-r--r-- | sys/fs/nfsserver/nfs_nfsdserv.c | 5 |
6 files changed, 46 insertions, 23 deletions
diff --git a/sys/fs/fuse/fuse_ipc.c b/sys/fs/fuse/fuse_ipc.c index 7f754ab7f1d4..bc36f0070d7d 100644 --- a/sys/fs/fuse/fuse_ipc.c +++ b/sys/fs/fuse/fuse_ipc.c @@ -694,7 +694,7 @@ fuse_body_audit(struct fuse_ticket *ftick, size_t blen) break; case FUSE_FORGET: - panic("FUSE: a handler has been intalled for FUSE_FORGET"); + panic("FUSE: a handler has been installed for FUSE_FORGET"); break; case FUSE_GETATTR: diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c index 683ee2f7ad56..97aa23bfb0b0 100644 --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -2756,7 +2756,7 @@ fuse_vnop_setextattr(struct vop_setextattr_args *ap) */ if (fsess_not_impl(mp, FUSE_REMOVEXATTR)) return (EXTERROR(EOPNOTSUPP, "This server does not " - "implement removing extended attributess")); + "implement removing extended attributes")); else return (EXTERROR(EINVAL, "DELETEEXTATTR should be used " "to remove extattrs")); diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 8d506a5643a9..f580a394a735 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -194,7 +194,6 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = { { 0, 1, 1, 1, LK_EXCLUSIVE, 1, 1 }, /* Removexattr */ }; -static int ncl_mbuf_mhlen = MHLEN; struct nfsrv_lughash { struct mtx mtx; struct nfsuserhashhead lughead; @@ -770,7 +769,7 @@ nfsm_dissct(struct nfsrv_descript *nd, int siz, int how) nd->nd_dpos += siz; } else if (nd->nd_md->m_next == NULL) { return (retp); - } else if (siz > ncl_mbuf_mhlen) { + } else if (siz > MHLEN) { panic("nfs S too big"); } else { MGET(mp2, how, MT_DATA); @@ -4192,10 +4191,15 @@ nfssvc_idname(struct nfsd_idargs *nidp) nidp->nid_namelen); if (error == 0 && nidp->nid_ngroup > 0 && (nidp->nid_flag & NFSID_ADDUID) != 0) { - grps = malloc(sizeof(gid_t) * nidp->nid_ngroup, M_TEMP, - M_WAITOK); - error = copyin(nidp->nid_grps, grps, - sizeof(gid_t) * nidp->nid_ngroup); + grps = NULL; + if (nidp->nid_ngroup > NGROUPS_MAX) + error = EINVAL; + if (error == 0) { + grps = malloc(sizeof(gid_t) * nidp->nid_ngroup, M_TEMP, + M_WAITOK); + error = copyin(nidp->nid_grps, grps, + sizeof(gid_t) * nidp->nid_ngroup); + } if (error == 0) { /* * Create a credential just like svc_getcred(), diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index d3b83eb8b94b..b61218958550 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -2212,7 +2212,7 @@ nfsrpc_writerpc(vnode_t vp, struct uio *uiop, int *iomode, NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_VERF); rlen = fxdr_unsigned(int, *tl++); - if (rlen == 0) { + if (rlen <= 0 || rlen > len) { error = NFSERR_IO; goto nfsmout; } else if (rlen < len) { @@ -5284,7 +5284,7 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpath, struct ucred *cred, struct nfsrv_descript nfsd; struct nfsrv_descript *nd = &nfsd; u_char *cp, *cp2, *fhp; - int error, cnt, len, setnil; + int error, cnt, i, len, setnil; u_int32_t *opcntp; nfscl_reqstart(nd, NFSPROC_PUTROOTFH, nmp, NULL, 0, &opcntp, NULL, 0, @@ -5325,8 +5325,12 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpath, struct ucred *cred, if (error) return (error); if (nd->nd_repstat == 0) { - NFSM_DISSECT(tl, u_int32_t *, (3 + 2 * cnt) * NFSX_UNSIGNED); - tl += (2 + 2 * cnt); + NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_UNSIGNED); + tl += 2; + for (i = 0; i < cnt; i++) { + NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); + tl++; + } if ((len = fxdr_unsigned(int, *tl)) <= 0 || len > NFSX_FHMAX) { nd->nd_repstat = NFSERR_BADXDR; @@ -5599,7 +5603,7 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep, } *tl++ = txdr_unsigned(4096); /* Max response size cached */ *tl++ = txdr_unsigned(20); /* Max operations */ - *tl++ = txdr_unsigned(64); /* Max slots */ + *tl++ = txdr_unsigned(NFSV4_SLOTS); /* Max slots */ *tl = 0; /* No rdma ird */ /* Fill in back channel attributes. */ @@ -5668,6 +5672,11 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep, sep->nfsess_maxcache = fxdr_unsigned(int, *tl++); tl++; sep->nfsess_foreslots = fxdr_unsigned(uint16_t, *tl++); + if (sep->nfsess_foreslots == 0) { + error = NFSERR_BADXDR; + goto nfsmout; + } else if (sep->nfsess_foreslots > NFSV4_SLOTS) + sep->nfsess_foreslots = NFSV4_SLOTS; NFSCL_DEBUG(4, "fore slots=%d\n", (int)sep->nfsess_foreslots); irdcnt = fxdr_unsigned(int, *tl); if (irdcnt < 0 || irdcnt > 1) { @@ -5681,6 +5690,8 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep, NFSM_DISSECT(tl, uint32_t *, 7 * NFSX_UNSIGNED); tl += 5; sep->nfsess_backslots = fxdr_unsigned(uint16_t, *tl); + if (sep->nfsess_backslots > NFSV4_CBSLOTS) + sep->nfsess_backslots = NFSV4_CBSLOTS; NFSCL_DEBUG(4, "back slots=%d\n", (int)sep->nfsess_backslots); } error = nd->nd_repstat; @@ -5800,7 +5811,8 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *deviceid, int layouttype, NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); stripecnt = fxdr_unsigned(int, *tl); NFSCL_DEBUG(4, "stripecnt=%d\n", stripecnt); - if (stripecnt < 1 || stripecnt > 4096) { + if (stripecnt >= MHLEN / NFSX_UNSIGNED || + stripecnt < 1) { printf("pNFS File layout devinfo stripecnt %d:" " out of range\n", stripecnt); error = NFSERR_BADXDR; @@ -7249,7 +7261,7 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED + NFSX_VERF); rlen = fxdr_unsigned(int, *tl++); NFSCL_DEBUG(4, "nfsrpc_writeds: len=%d rlen=%d\n", len, rlen); - if (rlen == 0) { + if (rlen <= 0 || rlen > len) { error = NFSERR_IO; goto nfsmout; } else if (rlen < len) { @@ -8246,7 +8258,7 @@ nfsrv_parseug(struct nfsrv_descript *nd, int dogrp, uid_t *uidp, gid_t *gidp, NFSPROC_T *p) { uint32_t *tl; - char *cp, *str, str0[NFSV4_SMALLSTR + 1]; + char *str, str0[NFSV4_SMALLSTR + 1]; uint32_t len = 0; int error = 0; @@ -8269,9 +8281,9 @@ nfsrv_parseug(struct nfsrv_descript *nd, int dogrp, uid_t *uidp, gid_t *gidp, str = malloc(len + 1, M_TEMP, M_WAITOK); else str = str0; - NFSM_DISSECT(cp, char *, NFSM_RNDUP(len)); - NFSBCOPY(cp, str, len); - str[len] = '\0'; + error = nfsrv_mtostr(nd, str, len); + if (error != 0) + goto nfsmout; NFSCL_DEBUG(4, "nfsrv_parseug: str=%s\n", str); if (dogrp != 0) error = nfsv4_strtogid(nd, str, len, gidp); @@ -9748,7 +9760,7 @@ nfsm_split(struct mbuf *mp, uint64_t xfer) pgno++; } while (pgno < m->m_epg_npgs); if (pgno == m->m_epg_npgs) - panic("nfsm_split: eroneous ext_pgs mbuf"); + panic("nfsm_split: erroneous ext_pgs mbuf"); m2 = mb_alloc_ext_pgs(M_WAITOK, mb_free_mext_pgs, 0); m2->m_epg_flags |= EPG_FLAG_ANON; diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 5ea7eab07632..212c88f28930 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -927,7 +927,7 @@ nfs_mount(struct mount *mp) struct vnode *vp; struct thread *td; char *hst; - u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100]; + u_char nfh[NFSX_FHMAX], krbname[100], *dirpath, srvkrbname[100]; char *cp, *opt, *name, *secname, *tlscertname; int nametimeo = NFS_DEFAULT_NAMETIMEO; int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO; @@ -943,6 +943,7 @@ nfs_mount(struct mount *mp) newflag = 0; tlscertname = NULL; hst = malloc(MNAMELEN, M_TEMP, M_WAITOK); + dirpath = malloc(MNAMELEN, M_TEMP, M_WAITOK); if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { error = EINVAL; goto out; @@ -1329,7 +1330,7 @@ nfs_mount(struct mount *mp) goto out; } else if (nfs_mount_parse_from(mp->mnt_optnew, &args.hostname, (struct sockaddr_in **)&nam, dirpath, - sizeof(dirpath), &dirlen) == 0) { + MNAMELEN, &dirlen) == 0) { has_nfs_from_opt = 1; bcopy(args.hostname, hst, MNAMELEN); hst[MNAMELEN - 1] = '\0'; @@ -1387,7 +1388,7 @@ nfs_mount(struct mount *mp) if (has_nfs_from_opt == 0) { if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0) - strlcpy(dirpath, name, sizeof (dirpath)); + strlcpy(dirpath, name, MNAMELEN); else dirpath[0] = '\0'; dirlen = strlen(dirpath); @@ -1472,6 +1473,7 @@ out: MNT_IUNLOCK(mp); } free(hst, M_TEMP); + free(dirpath, M_TEMP); return (error); } diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 6f3447f26620..67af0cf71175 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -5138,6 +5138,11 @@ nfsrvd_layoutcommit(struct nfsrv_descript *nd, __unused int isdgram, NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); layouttype = fxdr_unsigned(int, *tl++); maxcnt = fxdr_unsigned(int, *tl); + /* There is no limit in the RFC, so use 1000 as a sanity limit. */ + if (maxcnt < 0 || maxcnt > 1000) { + error = NFSERR_BADXDR; + goto nfsmout; + } if (maxcnt > 0) { layp = malloc(maxcnt + 1, M_TEMP, M_WAITOK); error = nfsrv_mtostr(nd, layp, maxcnt); |
