Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing CAMLparam in win32's Unix.stat #11737

Merged
merged 3 commits into from Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions Changes
Expand Up @@ -224,6 +224,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);
Copy link
Contributor

@nojb nojb Nov 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to elaborate on @mlasson's explanation, the problem is this call to caml_uerror: if the GC runs during the execution of do_stat (which may happen if there are multiple threads), then path may be left dangling as it is not registered with the GC.

}
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