Skip to content

Commit bc997b5

Browse files
committed
Improve thread_exit syscall thread safety
Write the "stack flag" atomically and use a memory barrier.
1 parent 2b6293c commit bc997b5

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

‎src/trusted/service_runtime/nacl_syscall_common.c‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "native_client/src/trusted/service_runtime/nacl_syscall_common.h"
2323

24+
#include "native_client/src/include/concurrency_ops.h"
2425
#include "native_client/src/include/nacl_macros.h"
2526
#include "native_client/src/include/portability_process.h"
2627
#include "native_client/src/include/portability_string.h"
@@ -159,8 +160,6 @@ int32_t NaClSysExit(struct NaClAppThread *natp,
159160

160161
int32_t NaClSysThreadExit(struct NaClAppThread *natp,
161162
uint32_t stack_flag_addr) {
162-
uint32_t zero = 0;
163-
164163
NaClLog(4, "NaClSysThreadExit(0x%08"NACL_PRIxPTR", "
165164
"0x%08"NACL_PRIx32"\n",
166165
(uintptr_t) natp, stack_flag_addr);
@@ -170,10 +169,18 @@ int32_t NaClSysThreadExit(struct NaClAppThread *natp,
170169
*/
171170

172171
if (0 != stack_flag_addr) {
173-
if (!NaClCopyOutToUser(natp->nap, (uintptr_t) stack_flag_addr,
174-
&zero, sizeof zero)) {
175-
NaClLog(4, "NaClSysThreadExit: ignoring invalid stack_flag_addr\n");
172+
uintptr_t sys_addr = NaClUserToSysAddrRange(natp->nap,
173+
(uintptr_t) stack_flag_addr,
174+
4);
175+
if (sys_addr == kNaClBadAddress || sys_addr % 4 != 0) {
176+
NaClLog(LOG_ERROR, "NaClSysThreadExit: invalid stack_flag_addr\n");
177+
return -NACL_ABI_EINVAL;
176178
}
179+
NaClWriteMemoryBarrier();
180+
/* Not using CopyOutToUser since this should be atomic */
181+
NaClCopyTakeLock(natp->nap);
182+
*(uint32_t *) sys_addr = 0;
183+
NaClCopyDropLock(natp->nap);
177184
}
178185

179186
NaClAppThreadTeardown(natp);

0 commit comments

Comments
 (0)