On Tue, 28 Nov 2017 05:52:25 +0000, Theo de Raadt wrote: > You could compare make build times. I suspect this will slightly > exceed the noise floor.
Without the patch, my fastest laptop (amd64, 8-core i7 @ 3.4 GHz) managed to $ make obj && make -j8 build in exactly 2359 seconds; with the patch applied, the same command happened to perform (insignificantly) faster, finishing in 2352 seconds. These were done on an otherwise completely idle system (not even cron(8) was running) and as the first executed command after a full reboot, with both /usr/src and /usr/obj mounted as mfs. As I was expecting, the performance impact of this diff appears to have been overestimated. A slightly improved version follows; further feedback is of course welcome. Index: asprintf.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/asprintf.c,v retrieving revision 1.25 diff -u -p -r1.25 asprintf.c --- asprintf.c 17 Mar 2017 14:53:08 -0000 1.25 +++ asprintf.c 30 Nov 2017 04:05:21 -0000 @@ -61,7 +61,7 @@ asprintf(char **str, const char *fmt, .. return (ret); err: - free(f._bf._base); + freezero(f._bf._base, f._bf._size); f._bf._base = NULL; *str = NULL; errno = ENOMEM; Index: fclose.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/fclose.c,v retrieving revision 1.10 diff -u -p -r1.10 fclose.c --- fclose.c 31 Aug 2015 02:53:57 -0000 1.10 +++ fclose.c 30 Nov 2017 04:05:21 -0000 @@ -51,7 +51,7 @@ fclose(FILE *fp) if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) r = EOF; if (fp->_flags & __SMBF) - free((char *)fp->_bf._base); + freezero(fp->_bf._base, fp->_bf._size); if (HASUB(fp)) FREEUB(fp); if (HASLB(fp)) Index: fmemopen.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/fmemopen.c,v retrieving revision 1.3 diff -u -p -r1.3 fmemopen.c --- fmemopen.c 31 Aug 2015 02:53:57 -0000 1.3 +++ fmemopen.c 30 Nov 2017 04:05:21 -0000 @@ -107,7 +107,7 @@ fmemopen_close_free(void *v) { struct state *st = v; - free(st->string); + freezero(st->string, st->size); free(st); return (0); Index: freopen.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/freopen.c,v retrieving revision 1.16 diff -u -p -r1.16 freopen.c --- freopen.c 21 Sep 2016 04:38:56 -0000 1.16 +++ freopen.c 30 Nov 2017 04:05:21 -0000 @@ -106,7 +106,7 @@ freopen(const char *file, const char *mo if (isopen && f != wantfd) (void) (*fp->_close)(fp->_cookie); if (fp->_flags & __SMBF) - free((char *)fp->_bf._base); + freezero(fp->_bf._base, fp->_bf._size); fp->_w = 0; fp->_r = 0; fp->_p = NULL; Index: local.h =================================================================== RCS file: /cvs/src/lib/libc/stdio/local.h,v retrieving revision 1.25 diff -u -p -r1.25 local.h --- local.h 23 May 2016 00:21:48 -0000 1.25 +++ local.h 30 Nov 2017 04:05:21 -0000 @@ -82,7 +82,7 @@ __END_HIDDEN_DECLS #define HASUB(fp) (_UB(fp)._base != NULL) #define FREEUB(fp) { \ if (_UB(fp)._base != (fp)->_ubuf) \ - free(_UB(fp)._base); \ + freezero(_UB(fp)._base, _UB(fp)._size); \ _UB(fp)._base = NULL; \ } @@ -91,7 +91,7 @@ __END_HIDDEN_DECLS */ #define HASLB(fp) ((fp)->_lb._base != NULL) #define FREELB(fp) { \ - free((char *)(fp)->_lb._base); \ + freezero((fp)->_lb._base, (fp)->_lb._size); \ (fp)->_lb._base = NULL; \ } Index: setvbuf.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/setvbuf.c,v retrieving revision 1.14 diff -u -p -r1.14 setvbuf.c --- setvbuf.c 21 Sep 2016 04:38:56 -0000 1.14 +++ setvbuf.c 30 Nov 2017 04:05:21 -0000 @@ -70,7 +70,7 @@ setvbuf(FILE *fp, char *buf, int mode, s fp->_r = fp->_lbfsize = 0; flags = fp->_flags; if (flags & __SMBF) - free(fp->_bf._base); + freezero(fp->_bf._base, fp->_bf._size); flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT | __SEOF); /* If setting unbuffered mode, skip all the hard work. */ Index: vasprintf.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/vasprintf.c,v retrieving revision 1.22 diff -u -p -r1.22 vasprintf.c --- vasprintf.c 17 Mar 2017 14:53:08 -0000 1.22 +++ vasprintf.c 30 Nov 2017 04:05:21 -0000 @@ -57,7 +57,7 @@ vasprintf(char **str, const char *fmt, _ return (ret); err: - free(f._bf._base); + freezero(f._bf._base, f._bf._size); f._bf._base = NULL; *str = NULL; errno = ENOMEM; Index: vfprintf.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/vfprintf.c,v retrieving revision 1.78 diff -u -p -r1.78 vfprintf.c --- vfprintf.c 21 Nov 2017 17:48:19 -0000 1.78 +++ vfprintf.c 30 Nov 2017 04:05:21 -0000 @@ -153,7 +153,7 @@ __sbprintf(FILE *fp, const char *fmt, va * string is null-terminated. */ static char * -__wcsconv(wchar_t *wcsarg, int prec) +__wcsconv(wchar_t *wcsarg, int prec, char *oconvbuf, size_t *convbuf_size) { mbstate_t mbs; char buf[MB_LEN_MAX]; @@ -191,18 +191,19 @@ __wcsconv(wchar_t *wcsarg, int prec) return (NULL); } } - if ((convbuf = malloc(nbytes + 1)) == NULL) + convbuf = recallocarray(oconvbuf, *convbuf_size, nbytes + 1, 1); + if (convbuf == NULL) return (NULL); + *convbuf_size = nbytes + 1; /* Fill the output buffer. */ p = wcsarg; memset(&mbs, 0, sizeof(mbs)); - if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p, - nbytes, &mbs)) == (size_t)-1) { - free(convbuf); + nbytes = wcsrtombs(convbuf, (const wchar_t **)&p, nbytes, &mbs); + if (nbytes == (size_t)-1) { + freezero(convbuf, *convbuf_size); return (NULL); } - convbuf[nbytes] = '\0'; return (convbuf); } #endif @@ -328,6 +329,7 @@ __vfprintf(FILE *fp, const char *fmt0, _ va_list orgap; /* original argument pointer */ #ifdef PRINTF_WIDE_CHAR char *convbuf; /* buffer for wide to multi-byte conversion */ + size_t convbuf_size; #endif /* @@ -845,8 +847,6 @@ fp_common: if (flags & LONGINT) { wchar_t *wcp; - free(convbuf); - convbuf = NULL; if ((wcp = GETARG(wchar_t *)) == NULL) { struct syslog_data sdata = SYSLOG_DATA_INIT; int save_errno = errno; @@ -857,7 +857,8 @@ fp_common: cp = "(null)"; } else { - convbuf = __wcsconv(wcp, prec); + convbuf = __wcsconv(wcp, prec, convbuf, + &convbuf_size); if (convbuf == NULL) { ret = -1; goto error; @@ -1077,7 +1078,7 @@ overflow: finish: #ifdef PRINTF_WIDE_CHAR - free(convbuf); + freezero(convbuf, convbuf_size); #endif #ifdef FLOATING_POINT if (dtoaresult) Index: vfwprintf.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/vfwprintf.c,v retrieving revision 1.19 diff -u -p -r1.19 vfwprintf.c --- vfwprintf.c 16 Nov 2017 08:16:03 -0000 1.19 +++ vfwprintf.c 30 Nov 2017 04:05:21 -0000 @@ -164,7 +164,7 @@ __xfputwc(wchar_t wc, FILE *fp) * To find out what happened check errno for ENOMEM, EILSEQ and EINVAL. */ static wchar_t * -__mbsconv(char *mbsarg, int prec) +__mbsconv(char *mbsarg, int prec, wchar_t *oconvbuf, size_t *convbuf_size) { mbstate_t mbs; wchar_t *convbuf, *wcp; @@ -205,9 +205,11 @@ __mbsconv(char *mbsarg, int prec) * converting at most `size' bytes of the input multibyte string to * wide characters for printing. */ - convbuf = calloc(insize + 1, sizeof(*convbuf)); + convbuf = recallocarray(oconvbuf, *convbuf_size, insize + 1, + sizeof(*convbuf)); if (convbuf == NULL) return (NULL); + *convbuf_size = insize + 1; wcp = convbuf; p = mbsarg; bzero(&mbs, sizeof(mbs)); @@ -221,7 +223,7 @@ __mbsconv(char *mbsarg, int prec) insize -= nconv; } if (nconv == (size_t)-1 || nconv == (size_t)-2) { - free(convbuf); + freezero(convbuf, *convbuf_size * sizeof(*convbuf)); return (NULL); } *wcp = '\0'; @@ -333,6 +335,7 @@ __vfwprintf(FILE * __restrict fp, const int nextarg; /* 1-based argument index */ va_list orgap; /* original argument pointer */ wchar_t *convbuf; /* buffer for multibyte to wide conversion */ + size_t convbuf_size; /* * Choose PADSIZE to trade efficiency vs. size. If larger printf @@ -678,8 +681,8 @@ reswitch: switch (ch) { prec = dtoaend - dtoaresult; if (expt == INT_MAX) ox[1] = '\0'; - free(convbuf); - cp = convbuf = __mbsconv(dtoaresult, -1); + cp = convbuf = __mbsconv(dtoaresult, -1, convbuf, + &convbuf_size); if (cp == NULL) goto error; ndig = dtoaend - dtoaresult; @@ -727,8 +730,8 @@ fp_begin: if (expt == 9999) expt = INT_MAX; } - free(convbuf); - cp = convbuf = __mbsconv(dtoaresult, -1); + cp = convbuf = __mbsconv(dtoaresult, -1, convbuf, + &convbuf_size); if (cp == NULL) goto error; ndig = dtoaend - dtoaresult; @@ -849,8 +852,8 @@ fp_common: mbsarg = "(null)"; } - free(convbuf); - convbuf = __mbsconv(mbsarg, prec); + convbuf = __mbsconv(mbsarg, prec, convbuf, + &convbuf_size); if (convbuf == NULL) { fp->_flags |= __SERR; goto error; @@ -1065,7 +1068,7 @@ overflow: ret = -1; finish: - free(convbuf); + freezero(convbuf, convbuf_size * sizeof(*convbuf)); #ifdef FLOATING_POINT if (dtoaresult) __freedtoa(dtoaresult); Index: vswprintf.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/vswprintf.c,v retrieving revision 1.6 diff -u -p -r1.6 vswprintf.c --- vswprintf.c 31 Aug 2015 02:53:57 -0000 1.6 +++ vswprintf.c 30 Nov 2017 04:05:21 -0000 @@ -64,13 +64,13 @@ vswprintf(wchar_t * __restrict s, size_t ret = __vfwprintf(&f, fmt, ap); if (ret < 0) { sverrno = errno; - free(f._bf._base); + freezero(f._bf._base, f._bf._size); errno = sverrno; return (-1); } if (ret == 0) { s[0] = L'\0'; - free(f._bf._base); + freezero(f._bf._base, f._bf._size); return (0); } *f._p = '\0'; @@ -81,7 +81,7 @@ vswprintf(wchar_t * __restrict s, size_t */ bzero(&mbs, sizeof(mbs)); nwc = mbsrtowcs(s, (const char **)&mbp, n, &mbs); - free(f._bf._base); + freezero(f._bf._base, f._bf._size); if (nwc == (size_t)-1) { errno = EILSEQ; return (-1); Index: vswscanf.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/vswscanf.c,v retrieving revision 1.3 diff -u -p -r1.3 vswscanf.c --- vswscanf.c 31 Aug 2015 02:53:57 -0000 1.3 +++ vswscanf.c 30 Nov 2017 04:05:21 -0000 @@ -70,7 +70,7 @@ vswscanf(const wchar_t * __restrict str, bzero(&mbs, sizeof(mbs)); strp = str; if ((mlen = wcsrtombs(mbstr, &strp, len, &mbs)) == (size_t)-1) { - free(mbstr); + freezero(mbstr, len); return (EOF); } if (mlen == len) @@ -82,7 +82,7 @@ vswscanf(const wchar_t * __restrict str, f._read = eofread; f._lb._base = NULL; r = __vfwscanf(&f, fmt, ap); - free(mbstr); + freezero(mbstr, len); return (r); } Regards, kshe