Skip to content

Commit 3d8fb96

Browse files
authored
Missing CAMLparam in win32's Unix.stat (ocaml#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.
1 parent 5360277 commit 3d8fb96

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

Changes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ Working version
228228
- #11732: Ensure that types from packed modules are always generalised
229229
(Stephen Dolan and Leo White, review by Jacques Garrigue)
230230

231+
- #11737: Fix segfault condition in Unix.stat under Windows in the presence of
232+
multiple threads.
233+
(Marc Lasson, Nicolás Ojeda Bär, review by Gabriel Scherer and David Allsopp)
234+
231235
OCaml 5.0
232236
---------
233237

otherlibs/unix/stat_win32.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,50 +339,54 @@ static int do_stat(int do_lstat, int use_64, const char* opath, HANDLE fstat, __
339339

340340
CAMLprim value caml_unix_stat(value path)
341341
{
342+
CAMLparam1(path);
342343
struct _stat64 buf;
343344
__int64 st_ino;
344345

345346
caml_unix_check_path(path, "stat");
346347
if (!do_stat(0, 0, String_val(path), NULL, &st_ino, &buf)) {
347348
caml_uerror("stat", path);
348349
}
349-
return stat_aux(0, st_ino, &buf);
350+
CAMLreturn (stat_aux(0, st_ino, &buf));
350351
}
351352

352353
CAMLprim value caml_unix_stat_64(value path)
353354
{
355+
CAMLparam1(path);
354356
struct _stat64 buf;
355357
__int64 st_ino;
356358

357359
caml_unix_check_path(path, "stat");
358360
if (!do_stat(0, 1, String_val(path), NULL, &st_ino, &buf)) {
359361
caml_uerror("stat", path);
360362
}
361-
return stat_aux(1, st_ino, &buf);
363+
CAMLreturn (stat_aux(1, st_ino, &buf));
362364
}
363365

364366
CAMLprim value caml_unix_lstat(value path)
365367
{
368+
CAMLparam1(path);
366369
struct _stat64 buf;
367370
__int64 st_ino;
368371

369372
caml_unix_check_path(path, "lstat");
370373
if (!do_stat(1, 0, String_val(path), NULL, &st_ino, &buf)) {
371374
caml_uerror("lstat", path);
372375
}
373-
return stat_aux(0, st_ino, &buf);
376+
CAMLreturn (stat_aux(0, st_ino, &buf));
374377
}
375378

376379
CAMLprim value caml_unix_lstat_64(value path)
377380
{
381+
CAMLparam1(path);
378382
struct _stat64 buf;
379383
__int64 st_ino;
380384

381385
caml_unix_check_path(path, "lstat");
382386
if (!do_stat(1, 1, String_val(path), NULL, &st_ino, &buf)) {
383387
caml_uerror("lstat", path);
384388
}
385-
return stat_aux(1, st_ino, &buf);
389+
CAMLreturn (stat_aux(1, st_ino, &buf));
386390
}
387391

388392
static value do_fstat(value handle, int use_64)

0 commit comments

Comments
 (0)