diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2025-01-27 20:38:27 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2025-01-28 22:59:20 +0000 |
commit | 21502f9a926c7e0c24ce230bb029fde4bf570a14 (patch) | |
tree | 1c1f3bc62777a720412696dbbdf99a7fe725877f /lib | |
parent | 6ee34bca48a9e0867d46b24a78855e225d46ddda (diff) |
crtend: accurately check for the start of .ctors
For the hypothetic situation where crtbegin.o is not linked into the
binary, but crtend.o is, which results in the missing starting sentinel
in the ctors array, be careful to not iterate past the start of the
section.
Reviewed by: andrew, dim
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D48700
Diffstat (limited to 'lib')
-rw-r--r-- | lib/csu/common/crtend.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/lib/csu/common/crtend.c b/lib/csu/common/crtend.c index d9259729bb0e..bf25c1d836a9 100644 --- a/lib/csu/common/crtend.c +++ b/lib/csu/common/crtend.c @@ -21,7 +21,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> +#include <sys/types.h> #include "crt.h" typedef void (*crt_func)(void); @@ -45,15 +45,22 @@ static crt_func __DTOR_END__[] __section(".dtors") __used = { (crt_func)0 }; +extern const char startof_ctors[] __asm(".startof..ctors") + __weak_symbol __hidden; + static void __do_global_ctors_aux(void) { crt_func fn; + uintptr_t ctors_start; int n; + ctors_start = (uintptr_t)&startof_ctors; for (n = 1;; n++) { fn = __CTOR_END__[-n]; - if (fn == (crt_func)0 || fn == (crt_func)-1) + if (fn == (crt_func)0 || fn == (crt_func)-1 || + (ctors_start > 0 && + (uintptr_t)&__CTOR_END__[-n] < ctors_start)) break; fn(); } |