Get cosmo_dlopen() working better on System Five

Imported functions are now aspected with a trampoline that blocks
signals and changes the thread-local storage register. This means
bigger more complicated libraries can now be imported even though
the whole technique remains fundamentally unsafe.
This commit is contained in:
Justine Tunney 2023-11-15 10:48:31 -08:00
parent 3a470ed356
commit e4584ace81
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
6 changed files with 304 additions and 190 deletions

View file

@ -16,6 +16,9 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "ape/sections.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/stack.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/tls.h"
@ -33,6 +36,11 @@ privileged long __get_safe_size(long want, long extraspace) {
if (!__tls_enabled) return want;
struct PosixThread *pt;
struct CosmoTib *tib = __get_tls_privileged();
if (!IsAutoFrame((uintptr_t)tib >> 16) &&
!(__executable_start <= (const unsigned char *)tib &&
(const unsigned char *)tib < _end)) {
return want;
}
long bottom, sp = GetStackPointer();
if ((char *)sp >= tib->tib_sigstack_addr &&
(char *)sp <= tib->tib_sigstack_addr + tib->tib_sigstack_size) {

View file

@ -471,7 +471,6 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
p = b;
f = fmt;
e = p + n; // assume if n was negative e < p will be the case
tib = __tls_enabled ? __get_tls_privileged() : 0;
for (;;) {
for (;;) {
if (!(c = *f++) || c == '%') break;
@ -582,6 +581,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
goto FormatUnsigned;
case 'P':
tib = __tls_enabled ? __get_tls_privileged() : 0;
if (!(tib && (tib->tib_flags & TIB_FLAG_VFORKED))) {
x = __pid;
#ifdef __x86_64__
@ -607,6 +607,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
goto FormatDecimal;
case 'H':
tib = __tls_enabled ? __get_tls_privileged() : 0;
if (!(tib && (tib->tib_flags & TIB_FLAG_VFORKED))) {
if (tib) {
x = atomic_load_explicit(&tib->tib_tid, memory_order_relaxed);
@ -760,6 +761,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
case 'm': {
int e;
tib = __tls_enabled ? __get_tls_privileged() : 0;
if (!(e = tib ? tib->tib_errno : __errno) && sign == ' ') {
break;
} else {