Skip to content

Commit ee1d25d

Browse files
authored
flambda-backend: Fix for naked pointer problem in unsafe_get_global_value (#2317)
1 parent 70819a5 commit ee1d25d

File tree

10 files changed

+50
-1
lines changed

10 files changed

+50
-1
lines changed

otherlibs/dynlink/byte/dynlink.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ module Bytecode = struct
219219
| exception _ -> None
220220
| obj -> Some obj
221221

222+
let does_symbol_exist ~bytecode_or_asm_symbol =
223+
Option.is_some (unsafe_get_global_value ~bytecode_or_asm_symbol)
224+
222225
let finish (ic, _filename, _digest) =
223226
close_in ic
224227
end

otherlibs/dynlink/dynlink.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ let unsafe_get_global_value ~bytecode_or_asm_symbol =
6262
if is_native then N.unsafe_get_global_value ~bytecode_or_asm_symbol
6363
else B.unsafe_get_global_value ~bytecode_or_asm_symbol
6464

65+
let does_symbol_exist ~bytecode_or_asm_symbol =
66+
if is_native then N.does_symbol_exist ~bytecode_or_asm_symbol
67+
else B.does_symbol_exist ~bytecode_or_asm_symbol
68+
6569
let adapt_filename file =
6670
if is_native then N.adapt_filename file
6771
else B.adapt_filename file

otherlibs/dynlink/dynlink.mli

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ val unsafe_get_global_value : bytecode_or_asm_symbol:string -> Obj.t option
166166
The accessible values are those in the main program and those provided by
167167
previous calls to [loadfile].
168168
169+
** This function may only be used to retrieve the addresses of symbols
170+
that are valid OCaml values. It cannot be used to retrieve e.g. code
171+
pointers. **
172+
169173
This function is deemed "unsafe" as there is no type safety provided.
170174
171175
When executing in bytecode, this function uses [Symtable]. As a cautionary
@@ -178,3 +182,8 @@ val unsafe_get_global_value : bytecode_or_asm_symbol:string -> Obj.t option
178182
client's version of [Symtable]). This is why we can't use [Dynlink] from the
179183
toplevel interactive loop, in particular.
180184
*)
185+
186+
(** Like [unsafe_get_global_value], but only tests whether the given symbol
187+
exists, and in native code may be used for any symbol (whether or not such
188+
symbol points at a valid OCaml value). *)
189+
val does_symbol_exist : bytecode_or_asm_symbol:string -> bool

otherlibs/dynlink/dynlink_common.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,12 @@ module Make (P : Dynlink_platform_intf.S) = struct
402402
P.unsafe_get_global_value ~bytecode_or_asm_symbol
403403
)
404404

405+
let does_symbol_exist ~bytecode_or_asm_symbol =
406+
with_lock (fun _ ->
407+
(* The bytecode implementation reads the global symtable *)
408+
P.does_symbol_exist ~bytecode_or_asm_symbol
409+
)
410+
405411
let is_native = P.is_native
406412
let adapt_filename = P.adapt_filename
407413
end

otherlibs/dynlink/dynlink_common.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module Make (_ : Dynlink_platform_intf.S) : sig
2424
val loadfile : string -> unit
2525
val loadfile_private : string -> unit
2626
val unsafe_get_global_value : bytecode_or_asm_symbol:string -> Obj.t option
27+
val does_symbol_exist : bytecode_or_asm_symbol:string -> bool
2728
val adapt_filename : string -> string
2829
val set_allowed_units : string list -> unit
2930
val allow_only: string list -> unit

otherlibs/dynlink/dynlink_platform_intf.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,7 @@ module type S = sig
7878

7979
val unsafe_get_global_value : bytecode_or_asm_symbol:string -> Obj.t option
8080

81+
val does_symbol_exist : bytecode_or_asm_symbol:string -> bool
82+
8183
val finish : handle -> unit
8284
end

otherlibs/dynlink/native/dynlink.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ module Native = struct
5353
= "caml_sys_exit" "caml_natdynlink_globals_inited"
5454
external ndl_loadsym : string -> Obj.t
5555
= "caml_sys_exit" "caml_natdynlink_loadsym"
56+
external ndl_existssym : string -> bool
57+
= "caml_sys_exit" "caml_natdynlink_existssym"
58+
[@@noalloc]
5659

5760
module Unit_header = struct
5861
type t = Cmxs_format.dynunit
@@ -161,6 +164,9 @@ module Native = struct
161164
| exception _ -> None
162165
| obj -> Some obj
163166

167+
let does_symbol_exist ~bytecode_or_asm_symbol =
168+
ndl_existssym bytecode_or_asm_symbol
169+
164170
let finish _handle = ()
165171
end
166172

runtime/dynlink_nat.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,16 @@ CAMLprim value caml_natdynlink_loadsym(value symbol)
204204
CAMLparam1 (symbol);
205205
CAMLlocal1 (sym);
206206

207+
/* Note that this can only be used for symbols which are valid OCaml
208+
values, otherwise a naked pointer would be returned. */
209+
207210
sym = (value) caml_globalsym(String_val(symbol));
208211
if (!sym) caml_failwith(String_val(symbol));
209212
CAMLreturn(sym);
210213
}
214+
215+
CAMLprim value caml_natdynlink_existssym(value symbol)
216+
{
217+
void* sym = caml_globalsym(String_val(symbol));
218+
return sym != NULL ? Val_true : Val_false;
219+
}

runtime4/dynlink_nat.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,16 @@ CAMLprim value caml_natdynlink_loadsym(value symbol)
221221
CAMLparam1 (symbol);
222222
CAMLlocal1 (sym);
223223

224+
/* Note that this can only be used for symbols which are valid OCaml
225+
values, otherwise a naked pointer would be returned. */
226+
224227
sym = (value) caml_globalsym(String_val(symbol));
225228
if (!sym) caml_failwith(String_val(symbol));
226229
CAMLreturn(sym);
227230
}
231+
232+
CAMLprim value caml_natdynlink_existssym(value symbol)
233+
{
234+
void* sym = caml_globalsym(String_val(symbol));
235+
return sym != NULL ? Val_true : Val_false;
236+
}

toplevel/native/tophooks.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ let lookup sym =
2828
Dynlink.unsafe_get_global_value ~bytecode_or_asm_symbol:sym
2929

3030
let need_symbol sym =
31-
Option.is_none (Dynlink.unsafe_get_global_value ~bytecode_or_asm_symbol:sym)
31+
not (Dynlink.does_symbol_exist ~bytecode_or_asm_symbol:sym)
3232

3333
let dll_run dll entry =
3434
match (try Result (Obj.magic (ndl_run_toplevel dll entry))

0 commit comments

Comments
 (0)