shithub: riscv

Download patch

ref: b2cd4959fe3695d317b6b75956da55a7f77ed858
parent: b37238edb8f86809cdb395c235f9f2cc3f24d388
author: Ori Bernstein <ori@eigenstate.org>
date: Sat May 18 14:26:38 EDT 2024

gefs: check name lengths before packing them

--- a/sys/src/cmd/gefs/dat.h
+++ b/sys/src/cmd/gefs/dat.h
@@ -42,8 +42,9 @@
 	Ndtab	= 1024,			/* number of dir tab entries */
 	Max9p	= 32*KiB,		/* biggest message size we're willing to negotiate */
 	Nsec	= 1000LL*1000*1000,	/* nanoseconds to the second */
-	Maxname	= 256,			/* maximum size of a name element */
-	Maxent	= 9+Maxname+1,		/* maximum size of ent key, with terminator */
+	Maxent	= 256,			/* maximum size of ent key, with terminator */
+	Maxname	= Maxent-1-9-1,		/* maximum size of a name element */
+	Maxuname= 64,			/* maximum length of a username */
 	Maxtag	= 1<<16,		/* maximum tag in 9p */
 
 	/*
@@ -51,7 +52,7 @@
 	 * there is no way to get a valid split of a
 	 * maximally filled tree.
 	 */
-	Keymax	= 128,			/* key data limit */
+	Keymax	= Maxent,		/* key data limit */
 	Inlmax	= 512,			/* inline data limit */
 	Ptrsz	= 24,			/* off, hash, gen */
 	Pptrsz	= 26,			/* off, hash, gen, fill */
@@ -128,7 +129,8 @@
 #define Zb (Bptr){-1, -1, -1}
 
 /* internal errors */
-#define Efs	(abort(), "fs broke")
+//#define Efs	(abort(), "fs broke")
+extern char Efs[];
 extern char Ecorrupt[];
 extern char Efsvers[];
 extern char Eimpl[];
--- a/sys/src/cmd/gefs/error.c
+++ b/sys/src/cmd/gefs/error.c
@@ -4,6 +4,7 @@
 #include <fcall.h>
 #include "dat.h"
 
+char Efs[]	= "internal error";
 char Ecorrupt[] = "block contents corrupted";
 char Efsvers[]	= "unknown fs version";
 char Eimpl[]	= "not implemented";
--- a/sys/src/cmd/gefs/fs.c
+++ b/sys/src/cmd/gefs/fs.c
@@ -253,22 +253,22 @@
 	d->muid = -1;
 }
 
-static int
+static char*
 okname(char *name)
 {
 	int i;
 
 	if(name[0] == 0)
-		return -1;
+		return Ename;
 	if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
-		return -1;
+		return Ename;
 	for(i = 0; i < Maxname; i++){
 		if(name[i] == 0)
-			return 0;
+			return nil;
 		if((name[i]&0xff) < 0x20 || name[i] == '/')
-			return -1;
+			return Ename;
 	}
-	return -1;
+	return Elength;
 }
 
 Chan*
@@ -1230,9 +1230,11 @@
 	dmode = d.mode;
 	r.type = Rwalk;
 	for(i = 0; i < m->nwname; i++){
+		name = m->wname[i];
+		if(strlen(name) > Maxname)
+			error(Elength);
 		if(fsaccess(o, d.mode, d.uid, d.gid, DMEXEC) != 0)
 			error(Eperm);
-		name = m->wname[i];
 		if(d.qid.path == Qdump){
 			if((mnt = getmount(m->wname[i])) == nil)
 				error(Esrch);
@@ -1345,7 +1347,7 @@
 fswstat(Fmsg *m, int id, Amsg **ao)
 {
 	char rnbuf[Kvmax], opbuf[Kvmax], upbuf[Upksz];
-	char *p, strs[65535];
+	char *p, *e, strs[65535];
 	int op, nm, rename;
 	vlong oldlen;
 	Qid old;
@@ -1395,10 +1397,12 @@
 			error(Ewstatv);
 	}
 	if(*d.name != '\0'){
+		if(strlen(d.name) > Maxname)
+			error(Elength);
 		if(strcmp(d.name, de->name) != 0){
 			rename = 1;
-			if(okname(d.name) == -1)
-				error(Ename);
+			if((e = okname(d.name)) != nil)
+				error(e);
 			if(walk1(t, f->dent->up, d.name, &old, &oldlen) == 0)
 				error(Eexist);
 			n.name = d.name;
@@ -1452,6 +1456,8 @@
 		}
 	}
 	if(*d.uid != '\0'){
+		if(strlen(d.uid) > Maxuname)
+			error(Elength);
 		rlock(&fs->userlk);
 		u = name2user(d.uid);
 		if(u == nil){
@@ -1467,6 +1473,8 @@
 		}
 	}
 	if(*d.gid != '\0'){
+		if(strlen(d.gid) > Maxuname)
+			error(Elength);
 		rlock(&fs->userlk);
 		u = name2user(d.gid);
 		if(u == nil){
@@ -1573,7 +1581,7 @@
 static void
 fscreate(Fmsg *m)
 {
-	char *p, buf[Kvmax], upkbuf[Keymax], upvbuf[Inlmax];
+	char *p, *e, buf[Kvmax], upkbuf[Keymax], upvbuf[Inlmax];
 	Dent *de;
 	vlong oldlen;
 	Qid old;
@@ -1583,8 +1591,8 @@
 	Xdir d;
 	int nm;
 
-	if(okname(m->name) == -1){
-		rerror(m, Ename);
+	if((e = okname(m->name)) != nil){
+		rerror(m, e);
 		return;
 	}
 	if(m->perm & (DMMOUNT|DMAUTH)){
--- a/sys/src/cmd/gefs/pack.c
+++ b/sys/src/cmd/gefs/pack.c
@@ -12,8 +12,7 @@
 {
 	int n;
 
-	if (e - p < 3)
-		error(Elength);
+	assert(e - p >= 3);
 	n = UNPACK16(p);
 	if(e - p < n + 3 || p[n+2] != 0)
 		broke(Efs);
@@ -28,8 +27,7 @@
 	int n;
 
 	n = strlen(s);
-	if (e - p < n+3)
-		error(Elength);
+	assert(e - p >= n+3);
 	PACK16(p, n);		p += 2;
 	memmove(p, s, n);	p += n;
 	*p = 0;			p += 1;
--- a/sys/src/cmd/gefs/snap.c
+++ b/sys/src/cmd/gefs/snap.c
@@ -377,12 +377,12 @@
 
 	i = 0;
 	n = nil;
-	if(waserror()){
-		free(n);
-		nexterror();
-	}
 	if(flg & Lmut){
 		n = emalloc(sizeof(Tree), 1);
+		if(waserror()){
+			free(n);
+			nexterror();
+		}
 		n->memref = 1;
 		n->dirty = 0;
 		n->nlbl = 1;
@@ -405,6 +405,7 @@
 		m[i].op = Oinsert;
 		tree2kv(n, &m[i], buf[i], sizeof(buf[i]));
 		i++;
+		poperror();
 	}else{
 		t->nlbl++;
 		m[i].op = Orelink;
@@ -418,7 +419,6 @@
 		i++;
 	}
 	btupsert(&fs->snap, m, i);
-	poperror();
 	free(n);
 }