Skip to content

Commit 81ac8e5

Browse files
i#7293 print crash: Increase privload tcb size to fix crashes (#7294)
Increases the private TLS "tcb_size" from 0x970 to 0x1000, which fixes crashes in glibc code like this with an offset larger than 0x970 on a call to fprintf by a client on Ubuntu 22: ``` (gdb) bt at ./libio/libioP.h:947 <fprintf from client here> => 0x00007ffdf70909ff <+15>: mov %fs:0x972,%al _sigfault = {si_addr = 0x7ffdf78a4072 7ffdf78a2000-7ffdf78a4000 rw-p 00000000 00:00 0 7ffdf78a4000-7ffdf78a6000 ---p 00000000 00:00 0 ``` This fixes the following tests which failed on Ubuntu 22: + client.destructor + client.file_io + code_api,satisfy_w_xor_x|client.file_io + sample.memtrace_simple_repstr + sample.memtrace_simple_repstr + sample.memtrace_simple + sample.memval_simple + sample.memval_simple_scattergather + sample.instrace_simple + sample.callstack + sample.memtrace_x86_text + sample.instrace_x86_text + tool.drcachesim.phys_SUDO + tool.drcacheoff.phys_SUDO + tool.drcacheoff.phys_nopriv This fixes a crash in this test, but it still fails due to the internal isa mode error hit in other Ubuntu22 tests (not yet filed separately: currently under #7270): + tool.drcachesim.phys-threads_SUDO Issue: #7270, #7293 Fixes #7293
1 parent 3248e72 commit 81ac8e5

1 file changed

Lines changed: 12 additions & 8 deletions

File tree

core/unix/loader_linux.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* *******************************************************************************
2-
* Copyright (c) 2011-2020 Google, Inc. All rights reserved.
2+
* Copyright (c) 2011-2025 Google, Inc. All rights reserved.
33
* Copyright (c) 2011 Massachusetts Institute of Technology All rights reserved.
44
* *******************************************************************************/
55

@@ -133,9 +133,11 @@ static size_t client_tls_size = 2 * 4096;
133133
* The "lea -0x900(%rax,%rbx,1),%rbx" instruction computes the thread pointer to
134134
* install. The allocator used by the loader has no headers, so we don't have a
135135
* good way to guess how big this allocation was. Instead we use this estimate.
136+
* For Ubuntu22 glibc 2.38, the size is 0x9c0; we use 0x1000 to cover future
137+
* expansion.
136138
*/
137139
/* On A32, the pthread is put before tcbhead instead tcbhead being part of pthread */
138-
static size_t tcb_size = IF_X64_ELSE(0x900, 0x490);
140+
static size_t tcb_size_estimate = IF_X64_ELSE(0x1000, 0x490);
139141

140142
/* thread contol block header type from
141143
* - sysdeps/x86_64/nptl/tls.h
@@ -440,7 +442,8 @@ privload_tls_init(void *app_tp)
440442
app_tp);
441443
dr_tp = heap_mmap(client_tls_alloc_size, MEMPROT_READ | MEMPROT_WRITE,
442444
VMM_SPECIAL_MMAP | VMM_PER_THREAD);
443-
ASSERT(APP_LIBC_TLS_SIZE + TLS_PRE_TCB_SIZE + tcb_size <= client_tls_alloc_size);
445+
ASSERT(APP_LIBC_TLS_SIZE + TLS_PRE_TCB_SIZE + tcb_size_estimate <=
446+
client_tls_alloc_size);
444447
#if defined(AARCHXX) || defined(RISCV64)
445448
/* GDB reads some pthread members (e.g., pid, tid), so we must make sure
446449
* the size and member locations match to avoid gdb crash.
@@ -454,7 +457,7 @@ privload_tls_init(void *app_tp)
454457
dr_tp = dr_tp + TLS_PRE_TCB_SIZE + sizeof(tcb_head_t);
455458
dr_tcb = (tcb_head_t *)(dr_tp - sizeof(tcb_head_t));
456459
#else
457-
dr_tp = dr_tp + client_tls_alloc_size - tcb_size;
460+
dr_tp = dr_tp + client_tls_alloc_size - tcb_size_estimate;
458461
dr_tcb = (tcb_head_t *)dr_tp;
459462
#endif
460463
LOG(GLOBAL, LOG_LOADER, 2, "%s: adjust thread pointer to " PFX "\n", __FUNCTION__,
@@ -465,13 +468,13 @@ privload_tls_init(void *app_tp)
465468
if (app_tp != NULL &&
466469
!safe_read_ex(
467470
app_tp - APP_LIBC_TLS_SIZE - TLS_PRE_TCB_SIZE IF_RISCV64(-sizeof(tcb_head_t)),
468-
APP_LIBC_TLS_SIZE + TLS_PRE_TCB_SIZE + tcb_size,
471+
APP_LIBC_TLS_SIZE + TLS_PRE_TCB_SIZE + tcb_size_estimate,
469472
dr_tp - APP_LIBC_TLS_SIZE - TLS_PRE_TCB_SIZE IF_RISCV64(-sizeof(tcb_head_t)),
470473
&tls_bytes_read)) {
471474
LOG(GLOBAL, LOG_LOADER, 2,
472475
"%s: read failed, tcb was 0x%lx bytes "
473476
"instead of 0x%lx\n",
474-
__FUNCTION__, tls_bytes_read - APP_LIBC_TLS_SIZE, tcb_size);
477+
__FUNCTION__, tls_bytes_read - APP_LIBC_TLS_SIZE, tcb_size_estimate);
475478
#if defined(AARCHXX) || defined(RISCV64)
476479
} else {
477480
dr_pthread_t *dp =
@@ -485,7 +488,8 @@ privload_tls_init(void *app_tp)
485488
* + our over-estimate crosses a page boundary (our estimate is for latest
486489
* libc and is larger than on older libc versions): i#855.
487490
*/
488-
ASSERT(tls_info.offset <= client_tls_alloc_size - TLS_PRE_TCB_SIZE - tcb_size);
491+
ASSERT(tls_info.offset <=
492+
client_tls_alloc_size - TLS_PRE_TCB_SIZE - tcb_size_estimate);
489493
#ifdef X86
490494
/* Update two self pointers. */
491495
dr_tcb->tcb = dr_tcb;
@@ -519,7 +523,7 @@ privload_tls_exit(void *dr_tp)
519523
#ifdef RISCV64
520524
dr_tp = dr_tp - TLS_PRE_TCB_SIZE - sizeof(tcb_head_t);
521525
#else
522-
dr_tp = dr_tp + tcb_size - client_tls_alloc_size;
526+
dr_tp = dr_tp + tcb_size_estimate - client_tls_alloc_size;
523527
#endif
524528
heap_munmap(dr_tp, client_tls_alloc_size, VMM_SPECIAL_MMAP | VMM_PER_THREAD);
525529
}

0 commit comments

Comments
 (0)