diff --git a/usr.sbin/config/lang.l b/usr.sbin/config/lang.l --- a/usr.sbin/config/lang.l +++ b/usr.sbin/config/lang.l @@ -297,6 +297,8 @@ return (-1); } cfgfile_add(fnamebuf == NULL ? fname : fnamebuf); + free(fnamebuf); + in = malloc(sizeof(*in)); assert(in != NULL); in->in_prev = inclp; diff --git a/usr.sbin/config/main.cc b/usr.sbin/config/main.cc --- a/usr.sbin/config/main.cc +++ b/usr.sbin/config/main.cc @@ -555,6 +555,8 @@ fo = fopen(p, "w"); if (!fo) err(2, "%s", p); + free(p); + if (filebased) { /* Is needed, can be used for backward compatibility. */ configfile_filebased(cfg); @@ -614,9 +616,9 @@ if (!changed && from_sb.st_size != to_sb.st_size) changed++; - tsize = (size_t)from_sb.st_size; - if (!changed) { + tsize = (size_t)from_sb.st_size; + p = (char *)mmap(NULL, tsize, PROT_READ, MAP_SHARED, from_fd, (off_t)0); if (p == MAP_FAILED) @@ -686,8 +688,10 @@ if (hl) continue; printf("Removing stale header: %s\n", dp->d_name); - if (unlink(path(dp->d_name)) == -1) + p = path(dp->d_name); + if (unlink(p) == -1) warn("unlink %s", dp->d_name); + free(p); } (void)closedir(dirp); } @@ -732,7 +736,7 @@ struct stat st; FILE *fp, *pp; int error, osz, r; - unsigned int i, off, size, t1, t2, align; + size_t i, off, size, t1, t2, align; char *cmd, *o; r = open(file, O_RDONLY); @@ -761,8 +765,10 @@ free(cmd); (void)fread(o, osz, 1, pp); pclose(pp); - r = sscanf(o, "%d%d%d%d%d", &off, &size, &t1, &t2, &align); + r = sscanf(o, "%zu%zu%zu%zu%zu", &off, &size, &t1, &t2, &align); free(o); + if (size > SIZE_MAX - off || off + size > (size_t)st.st_size) + errx(EXIT_FAILURE, "%s: incoherent ELF headers", file); if (r != 5) errx(EXIT_FAILURE, "File %s doesn't contain configuration " "file. Either unsupported, or not compiled with " diff --git a/usr.sbin/config/mkoptions.cc b/usr.sbin/config/mkoptions.cc --- a/usr.sbin/config/mkoptions.cc +++ b/usr.sbin/config/mkoptions.cc @@ -263,7 +263,7 @@ if (op == NULL) err(EXIT_FAILURE, "calloc"); op->op_name = ns(name); - op->op_value = value ? ns(value) : NULL; + op->op_value = ns(value); SLIST_INSERT_HEAD(&op_head, op, op_next); } @@ -294,6 +294,7 @@ static char hbuf[MAXPATHLEN]; char nbuf[MAXPATHLEN]; struct opt_list *po; + char *fpath; /* "cannot happen"? the otab list should be complete.. */ (void)strlcpy(nbuf, "options.h", sizeof(nbuf)); @@ -305,7 +306,9 @@ } } - (void)strlcpy(hbuf, path(nbuf), sizeof(hbuf)); + fpath = path(nbuf); + (void)strlcpy(hbuf, fpath, sizeof(hbuf)); + free(fpath); return (hbuf); } @@ -380,8 +383,10 @@ } optname = ns(wd); wd = get_word(fp); - if (wd.eof()) - return (1); + if (wd.eof()) { + free(optname); + break; + } if (wd.eol()) { if (flags) { fprintf(stderr, "%s: compat file requires two" @@ -396,10 +401,18 @@ } else { val = ns(wd); } - if (flags == 0) + + if (flags == 0) { + /* + * insert_option takes possession of `optname` in the + * new option instead of making yet another copy. + */ insert_option(fname, optname, val); - else + } else { update_option(optname, val, flags); + free(optname); + optname = NULL; + } } (void)fclose(fp); return (1);