Skip to content

Commit

Permalink
Missing CAMLparam in win32's Unix.stat (#11737)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mlasson committed Nov 21, 2022
1 parent 5360277 commit 3d8fb96
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Changes
Expand Up @@ -228,6 +228,10 @@ Working version
- #11732: Ensure that types from packed modules are always generalised
(Stephen Dolan and Leo White, review by Jacques Garrigue)

- #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 5.0
---------

Expand Down
12 changes: 8 additions & 4 deletions otherlibs/unix/stat_win32.c
Expand Up @@ -339,50 +339,54 @@ 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;

caml_unix_check_path(path, "stat");
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;

caml_unix_check_path(path, "stat");
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;

caml_unix_check_path(path, "lstat");
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;

caml_unix_check_path(path, "lstat");
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)
Expand Down

0 comments on commit 3d8fb96

Please sign in to comment.