From 88cc22e2a08792701a13f838757de345ed1f50a8 Mon Sep 17 00:00:00 2001 From: Dapeng Gao Date: Thu, 6 Jun 2024 16:02:30 +0100 Subject: [PATCH] c18n: Set curthread->tcb to real TCB upon thread start When a pthread is created, the TCB is allocated in _tcb_ctor by calling _rtld_allocate_tls(). In the case of c18n, RTLD allocates a real TCB and the new thread's stack lookup table and returns a fake wrapper TCB containing both. This is done so that when the thread is entered, it can readily install the stack lookup table contained in the fake TCB instead of having to allocate it---an action that cannot be performed without a stack lookup table in the first place. This commit fixes a mistake where the TCB field of curthread was still pointing to the fake wrapper TCB structure instead of the real TCB after thread start. --- lib/libthr/thread/thr_create.c | 6 ++++++ libexec/rtld-elf/rtld.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c index 71af366cb38d..c720fc8dbaaa 100644 --- a/lib/libthr/thread/thr_create.c +++ b/lib/libthr/thread/thr_create.c @@ -300,6 +300,12 @@ thread_start(struct pthread *curthread) bool restore_sigmask; #if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX) + /* + * At this point, curthread->tcb contains a fake wrapper TCB created by + * RTLD when the thread was created. The real TCB has now been installed + * by RTLD upon thread start, and the struct member should be set to it. + */ + curthread->tcb = _tcb_get(); restore_sigmask = true; #else restore_sigmask = curthread->attr.suspend == THR_CREATE_SUSPENDED; diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 8590ea58ffbb..9118a547aae6 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -6110,6 +6110,12 @@ _rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) ret = allocate_tls(globallist_curr(TAILQ_FIRST(&obj_list)), oldtls, tcbsize, tcbalign); #if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX) + /* + * Create a fake wrapper TCB containing pointers to the real TCB and stack + * lookup table. This is passed to the new thread as its initial TCB. Once + * the thread starts executing in _rtld_thread_start, it will set the + * thread's TCB to the real TCB after installing the stack lookup table. + */ if (C18N_ENABLED) ret = c18n_allocate_tcb(ret); #endif