Skip to content

Commit b134785

Browse files
committed
Merge pull request atomvm#1601 from mat-hek/upstream-fix-posix-read
Fix nif_atomvm_posix_read GC bug We've been getting ASAN errors in the calls to `nif_atomvm_posix_read`, and it seems it's because when GC moves things around, it also moves what the `fd_obj_ptr` variable points to. The proposed solution is to move the GC before `enif_get_resource`. We haven't encountered the error after the fix, but please verify that it makes sense. These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 8bc200c + 0c8c1a5 commit b134785

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ memory error
6363
- Fix potential use after free with code generated from OTP <= 24
6464
- Fix `is_function/2` guard
6565
- Fixed segfault when calling `lists:reverse/1` (#1600)
66+
- Fixed nif_atomvm_posix_read GC bug
6667

6768
### Changed
6869

src/libAtomVM/posix_nifs.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,14 +362,17 @@ static term nif_atomvm_posix_read(Context *ctx, int argc, term argv[])
362362
VALIDATE_VALUE(count_term, term_is_integer);
363363
int count = term_to_int(count_term);
364364

365+
size_t size = term_binary_data_size_in_terms(count) + BINARY_HEADER_SIZE + TERM_BOXED_SUB_BINARY_SIZE + TUPLE_SIZE(2);
366+
if (UNLIKELY(memory_ensure_free_with_roots(ctx, size, argc, argv, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
367+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
368+
}
369+
365370
void *fd_obj_ptr;
371+
366372
if (UNLIKELY(!enif_get_resource(erl_nif_env_from_context(ctx), argv[0], glb->posix_fd_resource_type, &fd_obj_ptr))) {
367373
RAISE_ERROR(BADARG_ATOM);
368374
}
369375
struct PosixFd *fd_obj = (struct PosixFd *) fd_obj_ptr;
370-
if (UNLIKELY(memory_ensure_free_opt(ctx, term_binary_data_size_in_terms(count) + BINARY_HEADER_SIZE + TERM_BOXED_SUB_BINARY_SIZE + TUPLE_SIZE(2), MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
371-
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
372-
}
373376
term bin_term = term_create_uninitialized_binary(count, &ctx->heap, glb);
374377
int res = read(fd_obj->fd, (void *) term_binary_data(bin_term), count);
375378
if (UNLIKELY(res < 0)) {

0 commit comments

Comments
 (0)