From 266e836fda2d23634d0b15361bdacad132e3b6ad Mon Sep 17 00:00:00 2001 From: Dragos Iulian Argint Date: Mon, 28 Nov 2022 22:19:24 +0200 Subject: [PATCH] Avoid `uk_syscall_set_tid_address()` for main thread The uk_syscall_set_tid_address call should be used to set the main thread's tid address within some internal structures. At the moment, because it is called before the initialization of the scheduler, it fails causing the program to crash. A workaround for this behavior is to set the tid to 0 if the `__uk_sched_thread_current` variable is NULL, which means that the scheduler is not initialized. Signed-off-by: Dragos Iulian Argint Reviewed-by: Razvan Deaconescu Approved-by: Simon Kuenzer Tested-by: Unikraft CI GitHub-Closes: #29 --- __uk_init_tls.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/__uk_init_tls.c b/__uk_init_tls.c index 552d2b6..df13b95 100644 --- a/__uk_init_tls.c +++ b/__uk_init_tls.c @@ -118,14 +118,26 @@ static int __uk_init_tp(void *p) /* * The original musl code will invoke here a `SYS_set_tid_address` * syscall, to set the tid user space address in the Kernel. - * FIXME: Currently this does not return the tid assigned for the caller, - * it returns an error code (-95, -ENOTSUP) because posix_process_init has not been - * called at this stage, but will be called via uk_late_initcall. + * FIXME: Currently this can fail in two ways. The first way is a + * crash, which we avoid by checking if the current thread is NULL. + * The reason why we introduced this check is that the scheduler is not + * initialized when this function gets executed. + *`uk_syscall_r_set_tid_address()` will call `uk_syscall_r_gettid()` + * which may use the current uk_thread. If the uk_thread is NULL then + * it will crash when trying to access an invalid address. + * The second way it can fail is by returning an invalid tid. The call + * can return an error code (-95, -ENOTSUP) because posix_process_init + * has not been called at this stage, but will be called via uk_late_initcall. * It is not a really big problem right now. Since this is the main thread, * nobody should ever wait for it, and we can just assume thread id 0. + * The workaround for the moment is to set the tid to 0 whenever an error + * might happen. */ - td->tid = uk_syscall_r_set_tid_address(&td->tid); - if (td->tid < 0) { + if (uk_thread_current()) { + td->tid = uk_syscall_r_set_tid_address(&td->tid); + if (td->tid < 0) + td->tid = 0; + } else { td->tid = 0; } td->locale = &libc.global_locale; -- 2.39.5