git: 9front

Download patch

ref: 3145dbcd0444dbc654cd85602c490a31a12f5147
parent: 8e1776881518c08f12960787f272c583f5517a9f
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){
--