]> git.lizzy.rs Git - plan9front.git/commitdiff
sshfs: fix -r / retulting in "//foo" paths, memory leaks, use estrdup9p()
authorcinap_lenrek <cinap_lenrek@felloff.net>
Sun, 30 Apr 2017 16:28:06 +0000 (18:28 +0200)
committercinap_lenrek <cinap_lenrek@felloff.net>
Sun, 30 Apr 2017 16:28:06 +0000 (18:28 +0200)
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

index d8687900f8b086c55d249f988b32f245a498aa94..a44b0dcaf186c6236252c8e0c0447f8a1d09909d 100644 (file)
@@ -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;