aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2025-01-27 20:38:27 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2025-01-28 22:59:20 +0000
commit21502f9a926c7e0c24ce230bb029fde4bf570a14 (patch)
tree1c1f3bc62777a720412696dbbdf99a7fe725877f /lib
parent6ee34bca48a9e0867d46b24a78855e225d46ddda (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.c11
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();
}