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 @@ -616,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) @@ -736,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); @@ -765,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); } @@ -383,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" @@ -399,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);