summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Lasson <marc.lasson@lexifi.com>2022-11-21 09:00:56 +0100
committerNicolás Ojeda Bär <n.oje.bar@gmail.com>2022-11-21 09:04:21 +0100
commit6ce4756e97b08b406ee29920914ab6ad98740a28 (patch)
tree935274f8a0807a213975552f15b3d040d3d711cf
parent14faa5d50862b5d50e0bc787f84f4dbbe81a9008 (diff)
downloadocaml-6ce4756e97b08b406ee29920914ab6ad98740a28.tar.gz
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)
-rw-r--r--Changes4
-rw-r--r--otherlibs/unix/stat_win32.c12
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)