From c00c60d327168c25e56077c8310cf2380833e9be Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 30 Apr 2017 18:28:06 +0200 Subject: [PATCH] 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(). --- sys/src/cmd/sshfs.c | 72 +++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/sys/src/cmd/sshfs.c b/sys/src/cmd/sshfs.c index d8687900f..a44b0dcaf 100644 --- a/sys/src/cmd/sshfs.c +++ b/sys/src/cmd/sshfs.c @@ -172,7 +172,7 @@ idlookup(IDEnt **tab, int id) 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); } @@ -367,19 +367,22 @@ recvpkt(void) return rxpkt[0]; } +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 @@ submitreq(Req *r) 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 @@ finalelem(char *p) 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 @@ attrib2dir(uchar *p0, uchar *ep, Dir *d) 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 @@ parsedir(SFid *sf) 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 @@ parsedir(SFid *sf) wunlock(sf); return 0; err: + freedir1(d); wunlock(sf); return -1; } @@ -731,9 +724,9 @@ sshfsattach(Req *r) } 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 @@ sendproc(void *) }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 @@ sendproc(void *) 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 @@ sshfswalk(Req *r) 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 @@ sshfswalk(Req *r) 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 @@ passwdparse(IDEnt **tab, char *s) 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; -- 2.44.0