From 3787f721c1efe19c0502dc7e429459804100757d Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Wed, 30 Jan 2013 06:28:42 +0100 Subject: [PATCH] 9p message size too small various fileservers do not check if the message size is too small (they subtract IOHDRSZ later from it to calculate iounit) which can overflow. --- sys/src/cmd/auth/keyfs.c | 2 ++ sys/src/cmd/bzfs/oramfs.c | 2 ++ sys/src/cmd/cwfs/9p2.c | 2 +- sys/src/cmd/disk/kfs/9p2.c | 3 +++ sys/src/cmd/exportfs/exportsrv.c | 6 ++++++ sys/src/cmd/ip/ftpfs/ftpfs.c | 8 +++++--- sys/src/cmd/unix/u9fs/u9fs.c | 4 ++++ sys/src/cmd/vnc/exportfs.c | 2 ++ 8 files changed, 25 insertions(+), 4 deletions(-) diff --git a/sys/src/cmd/auth/keyfs.c b/sys/src/cmd/auth/keyfs.c index 61df8d61b..193acf27e 100644 --- a/sys/src/cmd/auth/keyfs.c +++ b/sys/src/cmd/auth/keyfs.c @@ -224,6 +224,8 @@ Version(Fid*) for(f = fids; f; f = f->next) if(f->busy) Clunk(f); + if(rhdr.msize < 256) + return "message size too small"; if(rhdr.msize > sizeof mdata) thdr.msize = sizeof mdata; else diff --git a/sys/src/cmd/bzfs/oramfs.c b/sys/src/cmd/bzfs/oramfs.c index cba02724a..7f5d686d8 100644 --- a/sys/src/cmd/bzfs/oramfs.c +++ b/sys/src/cmd/bzfs/oramfs.c @@ -221,6 +221,8 @@ rversion(Fid*) for(f = fids; f; f = f->next) if(f->busy) rclunk(f); + if(thdr.msize < 256) + return "message size too small"; if(thdr.msize > sizeof mdata) rhdr.msize = sizeof mdata; else diff --git a/sys/src/cmd/cwfs/9p2.c b/sys/src/cmd/cwfs/9p2.c index 8c34691f5..97fafe55f 100644 --- a/sys/src/cmd/cwfs/9p2.c +++ b/sys/src/cmd/cwfs/9p2.c @@ -113,7 +113,7 @@ mkdir9p2(Dir* dir, Dentry* dentry, void* strs) static int version(Chan* chan, Fcall* f, Fcall* r) { - if(chan->protocol != nil) + if(chan->protocol != nil || f->msize < 256) return Eversion; if(f->msize < MSIZE) diff --git a/sys/src/cmd/disk/kfs/9p2.c b/sys/src/cmd/disk/kfs/9p2.c index de99ebd8f..90510a409 100644 --- a/sys/src/cmd/disk/kfs/9p2.c +++ b/sys/src/cmd/disk/kfs/9p2.c @@ -15,6 +15,9 @@ seterror(Fcall *ou, int err) static int fsversion(Chan* chan, Fcall* f, Fcall* r) { + if(f->msize < 256) + return Econvert; + if(f->msize < MSIZE) r->msize = f->msize; else diff --git a/sys/src/cmd/exportfs/exportsrv.c b/sys/src/cmd/exportfs/exportsrv.c index 842880529..7e8d836ff 100644 --- a/sys/src/cmd/exportfs/exportsrv.c +++ b/sys/src/cmd/exportfs/exportsrv.c @@ -26,11 +26,17 @@ Xversion(Fsrpc *t) { Fcall rhdr; + if(t->work.msize < 256){ + reply(&t->work, &rhdr, "version: message size too small"); + t->busy = 0; + return; + } if(t->work.msize > messagesize) t->work.msize = messagesize; messagesize = t->work.msize; if(strncmp(t->work.version, "9P2000", 6) != 0){ reply(&t->work, &rhdr, Eversion); + t->busy = 0; return; } rhdr.version = "9P2000"; diff --git a/sys/src/cmd/ip/ftpfs/ftpfs.c b/sys/src/cmd/ip/ftpfs/ftpfs.c index 17e0df7b4..5d6f35b2e 100644 --- a/sys/src/cmd/ip/ftpfs/ftpfs.c +++ b/sys/src/cmd/ip/ftpfs/ftpfs.c @@ -304,11 +304,13 @@ rnop(Fid *f) char* rversion(Fid*) { - if(thdr.msize > sizeof(mdata)) - rhdr.msize = messagesize; + if(thdr.msize < 256) + return "version: message size too small"; + if(thdr.msize > sizeof mdata) + rhdr.msize = sizeof mdata; else rhdr.msize = thdr.msize; - messagesize = thdr.msize; + messagesize = rhdr.msize; if(strncmp(thdr.version, "9P2000", 6) != 0) return "unknown 9P version"; diff --git a/sys/src/cmd/unix/u9fs/u9fs.c b/sys/src/cmd/unix/u9fs/u9fs.c index eeee21f12..b98ced8ba 100644 --- a/sys/src/cmd/unix/u9fs/u9fs.c +++ b/sys/src/cmd/unix/u9fs/u9fs.c @@ -355,6 +355,10 @@ serve(int rfd, int wfd) void rversion(Fcall *rx, Fcall *tx) { + if(rx->msize < 256){ + seterror(tx, "version: message size too small"); + return; + } if(msize > rx->msize) msize = rx->msize; tx->msize = msize; diff --git a/sys/src/cmd/vnc/exportfs.c b/sys/src/cmd/vnc/exportfs.c index 4948016d4..a2feb83ae 100644 --- a/sys/src/cmd/vnc/exportfs.c +++ b/sys/src/cmd/vnc/exportfs.c @@ -503,6 +503,8 @@ Exputfid(Export *fs, Fid *f) static char* Exversion(Export *fs, Fcall *rpc, uchar *) { + if(rpc->msize < 256) + return "version: message size too small"; if(rpc->msize > Maxrpc) rpc->msize = Maxrpc; if(strncmp(rpc->version, "9P", 2) != 0){