Diff below makes the calls to _malloc_init() from inside libc go direct, while leaving malloc_init() callable from outside for libpthread, eliminating the overridable PLT entry for _malloc_init.
ok? With the harsh light of California beating down on me, I now wonder if we should have instead had libc provide a "_malloc_make_me_mt()" routine that knows how to frob the normally-made-readonly mopts bits, but a) can only set the malloc_mt flag, and b) blocks all signals while doing so. Would that be less of a target for exploits? Anyway. I only caught this when I saw it while ltrace'ing something unrelated, which is a bad way to realize you missed something. My apologies to otto@ and everyone following OpenBSD for not catching this earlier. I don't have a firm idea on how to prevent this sort of thing in the future yet; suggestions? Maybe the libc.so.* build should have a check that matches a regexp against the overridable symbols and fails if an unexpected symbol is present? Mind you, that check is difficult to write on mips64 and and a couple other archs due to arch weirdness, but maybe it's Good Enough if it works on x86, sparc64, and arm? Philip Guenther Index: include/thread_private.h =================================================================== RCS file: /data/src/openbsd/src/lib/libc/include/thread_private.h,v retrieving revision 1.28 diff -u -p -r1.28 thread_private.h --- include/thread_private.h 1 Sep 2016 10:41:02 -0000 1.28 +++ include/thread_private.h 11 Sep 2016 05:06:29 -0000 @@ -9,6 +9,9 @@ #define _MALLOC_MUTEXES 4 void _malloc_init(int); +#ifdef __LIBC__ +PROTO_NORMAL(_malloc_init); +#endif /* __LIBC__ */ /* * The callbacks needed by libc to handle the threaded case. Index: stdlib/malloc.c =================================================================== RCS file: /data/src/openbsd/src/lib/libc/stdlib/malloc.c,v retrieving revision 1.195 diff -u -p -r1.195 malloc.c --- stdlib/malloc.c 1 Sep 2016 10:41:02 -0000 1.195 +++ stdlib/malloc.c 11 Sep 2016 05:06:47 -0000 @@ -1226,6 +1226,7 @@ _malloc_init(int from_rthreads) mprotect(&malloc_readonly, sizeof(malloc_readonly), PROT_READ); _MALLOC_UNLOCK(0); } +DEF_STRONG(_malloc_init); void * malloc(size_t size)