Skip to content

Commit c9bf2da

Browse files
committed
libia2/memory_maps: move ia2_threads_metadata global definition to INIT_RUNTIME to have a once-mapped definition
This also requires moving the type definitions from `memory_maps.h` to `ia2.h`. Moreover, since `ia2.h` `#include`d `ia2_internal.h` (where `INIT_RUNTIME` is) at the beginning, the type definitions and everything would have to go before that, so I instead moved the `#include "ia2_internal.h"` to the end of `ia2.h` and hoisted the `#define _GNU_SOURCE` to the top of `ia2.h`.
1 parent 105655c commit c9bf2da

File tree

5 files changed

+74
-58
lines changed

5 files changed

+74
-58
lines changed

runtime/libia2/include/ia2.h

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
#define IA2_ENABLE 0
55
#endif
66

7-
// This include must come first so we define _GNU_SOURCE before including
8-
// standard headers. ia2_internal.h requires GNU-specific headers.
9-
#if IA2_ENABLE
10-
#include "ia2_internal.h"
7+
// This include must come first so we define
8+
//`_GNU_SOURCE` before including standard headers.
9+
//`ia2_internal.h` requires GNU-specific headers.
10+
#ifndef _GNU_SOURCE
11+
#define _GNU_SOURCE
1112
#endif
1213

1314
#include <errno.h>
1415
#include <stdint.h>
1516
#include <unistd.h>
17+
#include <pthread.h>
1618

1719
/// Do not wrap functions or function pointers in the following code.
1820
///
@@ -163,6 +165,60 @@
163165

164166
#define IA2_MAX_COMPARTMENTS 16
165167

168+
// Only enable this code that stores these addresses when debug logging is enabled.
169+
// This reduces the trusted codebase and avoids runtime overhead.
170+
// #if IA2_DEBUG_MEMORY
171+
172+
/// The data here is shared, so it should not be trusted for use as a pointer,
173+
/// but it can be used best effort for non-trusted purposes.
174+
///
175+
/// All fields should be used atomically.
176+
struct ia2_thread_metadata {
177+
pid_t tid;
178+
pthread_t thread;
179+
180+
/// The start function passed to `pthread_create`.
181+
void *(*start_fn)(void *arg);
182+
183+
/// The addresses of each compartment's stack for this thread.
184+
uintptr_t stack_addrs[IA2_MAX_COMPARTMENTS];
185+
186+
/// The addresses of each compartment's TLS region for this thread,
187+
/// except for compartment 1, which has split TLS regions (see below).
188+
uintptr_t tls_addrs[IA2_MAX_COMPARTMENTS];
189+
190+
/// The TLS region is split only for the first compartment,
191+
/// so we need two addresses for just that one.
192+
///
193+
/// Compartment 1's TLS region is split because there is a page of
194+
/// unprotected data for `ia2_stackptr_0` (in compartment 0), plus padding,
195+
/// as we don't have a general implementation of shared TLS yet,
196+
/// but `ia2_stackptr_0` is special-cased for now
197+
/// as it must be stored in TLS and unprotected.
198+
uintptr_t tls_addr_compartment1_first;
199+
uintptr_t tls_addr_compartment1_second;
200+
};
201+
202+
// It's much simpler to only support a static number of created threads,
203+
// especially because we want to have very few dependencies.
204+
// If a program needs more threads, you can just increase this number.
205+
#define IA2_MAX_THREADS 512
206+
207+
struct ia2_all_threads_metadata {
208+
/// This is the number of threads registered,
209+
/// and it is monotonically increasing by 1.
210+
///
211+
/// It may be transiently higher than `IA2_MAX_THREADS`,
212+
/// but will abort if that happens (other threads may be observe a higher value).
213+
_Atomic size_t num_threads;
214+
pid_t tids[IA2_MAX_THREADS];
215+
216+
/// Should be initialized to 0.
217+
struct ia2_thread_metadata thread_metadata[IA2_MAX_THREADS];
218+
};
219+
220+
// #endif // IA2_DEBUG_MEMORY
221+
166222
/// Convert a compartment pkey to a PKRU register value
167223
#define PKRU(pkey) (~((3U << (2 * pkey)) | 3))
168224

@@ -179,3 +235,7 @@ size_t ia2_get_pkey();
179235
#ifdef __cplusplus
180236
}
181237
#endif
238+
239+
#if IA2_ENABLE
240+
#include "ia2_internal.h"
241+
#endif

runtime/libia2/include/ia2_compartment_init.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
#include <string.h>
1111
#include <sys/mman.h>
1212

