shithub: riscv

Download patch

ref: c00c60d327168c25e56077c8310cf2380833e9be
parent: 607e651c0636bd2a73d7888ef1cea863f0bd5c53
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Apr 30 14:28:06 EDT 2017

sshfs: fix -r / retulting in "//foo" paths, memory leaks, use estrdup9p()

just use cleanname() to implement pathcat(), which
handles double slashes and ".." elements already.

have to free the partial dir structue on error in
parsedir().

use estrdup9p() instead of strdup().

--- a/sys/src/cmd/sshfs.c
+++ b/sys/src/cmd/sshfs.c
@@ -172,7 +172,7 @@
 	
 	for(p = tab[(ulong)id % HASH]; p != nil; p = p->next)
 		if(p->id == id)
-			return strdup(p->name);
+			return estrdup9p(p->name);
 	return smprint("%d", id);
 }
 
@@ -368,18 +368,21 @@
 }
 
 void
+freedir1(Dir *d)
+{
+	free(d->name);
+	free(d->uid);
+	free(d->gid);
+	free(d->muid);
+}
+
+void
 freedir(SFid *s)
 {
 	int i;
-	Dir *d;
 
-	for(i = 0; i < s->ndirent; i++){
-		d = &s->dirent[i];
-		free(d->name);
-		free(d->uid);
-		free(d->gid);
-		free(d->muid);
-	}
+	for(i = 0; i < s->ndirent; i++)
+		freedir1(&s->dirent[i]);
 	free(s->dirent);
 	s->dirent = nil;
 	s->ndirent = 0;
@@ -436,23 +439,13 @@
 char *
 pathcat(char *p, char *c)
 {
-	if(strcmp(p, ".") == 0)
-		return strdup(c);
-	return smprint("%s/%s", p, c);
+	return cleanname(smprint("%s/%s", p, c));
 }
 
 char *
 parentdir(char *p)
 {
-	char *q, *r;
-	
-	if(strcmp(p, ".") == 0) return strdup(".");
-	if(strcmp(p, "/") == 0) return strdup("/");
-	q = strdup(p);
-	r = strrchr(q, '/');
-	if(r != nil) *r = 0;
-	else strcpy(q, ".");
-	return q;
+	return pathcat(p, "..");
 }
 
 char *
@@ -461,8 +454,8 @@
 	char *q;
 	
 	q = strrchr(p, '/');
-	if(q == nil) return strdup(p);
-	return strdup(q+1);
+	if(q == nil) return estrdup9p(p);
+	return estrdup9p(q+1);
 }
 
 u64int
@@ -524,10 +517,10 @@
 		d->uid = idlookup(uidtab, uid);
 		d->gid = idlookup(gidtab, gid);
 	}else{
-		d->uid = strdup("sshfs");
-		d->gid = strdup("sshfs");
+		d->uid = estrdup9p("sshfs");
+		d->gid = estrdup9p("sshfs");
 	}
-	d->muid = strdup(d->uid);
+	d->muid = estrdup9p(d->uid);
 	if((flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0){
 		rc = unpack(p, ep - p, "u", &perm); if(rc < 0) return -1; p += rc;
 		d->mode = perm & 0777;
@@ -632,17 +625,16 @@
 	p = rxpkt + 9;
 	ep = rxpkt + rxlen;
 	for(i = 0; i < c; i++){
-		rc = unpack(p, ep - p, "ss", &fn, &fns, &ln, &lns); if(rc < 0) goto err; p += rc;
 		memset(d, 0, sizeof(Dir));
+		rc = unpack(p, ep - p, "ss", &fn, &fns, &ln, &lns); if(rc < 0) goto err; p += rc;
 		rc = attrib2dir(p, ep, d); if(rc < 0) goto err; p += rc;
 		if(fn[0] == '.' && (fns == 1 || fns == 2 && fn[1] == '.')){
-			free(d->uid);
-			free(d->gid);
-			free(d->muid);
+			freedir1(d);
 			continue;
 		}
 		d->name = emalloc9p(fns + 1);
 		memcpy(d->name, fn, fns);
+		d->name[fns] = 0;
 		s = pathcat(sf->fn, d->name);
 		d->qid.path = qidcalc(s);
 		free(s);
@@ -652,6 +644,7 @@
 	wunlock(sf);
 	return 0;
 err:
+	freedir1(d);
 	wunlock(sf);
 	return -1;
 }
@@ -731,9 +724,9 @@
 	}
 	sf = emalloc9p(sizeof(SFid));
 	if(r->ifcall.aname != nil && *r->ifcall.aname != 0)
-		sf->fn = strdup(r->ifcall.aname);
+		sf->fn = estrdup9p(r->ifcall.aname);
 	else
-		sf->fn = strdup(root);
+		sf->fn = estrdup9p(root);
 	root = ".";
 	sf->qid = (Qid){qidcalc(sf->fn), 0, QTDIR};
 	r->ofcall.qid = sf->qid;
@@ -855,8 +848,8 @@
 				}else if(r->req->aux == (void*)-2){
 					sendpkt("bus", SSH_FXP_OPENDIR, r->reqid, sf->fn, strlen(sf->fn));
 				}else{
-					sendpkt("bus", SSH_FXP_READDIR, r->reqid, sf->hand, sf->handn);
 					sf->dirreads++;
+					sendpkt("bus", SSH_FXP_READDIR, r->reqid, sf->hand, sf->handn);
 				}
 				wunlock(sf);
 			}else{
@@ -892,9 +885,9 @@
 				rlock(sf);
 				s = parentdir(sf->fn);
 				t = pathcat(s, r->req->d.name);
-				sendpkt("buss", SSH_FXP_RENAME, r->reqid, sf->fn, strlen(sf->fn), t, strlen(t));
 				free(s);
 				r->req->aux = t;
+				sendpkt("buss", SSH_FXP_RENAME, r->reqid, sf->fn, strlen(sf->fn), t, strlen(t));
 				runlock(sf);
 				break;
 			}
@@ -1137,7 +1130,7 @@
 		r->newfid->qid = r->fid->qid;
 		s = r->fid->aux;
 		t = emalloc9p(sizeof(SFid));
-		t->fn = strdup(s->fn);
+		t->fn = estrdup9p(s->fn);
 		t->qid = s->qid;
 		r->newfid->aux = t;
 	}else
@@ -1146,12 +1139,9 @@
 		respond(r, nil);
 		return;
 	}
-	p = strdup(t->fn);
+	p = estrdup9p(t->fn);
 	for(i = 0; i < r->ifcall.nwname; i++){
-		if(strcmp(r->ifcall.wname[i], "..") == 0)
-			q = parentdir(p);
-		else
-			q = pathcat(p, r->ifcall.wname[i]);
+		q = pathcat(p, r->ifcall.wname[i]);
 		free(p);
 		p = q;
 		r->ofcall.wqid[i] = (Qid){qidcalc(p), 0, QTDIR};
@@ -1271,7 +1261,7 @@
 		if(p == nil) break;
 		p++;
 		e = emalloc9p(sizeof(IDEnt));
-		e->name = strdup(n);
+		e->name = estrdup9p(n);
 		e->id = id;
 		b = &tab[((ulong)e->id) % HASH];
 		e->next = *b;