forked from openenclave/openenclave
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Set MUSL libc to multi-threaded mode
Fix bug where writing to stdout, stderr from multiple threads could cause memory corruption/crash. MUSL, by default, sets locks of stdout, stderr to -1 indicating that locking is not needed. libc.threaded is also set to 1. When reads and writes are performed from the standard streams, no locking is performed since there is only the main thread. The first time a program creates another thread, the pthread_create function sets the locks of stdout, stderr etc to 0 to indicate that locking ought to be done since the program now has more than one thread. Similarly, libc.threaded is also set to 1. For enclaves, threads are allocated before-hand via the enclave configuration. Each TCS corresponds to an enclave thread. These threads are not created via pthread_creat; they are pre-allocated at enclave creation time. Since no call to pthread_create is made, MUSL continues to think that there is only one thread. This results in memory corruption. The fix is to set state variables in MUSL during enclave initialization so that MUSL operates in multi-threaded mode. Signed-off-by: Anand Krishnamoorthi <[email protected]>
- Loading branch information
Showing
8 changed files
with
103 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright (c) Open Enclave SDK contributors. | ||
// Licensed under the MIT License. | ||
|
||
#ifndef _OE_INTERNAL_LIBC_INIT_H | ||
#define _OE_INTERNAL_LIBC_INIT_H | ||
|
||
#include <openenclave/internal/defs.h> | ||
|
||
OE_EXTERNC_BEGIN | ||
|
||
/* Callback for initializing libc */ | ||
void oe_libc_initialize(void); | ||
|
||
/* Test utility to check whether libc has been initialized */ | ||
bool oe_test_libc_is_initialized(void); | ||
|
||
OE_EXTERNC_END | ||
|
||
#endif /* _OE_INTERNAL_LIBC_INIT_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright (c) Open Enclave SDK contributors. | ||
// Licensed under the MIT License. | ||
|
||
#include <openenclave/enclave.h> | ||
#include <openenclave/internal/libc/init.h> | ||
#include "libc.h" | ||
#include "stdio_impl.h" | ||
|
||
void oe_libc_initialize(void) | ||
{ | ||
// No multi-threaded initialization needed for OP-TEE. | ||
} | ||
|
||
bool oe_test_libc_is_initialized(void) | ||
{ | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright (c) Open Enclave SDK contributors. | ||
// Licensed under the MIT License. | ||
|
||
#include <openenclave/enclave.h> | ||
#include <openenclave/internal/libc/init.h> | ||
#include "libc.h" | ||
#include "stdio_impl.h" | ||
|
||
void oe_libc_initialize(void) | ||
{ | ||
/* In MUSL, locks are initialized for standard streams the first time a | ||
thread is created, in pthread_create.c. | ||
Since OE has pre-allocated number of thread, pthread_create is too late | ||
to mark libc as multi threaded. Therefore, libc initialization is done | ||
here instead. This also allows oecore to control exactly when libc is | ||
initialized. | ||
*/ | ||
libc.threaded = 1; | ||
// MUSL also maintains libc.threads_minus_1 variable to keep track of | ||
// number of running threads. That variable is used to decide whether | ||
// locks are needed. OE, instead, always locks since it is not possible | ||
// to easily manage that variable from within oecore. | ||
libc.need_locks = 1; | ||
stdin->lock = 0; | ||
stdout->lock = 0; | ||
stderr->lock = 0; | ||
} | ||
|
||
bool oe_test_libc_is_initialized(void) | ||
{ | ||
return (libc.threaded == 1) && (libc.need_locks == 1) && | ||
(__atomic_load_n(&stdin->lock, __ATOMIC_SEQ_CST) >= 0) && | ||
(__atomic_load_n(&stdout->lock, __ATOMIC_SEQ_CST) >= 0) && | ||
(__atomic_load_n(&stderr->lock, __ATOMIC_SEQ_CST) >= 0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters