diff --git a/Makefile b/Makefile index f33f88ea..8987d75c 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,10 @@ ifeq (,$(filter $(CONFIG_SELF_INIT),true false)) $(error CONFIG_SELF_INIT must be true or false) endif +ifeq (,$(filter $(CONFIG_UNSET_RTLD_DEEPBIND),true false)) + $(error CONFIG_UNSET_RTLD_DEEPBIND must be true or false) +endif + CPPFLAGS += \ -DCONFIG_SEAL_METADATA=$(CONFIG_SEAL_METADATA) \ -DZERO_ON_FREE=$(CONFIG_ZERO_ON_FREE) \ @@ -108,7 +112,8 @@ CPPFLAGS += \ -DCONFIG_CLASS_REGION_SIZE=$(CONFIG_CLASS_REGION_SIZE) \ -DN_ARENA=$(CONFIG_N_ARENA) \ -DCONFIG_STATS=$(CONFIG_STATS) \ - -DCONFIG_SELF_INIT=$(CONFIG_SELF_INIT) + -DCONFIG_SELF_INIT=$(CONFIG_SELF_INIT) \ + -DCONFIG_UNSET_RTLD_DEEPBIND=$(CONFIG_UNSET_RTLD_DEEPBIND) $(OUT)/libhardened_malloc$(SUFFIX).so: $(OBJECTS) | $(OUT) $(CC) $(CFLAGS) $(LDFLAGS) -shared $^ $(LDLIBS) -o $@ diff --git a/README.md b/README.md index 7d4f941f..14297658 100644 --- a/README.md +++ b/README.md @@ -279,6 +279,13 @@ The following boolean configuration options are available: hardware, which may become drastically lower in the future. Whether or not this feature is enabled, the metadata is all contained within an isolated memory region with high entropy random guard regions around it. +* `CONFIG_UNSET_RTLD_DEEPBIND`: `true` or `false` (default) to control whether a + `dlopen` wrapper is included to improve compatibility on glibc-based systems. + When enabled, the wrapper unsets the `RTLD_DEEPBIND` flag to ensure libraries + loaded via `dlopen` see the preloaded `libhardened_malloc.so` symbols, + preventing allocator mixing and related crashes or partial security bypasses. + That's useful for PHP extensions, browser plugins, and other modular software. + This option has no effect on non-glibc systems (e.g., musl, Bionic). The following integer configuration options are available: diff --git a/config/default.mk b/config/default.mk index 71b1cc42..e6f32342 100644 --- a/config/default.mk +++ b/config/default.mk @@ -21,3 +21,4 @@ CONFIG_CLASS_REGION_SIZE := 34359738368 # 32GiB CONFIG_N_ARENA := 4 CONFIG_STATS := false CONFIG_SELF_INIT := true +CONFIG_UNSET_RTLD_DEEPBIND := false diff --git a/config/light.mk b/config/light.mk index 88a0e1f5..d6e23755 100644 --- a/config/light.mk +++ b/config/light.mk @@ -21,3 +21,4 @@ CONFIG_CLASS_REGION_SIZE := 34359738368 # 32GiB CONFIG_N_ARENA := 4 CONFIG_STATS := false CONFIG_SELF_INIT := true +CONFIG_UNSET_RTLD_DEEPBIND := false diff --git a/h_malloc.c b/h_malloc.c index 58ae55e8..d3846902 100644 --- a/h_malloc.c +++ b/h_malloc.c @@ -2199,3 +2199,18 @@ COLD EXPORT void h_malloc_disable_memory_tagging(void) { #endif } #endif + +#if CONFIG_UNSET_RTLD_DEEPBIND + +#if defined(__GLIBC__) +#include + +EXPORT void *dlopen(const char *filename, int flags) +{ + void * (*original_dlopen)(const char *, int) = dlsym(RTLD_NEXT, "dlopen"); + flags &= ~RTLD_DEEPBIND; + return original_dlopen(filename, flags); +} +#endif + +#endif // CONFIG_UNSET_RTLD_DEEPBIND