Looking into this a bit further, looks like someone else had found the
same leak with valgrind in 2015:
https://marc.info/?l=openbsd-tech&m=145104118706360&w=2
Inspired by the thread, I tried compiling a libc with _fwalk(fclose)
substituted for _fwalk(__sflush) in the stdio _cleanup() routine, but
curiously enough that didn't clear up the memory leak, though the new
code definitely did get executed (confirmed with gdb). So either the
leak is unexpectedly subtle or I'm making a dumb error.
False positives from the libc like this are irritating, but - as I just
learned - at least valgrind has suppression files just for this purpose
[1], so perhaps that's the right place to fix this.
Thanks for your trouble.
[1]: http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress