From 6ce4756e97b08b406ee29920914ab6ad98740a28 Mon Sep 17 00:00:00 2001 From: Marc Lasson Date: Mon, 21 Nov 2022 09:00:56 +0100 Subject: Missing CAMLparam in win32's Unix.stat (#11737) The `path` argument is used after a `caml_enter_blocking_section` when the path does not exists (the path is used to build the unix error exception). Unfortunately, during the blocking section we may "yield" to a thread that can trigger a garbage collection and move the content of `path` elsewhere, triggering a segfault. The CAMLparam is therefore needed in that case. (cherry picked from commit 3d8fb96281c94d31299859e7a72b90ce0976254c) --- Changes | 4 ++++ otherlibs/unix/stat_win32.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index 57fcf68450..29ab19ecd7 100644 --- a/Changes +++ b/Changes @@ -529,6 +529,10 @@ OCaml 5.0 the bug was only present in development version of OCaml 5. (Stephen Dolan, report by Andre Maroneze, review by Gabriel Scherer) +- #11737: Fix segfault condition in Unix.stat under Windows in the presence of + multiple threads. + (Marc Lasson, Nicolás Ojeda Bär, review by Gabriel Scherer and David Allsopp) + OCaml 4.14.0 (28 March 2022) ---------------------------- diff --git a/otherlibs/unix/stat_win32.c b/otherlibs/unix/stat_win32.c index 2e1f6f84de..c1b69c0331 100644 --- a/otherlibs/unix/stat_win32.c +++ b/otherlibs/unix/stat_win32.c @@ -348,6 +348,7 @@ static int do_stat(int do_lstat, int use_64, const char* opath, HANDLE fstat, __ CAMLprim value caml_unix_stat(value path) { + CAMLparam1(path); struct _stat64 buf; __int64 st_ino; @@ -355,11 +356,12 @@ CAMLprim value caml_unix_stat(value path) if (!do_stat(0, 0, String_val(path), NULL, &st_ino, &buf)) { caml_uerror("stat", path); } - return stat_aux(0, st_ino, &buf); + CAMLreturn (stat_aux(0, st_ino, &buf)); } CAMLprim value caml_unix_stat_64(value path) { + CAMLparam1(path); struct _stat64 buf; __int64 st_ino; @@ -367,11 +369,12 @@ CAMLprim value caml_unix_stat_64(value path) if (!do_stat(0, 1, String_val(path), NULL, &st_ino, &buf)) { caml_uerror("stat", path); } - return stat_aux(1, st_ino, &buf); + CAMLreturn (stat_aux(1, st_ino, &buf)); } CAMLprim value caml_unix_lstat(value path) { + CAMLparam1(path); struct _stat64 buf; __int64 st_ino; @@ -379,11 +382,12 @@ CAMLprim value caml_unix_lstat(value path) if (!do_stat(1, 0, String_val(path), NULL, &st_ino, &buf)) { caml_uerror("lstat", path); } - return stat_aux(0, st_ino, &buf); + CAMLreturn (stat_aux(0, st_ino, &buf)); } CAMLprim value caml_unix_lstat_64(value path) { + CAMLparam1(path); struct _stat64 buf; __int64 st_ino; @@ -391,7 +395,7 @@ CAMLprim value caml_unix_lstat_64(value path) if (!do_stat(1, 1, String_val(path), NULL, &st_ino, &buf)) { caml_uerror("lstat", path); } - return stat_aux(1, st_ino, &buf); + CAMLreturn (stat_aux(1, st_ino, &buf)); } static value do_fstat(value handle, int use_64) -- cgit v1.2.1