shithub: riscv

Download patch

ref: 3787f721c1efe19c0502dc7e429459804100757d
parent: dbbbff89151794c838319e831254bcff6b3dbbcf
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Wed Jan 30 01:28:42 EST 2013

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.

--- a/sys/src/cmd/auth/keyfs.c
+++ b/sys/src/cmd/auth/keyfs.c
@@ -224,6 +224,8 @@
 	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
--- a/sys/src/cmd/bzfs/oramfs.c
+++ b/sys/src/cmd/bzfs/oramfs.c
@@ -221,6 +221,8 @@
 	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
--- a/sys/src/cmd/cwfs/9p2.c
+++ b/sys/src/cmd/cwfs/9p2.c
@@ -113,7 +113,7 @@
 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)
--- a/sys/src/cmd/disk/kfs/9p2.c
+++ b/sys/src/cmd/disk/kfs/9p2.c
@@ -15,6 +15,9 @@
 static int
 fsversion(Chan* chan, Fcall* f, Fcall* r)
 {
+	if(f->msize < 256)
+		return Econvert;
+
 	if(f->msize < MSIZE)
 		r->msize = f->msize;
 	else
--- a/sys/src/cmd/exportfs/exportsrv.c
+++ b/sys/src/cmd/exportfs/exportsrv.c
@@ -26,11 +26,17 @@
 {
 	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";
--- a/sys/src/cmd/ip/ftpfs/ftpfs.c
+++ b/sys/src/cmd/ip/ftpfs/ftpfs.c
@@ -304,11 +304,13 @@
 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";
--- a/sys/src/cmd/unix/u9fs/u9fs.c
+++ b/sys/src/cmd/unix/u9fs/u9fs.c
@@ -355,6 +355,10 @@
 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;
--- a/sys/src/cmd/vnc/exportfs.c
+++ b/sys/src/cmd/vnc/exportfs.c
@@ -503,6 +503,8 @@
 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){
--