diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-12-03 19:16:22 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-12-03 19:16:22 +0100 |
commit | 2fcd19f16eafc8ce22407334ee9ae0239f4e0be2 (patch) | |
tree | 793af9ee839d5e1974e09f70f72588290c24f71e /sys/src/ape | |
parent | a16f5cd2a33644a49974e1b6d9ef619155725d45 (diff) |
ape: fix memory leak and path limit in unlink()
db1 was leaked, and newname could overflow. fixed.
Diffstat (limited to 'sys/src/ape')
-rw-r--r-- | sys/src/ape/lib/ap/plan9/unlink.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/sys/src/ape/lib/ap/plan9/unlink.c b/sys/src/ape/lib/ap/plan9/unlink.c index a015c782f..c79f1b83b 100644 --- a/sys/src/ape/lib/ap/plan9/unlink.c +++ b/sys/src/ape/lib/ap/plan9/unlink.c @@ -19,7 +19,7 @@ unlink(const char *path) long long nn; Dir *db1, *db2, nd; Fdinfo *f; - char *p, newname[PATH_MAX], newelem[32]; + char *p, *newname, newelem[32]; /* if the file is already open, make it close-on-exec (and rename to qid) */ if((db1 = _dirstat(path)) == nil) { @@ -33,7 +33,10 @@ unlink(const char *path) db1->qid.vers == db2->qid.vers && db1->type == db2->type && db1->dev == db2->dev) { - sprintf(newelem, "%8.8lx%8.8lx", (ulong)(db2->qid.path>>32), (ulong)db2->qid.path); + newname = 0; + sprintf(newelem, "%8.8lx%8.8lx", + (ulong)(db2->qid.path>>32), + (ulong)db2->qid.path); _nulldir(&nd); nd.name = newelem; if(_dirfwstat(i, &nd) < 0) @@ -43,15 +46,23 @@ unlink(const char *path) if(p == 0) p = newelem; else { - memmove(newname, path, p-path); - newname[p-path] = '/'; - strcpy(newname+(p-path)+1, newelem); + n = p-path; + newname = malloc(n+1+sizeof(newelem)); + if(newname == 0){ + free(db2); + free(db1); + return -1; + } + memmove(newname, path, n); + newname[n] = '/'; + strcpy(newname+n+1, newelem); p = newname; } } /* reopen remove on close */ - fd = _OPEN(p, 64|(f->oflags)); + fd = _OPEN(p, ORCLOSE|(f->oflags)); if(fd < 0){ + free(newname); free(db2); continue; } @@ -61,6 +72,8 @@ unlink(const char *path) _SEEK(fd, nn, 0); _DUP(fd, i); _CLOSE(fd); + free(newname); + free(db2); free(db1); return 0; } |