Skip to content

Commit 6d8acb7

Browse files
committed
Avoid possible crash within libsanitizer.
We've successfully used libsanitizer for awhile with the undefined and alignment sanitizers, but with some other sanitizers (at least thread and hwaddress) it crashes due to internal recursion before it's fully initialized itself. It turns out that that's due to the "__ubsan_default_options" hack installed by commit f686ae8, and we can fix it by ensuring that __ubsan_default_options is built without any sanitizer instrumentation hooks. Reported-by: Emmanuel Sibi <emmanuelsibi.mec@gmail.com> Reported-by: Alexander Lakhin <exclusion@gmail.com> Diagnosed-by: Emmanuel Sibi <emmanuelsibi.mec@gmail.com> Fix-suggested-by: Jacob Champion <jacob.champion@enterprisedb.com> Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/F7543B04-E56C-4D68-A040-B14CCBAD38F1@gmail.com Discussion: https://postgr.es/m/dbf77bf7-6e54-ed8a-c4ae-d196eeb664ce@gmail.com Backpatch-through: 16
1 parent 500f646 commit 6d8acb7

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

src/backend/main/main.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -482,20 +482,29 @@ check_root(const char *progname)
482482
/*
483483
* At least on linux, set_ps_display() breaks /proc/$pid/environ. The
484484
* sanitizer library uses /proc/$pid/environ to implement getenv() as it wants
485-
* to work independent of libc. When just using undefined and alignment
486-
* sanitizers, the sanitizer library is only initialized when the first error
487-
* occurs, by which time we've often already called set_ps_display(),
488-
* preventing the sanitizer libraries from seeing the options.
485+
* to work independent of libc. Depending on which sanitizers are enabled,
486+
* the sanitizer library may not get initialized until after we've called
487+
* set_ps_display(), preventing the sanitizer from seeing environment-supplied
488+
* options.
489489
*
490490
* We can work around that by defining __ubsan_default_options, a weak symbol
491491
* libsanitizer uses to get defaults from the application, and return
492492
* getenv("UBSAN_OPTIONS"). But only if main already was reached, so that we
493493
* don't end up relying on a not-yet-working getenv().
494494
*
495+
* On the other hand, with different sanitizers enabled, libsanitizer can
496+
* call this so early that it's not fully initialized itself, resulting in
497+
* recursion and a core dump within libsanitizer. To prevent that, ensure
498+
* that this function is built without any sanitizer callbacks in it.
499+
*
495500
* As this function won't get called when not running a sanitizer, it doesn't
496501
* seem necessary to only compile it conditionally.
497502
*/
498503
const char *__ubsan_default_options(void);
504+
505+
#if __has_attribute(disable_sanitizer_instrumentation)
506+
__attribute__((disable_sanitizer_instrumentation))
507+
#endif
499508
const char *
500509
__ubsan_default_options(void)
501510
{

0 commit comments

Comments
 (0)