Skip to content

Commit

Permalink
Fix a crash in Obj.reachable_words (ocaml#10853)
Browse files Browse the repository at this point in the history
A marshaling operation can leave `extern_flags` with the `NO_SHARING`
bit set.  In this context, `caml_obj_reachable_words` calls
`extern_init_position_table`, which does nothing, then proceeds to
access the position table, causing a crash.

The solution is trivial: initialize `extern_flags` before calling
`extern_init_position_table`.

A regression test was added.

First reported at ocaml-multicore/ocaml-multicore#824
  • Loading branch information
xavierleroy authored and avsm committed Jan 6, 2022
1 parent 039807e commit daf23ef
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Changes
Expand Up @@ -438,6 +438,16 @@ OCaml 4.14.0
- #10763, #10764: fix miscompilation of method delegation
(Alain Frisch, review by Vincent Laviron and Jacques Garrigue)

- #10822, #10823: Bad interaction between ambivalent types and subtyping
coercions (Jacques Garrigue, report and review by Frédéric Bour)

- #10849: Display the result of `let _ : <type> = <expr>` in the native
toplevel, as in the bytecode toplevel.
(David Allsopp, report by Nathan Rebours, review by Gabriel Scherer)

- #10853: `Obj.reachable_words` could crash if called after a marshaling
operation in `NO_SHARING` mode.
(Xavier Leroy, report by Anil Madhavapeddy, review by Alain Frisch)

OCaml 4.13 maintenance branch
-----------------------------
Expand Down
1 change: 1 addition & 0 deletions runtime/extern.c
Expand Up @@ -1209,6 +1209,7 @@ CAMLprim value caml_obj_reachable_words(value v)
struct caml_extern_state *s = get_extern_state ();

s->obj_counter = 0;
s->extern_flags = 0;
extern_init_position_table(s);
sp = s->extern_stack;
size = 0;
Expand Down
9 changes: 9 additions & 0 deletions testsuite/tests/lib-obj/reachable_words_bug.ml
@@ -0,0 +1,9 @@
(* TEST
*)

let _ =
(* In 4.13 this causes Obj.reachable_words to segfault
because of a missing initialization in caml_obj_reachable_words *)
ignore (Marshal.(to_string 123 [No_sharing]));
let n = Obj.reachable_words (Obj.repr (Array.init 10 (fun i -> i))) in
assert (n = 11)

0 comments on commit daf23ef

Please sign in to comment.