Skip to content

Commit d5ad0ec

Browse files
committed
Guard getenv with spinlock
1 parent cae1094 commit d5ad0ec

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

src/libAtomVM/nifs.c

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,7 @@ static term nif_os_getenv_1(Context *ctx, int argc, term argv[])
18111811
{
18121812
UNUSED(argc);
18131813

1814+
term result;
18141815
term env_var_list = argv[0];
18151816
VALIDATE_VALUE(env_var_list, term_is_list);
18161817

@@ -1820,17 +1821,45 @@ static term nif_os_getenv_1(Context *ctx, int argc, term argv[])
18201821
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
18211822
}
18221823

1823-
const char *env_var_value = getenv(env_var);
1824-
if (IS_NULL_PTR(env_var_value)) {
1825-
return FALSE_ATOM;
1824+
#ifndef AVM_NO_SMP
1825+
smp_spinlock_lock(&ctx->global->env_spinlock);
1826+
#endif
1827+
1828+
const char *env_var_value_tmp = getenv(env_var);
1829+
1830+
if (IS_NULL_PTR(env_var_value_tmp)) {
1831+
result = FALSE_ATOM;
1832+
goto nif_os_getenv_1_unlock_return;
18261833
}
18271834

1828-
size_t len = strlen(env_var_value);
1829-
if (UNLIKELY(memory_ensure_free_opt(ctx, LIST_SIZE(len, 1), MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
1835+
size_t env_value_len = strlen(env_var_value_tmp);
1836+
char *env_var_value = malloc(env_value_len + 1);
1837+
1838+
if (UNLIKELY(IS_NULL_PTR(env_var_value))) {
1839+
result = OUT_OF_MEMORY_ATOM;
1840+
goto nif_os_getenv_1_unlock_return;
1841+
}
1842+
1843+
strcpy(env_var_value, env_var_value_tmp);
1844+
1845+
#ifndef AVM_NO_SMP
1846+
smp_spinlock_unlock(&ctx->global->env_spinlock);
1847+
#endif
1848+
1849+
if (UNLIKELY(memory_ensure_free_opt(ctx, LIST_SIZE(env_value_len, 1), MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
18301850
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
18311851
}
18321852

1833-
return interop_bytes_to_list(env_var_value, len, &ctx->heap);
1853+
result = interop_bytes_to_list(env_var_value, env_value_len, &ctx->heap);
1854+
free(env_var_value);
1855+
return result;
1856+
1857+
nif_os_getenv_1_unlock_return:
1858+
#ifndef AVM_NO_SMP
1859+
smp_spinlock_unlock(&ctx->global->env_spinlock);
1860+
#endif
1861+
1862+
return result;
18341863
}
18351864

18361865
static term nif_erlang_make_tuple_2(Context *ctx, int argc, term argv[])

0 commit comments

Comments
 (0)