13-
#include <ia2_internal.h>
1413
#include <ia2.h>
14+
#include <ia2_internal.h>
1515

1616
#ifndef IA2_COMPARTMENT_LIBRARIES
1717
#define IA2_COMPARTMENT_LIBRARIES NULL

runtime/libia2/include/ia2_internal.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,14 @@ __attribute__((__noreturn__)) void ia2_reinit_stack_err(int i);
443443
init_stacks_and_setup_tls(); \
444444
REPEATB##n(setup_destructors_for_compartment, nop_macro); \
445445
mark_init_finished(); \
446-
}
446+
} \
447+
\
448+
/* All zeroed, so this should go in `.bss` */ \
449+
/* and only have pages lazily allocated. */ \
450+
struct ia2_all_threads_metadata ia2_threads_metadata IA2_SHARED_DATA = { \
451+
.num_threads = 0, \
452+
.thread_metadata = {0}, \
453+
};
447454

448455
#if IA2_VERBOSE
449456
#define ia2_log(fmt, ...) fprintf(stdout, "%s:" fmt, __func__, __VA_ARGS__)

runtime/libia2/memory_maps.c

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,10 @@
77
// This reduces the trusted codebase and avoids runtime overhead.
88
#if IA2_DEBUG_MEMORY
99

10-
// It's much simpler to only support a static number of created threads,
11-
// especially because we want to have very few dependencies.
12-
// If a program needs more threads, you can just increase this number.
13-
#define IA2_MAX_THREADS 512
14-
15-
struct ia2_all_threads_metadata {
16-
/// This is the number of threads registered,
17-
/// and it is monotonically increasing by 1.
18-
///
19-
/// It may be transiently higher than `IA2_MAX_THREADS`,
20-
/// but will abort if that happens (other threads may be observe a higher value).
21-
_Atomic size_t num_threads;
22-
pid_t tids[IA2_MAX_THREADS];
23-
24-
/// Should be initialized to 0.
25-
struct ia2_thread_metadata thread_metadata[IA2_MAX_THREADS];
26-
};
27-
2810
#define min(a, b) ((a) < (b) ? (a) : (b))
2911

3012
// All zeroed, so this should go in `.bss` and only have pages lazily allocated.
31-
static struct ia2_all_threads_metadata IA2_SHARED_DATA ia2_threads_metadata = {
32-
.num_threads = 0,
33-
.thread_metadata = {0},
34-
};
13+
extern struct ia2_all_threads_metadata ia2_threads_metadata;
3514

3615
struct ia2_thread_metadata *ia2_all_threads_metadata_new_for_current_thread(struct ia2_all_threads_metadata *const this) {
3716
const size_t thread = atomic_fetch_add(&this->num_threads, 1);

runtime/libia2/memory_maps.h

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,6 @@ void setup_thread_metadata(void);
1111
// This reduces the trusted codebase and avoids runtime overhead.
1212
#if IA2_DEBUG_MEMORY
1313

14-
/// The data here is shared, so it should not be trusted for use as a pointer,
15-
/// but it can be used best effort for non-trusted purposes.
16-
///
17-
/// All fields should be used atomically.
18-
struct ia2_thread_metadata {
19-
pid_t tid;
20-
pthread_t thread;
21-
22-
/// The start function passed to `pthread_create`.
23-
void *(*start_fn)(void *arg);
24-
25-
/// The addresses of each compartment's stack for this thread.
26-
uintptr_t stack_addrs[IA2_MAX_COMPARTMENTS];
27-
28-
/// The addresses of each compartment's TLS region for this thread,
29-
/// except for compartment 1, which has split TLS regions (see below).
30-
uintptr_t tls_addrs[IA2_MAX_COMPARTMENTS];
31-
32-
/// The TLS region is split only for the first compartment,
33-
/// so we need two addresses for just that one.
34-
///
35-
/// Compartment 1's TLS region is split because there is a page of
36-
/// unprotected data for `ia2_stackptr_0` (in compartment 0), plus padding,
37-
/// as we don't have a general implementation of shared TLS yet,
38-
/// but `ia2_stackptr_0` is special-cased for now
39-
/// as it must be stored in TLS and unprotected.
40-
uintptr_t tls_addr_compartment1_first;
41-
uintptr_t tls_addr_compartment1_second;
42-
};
43-
4414
/// Allocate and initialize a new `ia2_thread_metadata` for the current thread.
4515
/// Importantly, this may only be called once per thread.
4616
///

0 commit comments

Comments
 (0)