--- /sys/src/cmd/tapefs/tarfs.c Tue Jul 3 02:08:07 2007 +++ /sys/src/cmd/tapefs/tarfs.c Wed Oct 2 01:21:13 2013 @@ -144,10 +144,12 @@ } f.mode &= DMDIR | 0777; - /* make file name safe and canonical */ + /* make file name safe, canonical and free of . and .. */ while (fname[0] == '/') /* don't allow absolute paths */ ++fname; cleanname(fname); + while (strncmp(fname, "../", 3) == 0) + fname += 3; /* reject links */ linkflg = hp->linkflag == LF_SYMLINK1 || --- /sys/src/cmd/tar.c Fri Jul 29 20:37:30 2011 +++ /sys/src/cmd/tar.c Wed Oct 2 01:48:17 2013 @@ -869,6 +869,7 @@ int i, ar; ulong blksleft, blksread; Off bytes; + char *arg; Hdr *hp; Compress *comp = nil; Pushstate ps; @@ -909,7 +910,12 @@ } for (i = 0; argv[i] != nil; i++) { - addtoar(ar, argv[i], argv[i]); + arg = argv[i]; + cleanname(arg); + if (strcmp(arg, "..") == 0 || strncmp(arg, "../", 3) == 0) + fprint(2, "%s: name starting with .. is a bad idea\n", + argv0); + addtoar(ar, arg, arg); chdir(origdir); /* for correctness & profiling */ } --- /sys/src/cmd/test.c Wed May 28 19:54:23 2008 +++ /sys/src/cmd/test.c Wed Oct 2 00:34:44 2013 @@ -327,7 +327,7 @@ int isolder(char *pin, char *f) { - int r; + int r, rel; ulong n, m; char *p = pin; Dir *dir; @@ -338,6 +338,7 @@ /* parse time */ n = 0; + rel = 0; while(*p){ m = strtoul(p, &p, 0); switch(*p){ @@ -362,13 +363,22 @@ case 's': n += m; p++; + rel = 1; break; default: synbad("bad time syntax, ", pin); } } - - r = dir->mtime + n < time(0); + if (!rel) + m = n; + else{ + m = time(0); + if (n > m) /* before epoch? */ + m = 0; + else + m -= n; + } + r = dir->mtime < m; free(dir); return r; }