This patch solves the "bugs" mentioned in: http://schtarb.free.fr/plan9.txt at the beginning. The last section did not seem to be bugs, so I did not look at them. Notes: Sun May 22 00:51:30 EDT 2005 rsc Thanks for taking a look at these. A few small things to fix: 1. In troff/t10.c you call strncpy without a third argument. Not sure why building troff wouldn't have caught that. 2. Please don't use strncpy(dst, src, n). Use strecpy(dst, dst+n, src). The difference between the two is that strecpy promises to NUL-terminate dst, while strncpy does not. 3. In awd, you changed the prints into a series of fprints. This is not okay -- these are control messages and they need to arrive at acme as a single write. Use smprint if you need to. Thanks again for taking care of these. I look forward to another patch. Russ Reference: /n/sources/patch/sorry/schtarb-plan9 Date: Sat May 21 23:55:27 CES 2005 Reviewed-by: rsc --- /sys/src/cmd/auth/none.c Sat May 21 23:27:33 2005 +++ /sys/src/cmd/auth/none.c Sat May 21 23:27:29 2005 @@ -23,12 +23,12 @@ sysfatal("can't build namespace"); if (argc > 1) { - strcpy(cmd, argv[1]); + strncpy(cmd, argv[1], sizeof(cmd)); exec(cmd, &argv[1]); if (strncmp(cmd, "/", 1) != 0 && strncmp(cmd, "./", 2) != 0 && strncmp(cmd, "../", 3) != 0) { - sprint(cmd, "/bin/%s", argv[1]); + snprint(cmd, sizeof(cmd), "/bin/%s", argv[1]); exec(cmd, &argv[1]); } } else { --- /sys/src/cmd/upas/send/filter.c Sat May 21 23:27:51 2005 +++ /sys/src/cmd/upas/send/filter.c Sat May 21 23:27:47 2005 @@ -14,7 +14,7 @@ dest *dp; Reprog *p; Resub match[10]; - char file[MAXPATHLEN]; + char file[MAXPATHLEN + 1]; Biobuf *fp; char *rcvr, *cp; Mlock *l; @@ -48,7 +48,7 @@ } dp = d_new(s_copy(argv[0])); - strcpy(file, argv[1]); + strncpy(file, argv[1], sizeof(file)); cp = findbody(s_to_c(mp->body)); for(i = 2; i < argc; i += 2){ p = regcomp(argv[i]); --- /sys/src/cmd/bzip2/bzip2recover.c Sat May 21 23:28:16 2005 +++ /sys/src/cmd/bzip2/bzip2recover.c Sat May 21 23:28:10 2005 @@ -290,7 +290,7 @@ exit(1); } - strcpy ( inFileName, argv[1] ); + strncpy ( inFileName, argv[1], sizeof(inFileName) ); inFile = fopen ( inFileName, "rb" ); if (inFile == NULL) { --- /sys/src/cmd/spin/main.c Sat May 21 23:28:45 2005 +++ /sys/src/cmd/spin/main.c Sat May 21 23:28:39 2005 @@ -317,14 +317,14 @@ if (argc > 1) { char cmd[128], out2[64]; #ifdef PC - strcpy(out1, "_tmp1_"); - strcpy(out2, "_tmp2_"); + strncpy(out1, "_tmp1_", sizeof(out1)); + strncpy(out2, "_tmp2_", sizeof(out2)); #else /* extern char *tmpnam(char *); in stdio.h */ if (add_ltl || nvr_file) { /* must remain in current dir */ - strcpy(out1, "_tmp1_"); - strcpy(out2, "_tmp2_"); + strncpy(out1, "_tmp1_", sizeof(out1)); + strncpy(out2, "_tmp2_", sizeof(out2)); } else { (void) tmpnam(out1); (void) tmpnam(out2); @@ -367,9 +367,9 @@ if (strncmp(argv[1], "progress", 8) == 0 || strncmp(argv[1], "accept", 6) == 0) - sprintf(cmd, "_%s", argv[1]); + snprintf(cmd, sizeof(cmd), "_%s", argv[1]); else - strcpy(cmd, argv[1]); + strncpy(cmd, argv[1], sizeof(cmd)); oFname = Fname = lookup(cmd); if (oFname->name[0] == '\"') { int i = strlen(oFname->name); --- /sys/src/cmd/calendar.c Sat May 21 23:29:16 2005 +++ /sys/src/cmd/calendar.c Sat May 21 23:29:12 2005 @@ -77,7 +77,7 @@ snprint(buf, sizeof(buf), "/usr/%s/lib/calendar", getuser()); else - strcpy(buf, argv[i]); + strncpy(buf, sizeof(buf), argv[i]); fd = open(buf, OREAD); if(fd<0 || Binit(&in, fd, OREAD)<0){ fprint(2, "calendar: can't open %s: %r\n", buf); --- /sys/src/cmd/aux/reboot.c Sat May 21 23:29:52 2005 +++ /sys/src/cmd/aux/reboot.c Sat May 21 23:29:48 2005 @@ -64,7 +64,7 @@ notify(ding); if(argc > 1) - strcpy(file, argv[1]); + strncpy(file, sizeof(file), argv[1]); else{ p = readenv("cputype", buf, sizeof(buf)); if(p == 0) --- /sys/src/cmd/gs/jpeg/wrjpgcom.c Sat May 21 23:30:34 2005 +++ /sys/src/cmd/gs/jpeg/wrjpgcom.c Sat May 21 23:30:28 2005 @@ -445,7 +445,7 @@ comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); if (comment_arg == NULL) ERREXIT("Insufficient memory"); - strcpy(comment_arg, argv[argn]+1); + strncpy(comment_arg, sizeof(comment_arg), argv[argn]+1); for (;;) { comment_length = strlen(comment_arg); if (comment_length > 0 && comment_arg[comment_length-1] == '"') { --- /sys/src/cmd/spin/tl_main.c Sat May 21 23:31:23 2005 +++ /sys/src/cmd/spin/tl_main.c Sat May 21 23:31:19 2005 @@ -66,7 +66,7 @@ || argv[1][i] == '\n') argv[1][i] = ' '; } - strcpy(uform, argv[1]); + strncpy(uform, sizeof(uform), argv[1]); hasuform = strlen(uform); break; case 'v': tl_verbose++; --- /sys/src/cmd/upas/scanmail/scanmail.c Sat May 21 23:32:10 2005 +++ /sys/src/cmd/upas/scanmail/scanmail.c Sat May 21 23:32:05 2005 @@ -102,7 +102,7 @@ usage(); argc--; argv++; - strcpy(patfile, *argv); + strncpy(patfile, sizeof(patfile), *argv); break; case 'q': /* queue name */ if(argv[0][2] || argv[1] == 0) --- /sys/src/libscribble/graffiti.c Sat May 21 23:33:02 2005 +++ /sys/src/libscribble/graffiti.c Sat May 21 23:32:58 2005 @@ -187,13 +187,11 @@ /* ...then figure out where the classifiers are... */ if ( (homedir = (char*)getenv("home")) == nil ) { if(0)fprint(2, "no homedir, using = %s\n", REC_DEFAULT_USER_DIR); - strcpy(pg->cldir, REC_DEFAULT_USER_DIR); + strncpy(pg->cldir, REC_DEFAULT_USER_DIR, sizeof(pg->cldir)); usingDefault = true; } else { if(0)fprint(2, "homedir = %s\n", homedir); - strcpy(pg->cldir, homedir); - strcat(pg->cldir, "/"); - strcat(pg->cldir, CLASSIFIER_DIR); + snprint(pg->cldir, sizeof(pg->cldir), "%s/%s", homedir, CLASSIFIER_DIR); usingDefault = false; } --- /sys/src/cmd/aux/vga/main.c Sat May 21 23:33:57 2005 +++ /sys/src/cmd/aux/vga/main.c Sat May 21 23:33:53 2005 @@ -289,9 +289,9 @@ if(iflag || lflag){ if(getenv(type)) - sprint(monitordb, "/env/%s", type); + snprint(monitordb, sizeof(monitordb), "/env/%s", type); else - strcpy(monitordb, dbname); + strncpy(monitordb, dbname, sizeof(monitordb)); if(vga->vesa){ strcpy(monitordb, "vesa bios"); --- /sys/src/cmd/troff/t10.c Sat May 21 23:34:57 2005 +++ /sys/src/cmd/troff/t10.c Sat May 21 23:34:52 2005 @@ -48,7 +48,7 @@ /* open table for device, */ /* read in resolution, size info, font info, etc., set params */ if ((p = getenv("TYPESETTER")) != 0) - strcpy(devname, p); + strncpy(devname, p); if (termtab[0] == 0) strcpy(termtab, DWBfontdir); if (fontdir[0] == 0) @@ -58,7 +58,7 @@ hyf = 1; lg = 1; - sprintf(buf, "/dev%s/DESC", devname); + snprintf(buf, sizeof(buf), "/dev%s/DESC", devname); strcat(termtab, buf); if (getdesc(termtab) < 0) { ERROR "can't open DESC file %s", termtab WARN; --- /sys/src/cmd/ip/ftpd.c Sat May 21 23:36:05 2005 +++ /sys/src/cmd/ip/ftpd.c Sat May 21 23:35:57 2005 @@ -217,7 +217,7 @@ /* figure out which binaries to bind in later */ arg = getenv("cputype"); if(arg) - strcpy(cputype, arg); + strncpy(cputype, arg, sizeof(cputype)); else strcpy(cputype, "mips"); snprint(bindir, sizeof(bindir), "/bin/%s/bin", cputype); --- /sys/src/cmd/7a/lex.c Sat May 21 23:37:12 2005 +++ /sys/src/cmd/7a/lex.c Sat May 21 23:37:07 2005 @@ -81,7 +81,7 @@ } child: - strcpy(ofile, *argv); + strncpy(ofile, *argv, sizeof(ofile)); if(p = strrchr(ofile, '/')) { include[0] = ofile; *p++ = 0; --- /sys/src/cmd/upas/common/libsys.c Sat May 21 23:38:24 2005 +++ /sys/src/cmd/upas/common/libsys.c Sat May 21 23:38:18 2005 @@ -429,7 +429,7 @@ cp = alt_sysname_read(); if(cp == 0 || *cp == 0) cp = "kremvax"; - strcpy(name, cp); + strncpy(name, cp, sizeof(name)); return name; } extern char * --- /sys/src/ape/lib/ap/plan9/system.c Sat May 21 23:39:36 2005 +++ /sys/src/ape/lib/ap/plan9/system.c Sat May 21 23:39:32 2005 @@ -17,7 +17,7 @@ if(!s) return 1; /* a command interpreter is available */ pid = fork(); - sprintf(cmd, "/%s/bin/ape/sh", oty); + snprintf(cmd, sizeof(cmd), "/%s/bin/ape/sh", oty); if(pid == 0) { execl(cmd, "sh", "-c", s, 0); _exit(1); --- /sys/src/cmd/cpp/nlist.c Sat May 21 23:40:53 2005 +++ /sys/src/cmd/cpp/nlist.c Sat May 21 23:40:49 2005 @@ -83,7 +83,7 @@ * (Note that includelist is searched from high end to low) */ if ((objtype = getenv("objtype"))){ - sprintf(nbuf, "/%s/include", objtype); + snprintf(nbuf, sizeof(nbuf), "/%s/include", objtype); includelist[1].file = nbuf; includelist[1].always = 1; } else { --- /sys/src/cmd/gs/jpeg/jmemdos.c Sat May 21 23:42:17 2005 +++ /sys/src/cmd/gs/jpeg/jmemdos.c Sat May 21 23:42:11 2005 @@ -144,7 +144,7 @@ *ptr++ = '\\'; /* append backslash if not in env variable */ /* Append a suitable file name */ next_file_num++; /* advance counter */ - sprintf(ptr, "JPG%03d.TMP", next_file_num); + snprintf(ptr, strlen(ptr), "JPG%03d.TMP", next_file_num); /* Probe to see if file name is already in use */ if ((tfile = fopen(fname, READ_BINARY)) == NULL) break; --- /sys/src/cmd/lp/lpdsend.c Sat May 21 23:43:41 2005 +++ /sys/src/cmd/lp/lpdsend.c Sat May 21 23:43:36 2005 @@ -231,15 +231,15 @@ if(cp == 0){ if(defnet==0){ if(defsrv) - sprintf(addr, "net!%s!%s", linear, defsrv); + snprintf(addr, sizeof(addr), "net!%s!%s", linear, defsrv); else - sprintf(addr, "net!%s", linear); + snprintf(addr, sizeof(addr), "net!%s", linear); } else { if(defsrv) - sprintf(addr, "%s!%s!%s", defnet, linear, defsrv); + snprintf(addr, sizeof(addr), "%s!%s!%s", defnet, linear, defsrv); else - sprintf(addr, "%s!%s", defnet, linear); + snprintf(addr, sizeof(addr), "%s!%s", defnet, linear); } return addr; } --- /sys/src/cmd/awd.c Sat May 21 23:45:08 2005 +++ /sys/src/cmd/awd.c Sat May 21 23:45:05 2005 @@ -4,31 +4,23 @@ void main(int argc, char **argv) { - int fd, n, m; - char buf[1024], dir[512], *str; + int fd, n; + char dir[512], *str; fd = open("/dev/acme/ctl", OWRITE); if(fd < 0) exits(0); getwd(dir, 512); - strcpy(buf, "name "); - strcpy(buf+5, dir); - n = strlen(buf); - if(n>0 && buf[n-1]!='/') - buf[n++] = '/'; - buf[n++] = '-'; + fprint(fd, "name %s", dir); + n = strlen(dir); + if(n>0 && dir[n-1]!='/') + fprint(fd, "/"); + fprint(fd, "-"); if(argc > 1) str = argv[1]; else str = "rc"; - m = strlen(str); - strcpy(buf+n, str); - n += m; - buf[n++] = '\n'; - write(fd, buf, n); - strcpy(buf, "dumpdir "); - strcpy(buf+8, dir); - strcat(buf, "\n"); - write(fd, buf, strlen(buf)); + fprint(fd, "%s\n", str); + fprint(fd, "dumpdir %s\n", dir); exits(0); } --- /sys/src/cmd/history.c Sat May 21 23:46:41 2005 +++ /sys/src/cmd/history.c Sat May 21 23:46:37 2005 @@ -97,7 +97,7 @@ ndump = "dump"; tm = localtime(time(0)); - sprint(buf, "/n/%s/%.4d/", ndump, tm->year+1900); + snprint(buf, sizeof(buf), "/n/%s/%.4d/", ndump, tm->year+1900); if(access(buf, AREAD) < 0) { if(verb) print("mounting dump %s\n", ndump); @@ -124,7 +124,7 @@ else{ print("%s %s %lld [%s]\n", prtime(dir->mtime), file, dir->length, dir->muid); started = 1; - strcpy(pair[1], file); + strncpy(pair[1], file, sizeof(pair[1])); } free(dir); otime = starttime(sflag); --- /sys/src/cmd/import.c Sat May 21 23:48:17 2005 +++ /sys/src/cmd/import.c Sat May 21 23:48:13 2005 @@ -333,7 +333,7 @@ if ((s = strchr(newport, '!')) == nil) sysfatal("filter: illegally formatted port %s\n", newport); - strcpy(buf, netmkaddr(host, "tcp", "0")); + strncpy(buf, netmkaddr(host, "tcp", "0"), sizeof(buf)); pbuf = strrchr(buf, '!'); strcpy(pbuf, s); --- /sys/src/cmd/yacc.c Sat May 21 23:50:10 2005 +++ /sys/src/cmd/yacc.c Sat May 21 23:49:58 2005 @@ -2111,26 +2111,26 @@ char buf[256]; if(vflag) { - sprint(buf, "%s.%s", stem, FILEU); + snprint(buf, sizeof(buf), "%s.%s", stem, FILEU); foutput = Bopen(buf, OWRITE); if(foutput == 0) error("cannot open %s", buf); } if(yydebug) { - sprint(buf, "%s.%s", stem, FILEDEBUG); + snprint(buf, sizeof(buf), "%s.%s", stem, FILEDEBUG); if((fdebug = Bopen(buf, OWRITE)) == 0) error("can't open %s", buf); } if(dflag) { - sprint(buf, "%s.%s", stem, FILED); + snprint(buf, sizeof(buf), "%s.%s", stem, FILED); fdefine = Bopen(buf, OWRITE); if(fdefine == 0) error("can't create %s", buf); } if(ytab == 0) - sprint(buf, "%s.%s", stem, OFILE); + snprint(buf, sizeof(buf), "%s.%s", stem, OFILE); else - strcpy(buf, ytabc); + strncpy(buf, ytabc, sizeof(buf)); ftable = Bopen(buf, OWRITE); if(ftable == 0) error("cannot open table file %s", buf); --- /sys/src/cmd/split.c Sat May 21 23:51:53 2005 +++ /sys/src/cmd/split.c Sat May 21 23:51:49 2005 @@ -116,8 +116,7 @@ fprint(2, "split: file %szz not split\n",stem); canopen = 0; } else { - strcpy(name, stem); - strcat(name, suff); + snprint(name, sizeof(name), "%s%s", stem, suff); if(++suff[1] > 'z') suff[1] = 'a', ++suff[0]; openf(); @@ -131,7 +130,7 @@ if(match[1].sp) { int len = match[1].ep - match[1].sp; strncpy(name, match[1].sp, len); - strcpy(name+len, suffix); + strncpy(name+len, suffix, sizeof(name) - len); openf(); return 1; } --- /sys/src/cmd/srvfs.c Sat May 21 23:53:40 2005 +++ /sys/src/cmd/srvfs.c Sat May 21 23:53:37 2005 @@ -78,7 +78,7 @@ fprint(2, "not OK (%d): %s\n", n, buf); exits("OK"); } - if(argv[0][0] == '/') + if(argv[0] != nil && argv[0][0] == '/') strcpy(buf, argv[0]); else sprint(buf, "/srv/%s", argv[0]);