HomeFreeBSD

rtld/arm: fix initial-exec (IE) thread-local storage relocation

Description

rtld/arm: fix initial-exec (IE) thread-local storage relocation

net/frr[89] revealed an interesting edge-case on arm when dynamically
linking a shared library that declares more than one static TLS variable
with at least one using the "initial-exec" TLS model. In the case
of frr[89], this library was libfrr.so which essentially does the
following:

#include <stdio.h>

#include "lib.h"

static __thread int *a

		__attribute__((tls_model("initial-exec")));

void lib_test()
{

		static __thread int b = -1;

		printf("&a = %p\n", &a);
		printf(" a = %p\n", a);

		printf("\n");

		printf("&b = %p\n", &b);
		printf(" b = %d\n", b);

}

Allocates a file scoped static __thread pointer with
tls_model("initial-exec") and later a block scoped TLS int. Notice in
the above minimal reproducer, b == -1. The relocation process does
the wrong thing and ends up pointing both a and b at the same place
in memory.

The output of the above in the broken state is:

&a = 0x4009c018

	 a = 0xffffffff

&b = 0x4009c018

	 b = -1

With the patch applied, the output becomes:

&a = 0x4009c01c

	 a = 0x0

&b = 0x4009c018

	 b = -1

Reviewed by: kib
Approved by: kp (mentor)
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D42415/

(cherry picked from commit 98fd69f0090da73d9d0451bd769d7752468284c6)

Details

Provenance
rcmAuthored on Nov 3 2023, 12:56 PM
Parents
rG7951b4f4f99c: _utmx_op: don't recurse on chain busy
Branches
Unknown
Tags
Unknown