Skip to content

Commit

Permalink
Missing CAMLparam in win32's Unix.stat (ocaml#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.

(cherry picked from commit 3d8fb96)
  • Loading branch information
mlasson authored and nojb committed Nov 21, 2022
1 parent fb5b1e4 commit 6729eb8
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ OCaml 4.14 maintenance branch
mismatch error involving recursive types.
(Florian Angeletti, 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)
----------------------------

Expand Down
12 changes: 8 additions & 4 deletions otherlibs/win32unix/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,50 +347,54 @@ static int do_stat(int do_lstat, int use_64, const char* opath, HANDLE fstat, __

CAMLprim value 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)) {
uerror("stat", path);
}
return stat_aux(0, st_ino, &buf);
CAMLreturn (stat_aux(0, st_ino, &buf));
}

CAMLprim value 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)) {
uerror("stat", path);
}
return stat_aux(1, st_ino, &buf);
CAMLreturn (stat_aux(1, st_ino, &buf));
}

CAMLprim value 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)) {
uerror("lstat", path);
}
return stat_aux(0, st_ino, &buf);
CAMLreturn (stat_aux(0, st_ino, &buf));
}

CAMLprim value 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)) {
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 6729eb8

Please sign in to comment.