summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2019-01-18 13:56:39 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2019-01-18 13:56:39 +0000
commitd56258d58186dc64070f940dbe33ec9b20c4cc8c (patch)
tree464f56fae625457f9f2c82d143c79b7ca58a63be /sys
parent21718a942e1ad7f14af97f94c17b5965fd31cca7 (diff)
Check for negative length integers in NFS server. A malicious
client could crash the server. OK tedu@
Diffstat (limited to 'sys')
-rw-r--r--sys/nfs/nfs_serv.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c
index cf1ed7733dd..f69afb57f98 100644
--- a/sys/nfs/nfs_serv.c
+++ b/sys/nfs/nfs_serv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_serv.c,v 1.117 2018/11/09 14:14:32 claudio Exp $ */
+/* $OpenBSD: nfs_serv.c,v 1.118 2019/01/18 13:56:38 bluhm Exp $ */
/* $NetBSD: nfs_serv.c,v 1.34 1997/05/12 23:37:12 fvdl Exp $ */
/*
@@ -1720,7 +1720,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
nfsm_mtouio(&io, len2);
if (!info.nmi_v3) {
nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
- va.va_mode = fxdr_unsigned(u_int16_t, sp->sa_mode);
+ va.va_mode = nfstov_mode(sp->sa_mode);
}
*(pathcp + len2) = '\0';
if (nd.ni_vp) {
@@ -2092,12 +2092,12 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
}
off = toff;
cnt = fxdr_unsigned(int, *tl);
- siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
xfer = NFS_SRVMAXDATA(nfsd);
+ if (cnt > xfer || cnt < 0)
+ cnt = xfer;
+ siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
if (siz > xfer)
siz = xfer;
- if (cnt > xfer)
- cnt = xfer;
fullsiz = siz;
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
if (error) {
@@ -2285,19 +2285,18 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
- toff = fxdr_hyper(tl);
+ off = toff = fxdr_hyper(tl);
tl += 2;
verf = fxdr_hyper(tl);
tl += 2;
siz = fxdr_unsigned(int, *tl++);
cnt = fxdr_unsigned(int, *tl);
- off = toff;
- siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
xfer = NFS_SRVMAXDATA(nfsd);
+ if (cnt > xfer || cnt < 0)
+ cnt = xfer;
+ siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
if (siz > xfer)
siz = xfer;
- if (cnt > xfer)
- cnt = xfer;
fullsiz = siz;
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
if (error) {
@@ -2532,6 +2531,8 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
off = fxdr_hyper(tl);
tl += 2;
cnt = fxdr_unsigned(int, *tl);
+ if (cnt < 0)
+ cnt = 0;
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);