Skip to content

Commit b97a7b9

Browse files
committed
Fix read 32 bits accesses to modules to be unaligned
Modules can be unaligned when they are loaded from a binary and reads should therefore be unaligned. This yielded a crash on arm32v7 CI. Also update arm32v7 CI to use bookworm debian image Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent 65482c8 commit b97a7b9

File tree

4 files changed

+33
-32
lines changed

4 files changed

+33
-32
lines changed

.github/workflows/build-and-test-other.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ jobs:
9494
9595
- arch: "arm32v7"
9696
platform: "arm/v7"
97-
tag: "bullseye"
97+
tag: "bookworm"
9898
# -D_FILE_OFFSET_BITS=64 is required for making atomvm:posix_readdir/1 test work
9999
# otherwise readdir will fail due to 64 bits inode numbers with 32 bit ino_t
100100
cflags: "-mcpu=cortex-a7 -mfloat-abi=hard -O2 -mthumb -mthumb-interwork -D_FILE_OFFSET_BITS=64"

src/libAtomVM/iff.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void scan_iff(const void *iff_binary, int buf_size, unsigned long *offsets, unsi
5050

5151
int current_pos = 12;
5252

53-
uint32_t iff_size = READ_32_ALIGNED(data + 4);
53+
uint32_t iff_size = READ_32_UNALIGNED(data + 4);
5454
int file_size = iff_size;
5555
if (UNLIKELY(buf_size < file_size)) {
5656
fprintf(stderr, "error: buffer holding IFF is smaller than IFF size: %i\n", buf_size);

src/libAtomVM/module.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ static void module_parse_line_table(Module *mod, const uint8_t *data, size_t len
6464

6565
static enum ModuleLoadResult module_populate_atoms_table(Module *this_module, uint8_t *table_data, GlobalContext *glb)
6666
{
67-
int atoms_count = READ_32_ALIGNED(table_data + 8);
67+
int atoms_count = READ_32_UNALIGNED(table_data + 8);
68+
6869
const char *current_atom = (const char *) table_data + 12;
6970

7071
this_module->local_atoms_to_global_table = calloc(atoms_count + 1, sizeof(int));
@@ -85,7 +86,7 @@ static enum ModuleLoadResult module_populate_atoms_table(Module *this_module, ui
8586

8687
static enum ModuleLoadResult module_build_imported_functions_table(Module *this_module, uint8_t *table_data, GlobalContext *glb)
8788
{
88-
int functions_count = READ_32_ALIGNED(table_data + 8);
89+
int functions_count = READ_32_UNALIGNED(table_data + 8);
8990

9091
this_module->imported_funcs = calloc(functions_count, sizeof(struct ExportedFunction *));
9192
if (IS_NULL_PTR(this_module->imported_funcs)) {
@@ -94,11 +95,11 @@ static enum ModuleLoadResult module_build_imported_functions_table(Module *this_
9495
}
9596

9697
for (int i = 0; i < functions_count; i++) {
97-
int local_module_atom_index = READ_32_ALIGNED(table_data + i * 12 + 12);
98-
int local_function_atom_index = READ_32_ALIGNED(table_data + i * 12 + 4 + 12);
98+
int local_module_atom_index = READ_32_UNALIGNED(table_data + i * 12 + 12);
99+
int local_function_atom_index = READ_32_UNALIGNED(table_data + i * 12 + 4 + 12);
99100
AtomString module_atom = module_get_atom_string_by_id(this_module, local_module_atom_index, glb);
100101
AtomString function_atom = module_get_atom_string_by_id(this_module, local_function_atom_index, glb);
101-
uint32_t arity = READ_32_ALIGNED(table_data + i * 12 + 8 + 12);
102+
uint32_t arity = READ_32_UNALIGNED(table_data + i * 12 + 8 + 12);
102103

103104
const struct ExportedFunction *bif = bif_registry_get_handler(module_atom, function_atom, arity);
104105

@@ -130,13 +131,13 @@ static enum ModuleLoadResult module_build_imported_functions_table(Module *this_
130131
void module_get_imported_function_module_and_name(const Module *this_module, int index, AtomString *module_atom, AtomString *function_atom, GlobalContext *glb)
131132
{
132133
const uint8_t *table_data = (const uint8_t *) this_module->import_table;
133-
int functions_count = READ_32_ALIGNED(table_data + 8);
134+
int functions_count = READ_32_UNALIGNED(table_data + 8);
134135

135136
if (UNLIKELY(index > functions_count)) {
136137
AVM_ABORT();
137138
}
138-
int local_module_atom_index = READ_32_ALIGNED(table_data + index * 12 + 12);
139-
int local_function_atom_index = READ_32_ALIGNED(table_data + index * 12 + 4 + 12);
139+
int local_module_atom_index = READ_32_UNALIGNED(table_data + index * 12 + 12);
140+
int local_function_atom_index = READ_32_UNALIGNED(table_data + index * 12 + 4 + 12);
140141
*module_atom = module_get_atom_string_by_id(this_module, local_module_atom_index, glb);
141142
*function_atom = module_get_atom_string_by_id(this_module, local_function_atom_index, glb);
142143
}
@@ -146,11 +147,11 @@ bool module_get_function_from_label(Module *this_module, int label, AtomString *
146147
{
147148
int best_label = -1;
148149
const uint8_t *export_table_data = (const uint8_t *) this_module->export_table;
149-
int exports_count = READ_32_ALIGNED(export_table_data + 8);
150+
int exports_count = READ_32_UNALIGNED(export_table_data + 8);
150151
for (int export_index = exports_count - 1; export_index >= 0; export_index--) {
151-
int fun_atom_index = READ_32_ALIGNED(export_table_data + (export_index * 12) + 12);
152-
int fun_arity = READ_32_ALIGNED(export_table_data + (export_index * 12) + 4 + 12);
153-
int fun_label = READ_32_ALIGNED(export_table_data + (export_index * 12) + 8 + 12);
152+
int fun_atom_index = READ_32_UNALIGNED(export_table_data + (export_index * 12) + 12);
153+
int fun_arity = READ_32_UNALIGNED(export_table_data + (export_index * 12) + 4 + 12);
154+
int fun_label = READ_32_UNALIGNED(export_table_data + (export_index * 12) + 8 + 12);
154155
if (fun_label <= label && best_label < fun_label) {
155156
best_label = fun_label;
156157
*arity = fun_arity;
@@ -159,11 +160,11 @@ bool module_get_function_from_label(Module *this_module, int label, AtomString *
159160
}
160161

161162
const uint8_t *local_table_data = (const uint8_t *) this_module->local_table;
162-
int locals_count = READ_32_ALIGNED(local_table_data + 8);
163+
int locals_count = READ_32_UNALIGNED(local_table_data + 8);
163164
for (int local_index = locals_count - 1; local_index >= 0; local_index--) {
164-
int fun_atom_index = READ_32_ALIGNED(local_table_data + (local_index * 12) + 12);
165-
int fun_arity = READ_32_ALIGNED(local_table_data + (local_index * 12) + 4 + 12);
166-
int fun_label = READ_32_ALIGNED(local_table_data + (local_index * 12) + 8 + 12);
165+
int fun_atom_index = READ_32_UNALIGNED(local_table_data + (local_index * 12) + 12);
166+
int fun_arity = READ_32_UNALIGNED(local_table_data + (local_index * 12) + 4 + 12);
167+
int fun_label = READ_32_UNALIGNED(local_table_data + (local_index * 12) + 8 + 12);
167168
if (fun_label <= label && best_label < fun_label) {
168169
best_label = fun_label;
169170
*arity = fun_arity;
@@ -180,7 +181,7 @@ bool module_get_function_from_label(Module *this_module, int label, AtomString *
180181
size_t module_get_exported_functions_count(Module *this_module)
181182
{
182183
const uint8_t *table_data = (const uint8_t *) this_module->export_table;
183-
size_t functions_count = READ_32_ALIGNED(table_data + 8);
184+
size_t functions_count = READ_32_UNALIGNED(table_data + 8);
184185
return functions_count;
185186
}
186187

@@ -190,10 +191,10 @@ uint32_t module_search_exported_function(Module *this_module, AtomString func_na
190191

191192
const uint8_t *table_data = (const uint8_t *) this_module->export_table;
192193
for (unsigned int i = 0; i < functions_count; i++) {
193-
AtomString function_atom = module_get_atom_string_by_id(this_module, READ_32_ALIGNED(table_data + i * 12 + 12), glb);
194-
int32_t arity = READ_32_ALIGNED(table_data + i * 12 + 4 + 12);
194+
AtomString function_atom = module_get_atom_string_by_id(this_module, READ_32_UNALIGNED(table_data + i * 12 + 12), glb);
195+
int32_t arity = READ_32_UNALIGNED(table_data + i * 12 + 4 + 12);
195196
if ((func_arity == arity) && atom_are_equals(func_name, function_atom)) {
196-
uint32_t label = READ_32_ALIGNED(table_data + i * 12 + 8 + 12);
197+
uint32_t label = READ_32_UNALIGNED(table_data + i * 12 + 8 + 12);
197198
return label;
198199
}
199200
}
@@ -208,8 +209,8 @@ term module_get_exported_functions(Module *this_module, Heap *heap, GlobalContex
208209

209210
const uint8_t *table_data = (const uint8_t *) this_module->export_table;
210211
for (unsigned int i = 0; i < functions_count; i++) {
211-
AtomString function_atom = module_get_atom_string_by_id(this_module, READ_32_ALIGNED(table_data + i * 12 + 12), glb);
212-
int32_t arity = READ_32_ALIGNED(table_data + i * 12 + 4 + 12);
212+
AtomString function_atom = module_get_atom_string_by_id(this_module, READ_32_UNALIGNED(table_data + i * 12 + 12), glb);
213+
int32_t arity = READ_32_UNALIGNED(table_data + i * 12 + 4 + 12);
213214
term function_tuple = term_alloc_tuple(2, heap);
214215
term_put_tuple_element(function_tuple, 0, globalcontext_existing_term_from_atom_string(glb, function_atom));
215216
term_put_tuple_element(function_tuple, 1, term_from_int(arity));
@@ -327,7 +328,7 @@ COLD_FUNC void module_destroy(Module *module)
327328
#ifdef WITH_ZLIB
328329
static void *module_uncompress_literals(const uint8_t *litT, int size)
329330
{
330-
unsigned int required_buf_size = READ_32_ALIGNED(litT + LITT_UNCOMPRESSED_SIZE_OFFSET);
331+
unsigned int required_buf_size = READ_32_UNALIGNED(litT + LITT_UNCOMPRESSED_SIZE_OFFSET);
331332

332333
uint8_t *outBuf = malloc(required_buf_size);
333334
if (IS_NULL_PTR(outBuf)) {
@@ -362,7 +363,7 @@ static void *module_uncompress_literals(const uint8_t *litT, int size)
362363

363364
static struct LiteralEntry *module_build_literals_table(const void *literalsBuf)
364365
{
365-
uint32_t terms_count = READ_32_ALIGNED(literalsBuf);
366+
uint32_t terms_count = READ_32_UNALIGNED(literalsBuf);
366367

367368
const uint8_t *pos = (const uint8_t *) literalsBuf + sizeof(uint32_t);
368369

src/libAtomVM/module.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ static inline term module_address(unsigned int module_index, unsigned int instru
323323
static inline uint32_t module_get_fun_freeze(const Module *this_module, int fun_index)
324324
{
325325
const uint8_t *table_data = (const uint8_t *) this_module->fun_table;
326-
int funs_count = READ_32_ALIGNED(table_data + 8);
326+
int funs_count = READ_32_UNALIGNED(table_data + 8);
327327

328328
if (UNLIKELY(fun_index >= funs_count)) {
329329
AVM_ABORT();
@@ -333,7 +333,7 @@ static inline uint32_t module_get_fun_freeze(const Module *this_module, int fun_
333333
// arity
334334
// label
335335
// index
336-
uint32_t n_freeze = READ_32_ALIGNED(table_data + fun_index * 24 + 16 + 12);
336+
uint32_t n_freeze = READ_32_UNALIGNED(table_data + fun_index * 24 + 16 + 12);
337337
// ouniq
338338

339339
return n_freeze;
@@ -342,17 +342,17 @@ static inline uint32_t module_get_fun_freeze(const Module *this_module, int fun_
342342
static inline void module_get_fun(const Module *this_module, int fun_index, uint32_t *label, uint32_t *arity, uint32_t *n_freeze)
343343
{
344344
const uint8_t *table_data = (const uint8_t *) this_module->fun_table;
345-
int funs_count = READ_32_ALIGNED(table_data + 8);
345+
int funs_count = READ_32_UNALIGNED(table_data + 8);
346346

347347
if (UNLIKELY(fun_index >= funs_count)) {
348348
AVM_ABORT();
349349
}
350350

351351
// fun atom index
352-
*arity = READ_32_ALIGNED(table_data + fun_index * 24 + 4 + 12);
353-
*label = READ_32_ALIGNED(table_data + fun_index * 24 + 8 + 12);
352+
*arity = READ_32_UNALIGNED(table_data + fun_index * 24 + 4 + 12);
353+
*label = READ_32_UNALIGNED(table_data + fun_index * 24 + 8 + 12);
354354
// index
355-
*n_freeze = READ_32_ALIGNED(table_data + fun_index * 24 + 16 + 12);
355+
*n_freeze = READ_32_UNALIGNED(table_data + fun_index * 24 + 16 + 12);
356356
// ouniq
357357
}
358358

0 commit comments

Comments
 (0)