summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2010-06-16 15:25:45 +0100
committerRichard Jones <rjones@redhat.com>2010-06-16 15:32:20 +0100
commit1079f74704a06c06996e547fdecf20a8f92799c6 (patch)
tree32b272a9b86952f06f8565526c1fe5d8cf09bee7 /src
parent1e568f057e8bb7b36cc14e0e531d74b75ad9cb6c (diff)
downloadlibguestfs-1079f74704a06c06996e547fdecf20a8f92799c6.tar.gz
libguestfs-1079f74704a06c06996e547fdecf20a8f92799c6.tar.xz
libguestfs-1079f74704a06c06996e547fdecf20a8f92799c6.zip
ocaml: Fix thread safety of strings in bindings (RHBZ#604691).
There's a thread safety issue with the current OCaml bindings which is well explained in the bug report: https://bugzilla.redhat.com/show_bug.cgi?id=604691 This commit fixes the safety issue by copying strings temporarily before releasing the thread lock. Updated code looks like this: char *filename = guestfs_safe_strdup (g, String_val (filenamev)); int r; caml_enter_blocking_section (); r = guestfs_add_drive_ro (g, filename); caml_leave_blocking_section (); free (filename); if (r == -1) ocaml_guestfs_raise_error (g, "add_drive_ro"); Also included is a regression test.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/generator.ml25
1 files changed, 15 insertions, 10 deletions
diff --git a/src/generator.ml b/src/generator.ml
index 571870da..d640343e 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -6349,6 +6349,8 @@ and generate_linker_script () =
*)
"guestfs_safe_calloc";
"guestfs_safe_malloc";
+ "guestfs_safe_strdup";
+ "guestfs_safe_memdup";
] in
let functions =
List.map (fun (name, _, _, _, _, _, _) -> "guestfs_" ^ name)
@@ -8395,7 +8397,7 @@ and generate_ocaml_c () =
#include <caml/mlvalues.h>
#include <caml/signals.h>
-#include <guestfs.h>
+#include \"guestfs.h\"
#include \"guestfs_c.h\"
@@ -8563,14 +8565,15 @@ copy_table (char * const * argv)
| String n
| FileIn n
| FileOut n ->
- pr " const char *%s = String_val (%sv);\n" n n
+ (* Copy strings in case the GC moves them: RHBZ#604691 *)
+ pr " char *%s = guestfs_safe_strdup (g, String_val (%sv));\n" n n
| OptString n ->
- pr " const char *%s =\n" n;
- pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
- n n
+ pr " char *%s =\n" n;
+ pr " %sv != Val_int (0) ?" n;
+ pr " guestfs_safe_strdup (g, String_val (Field (%sv, 0))) : NULL;\n" n
| BufferIn n ->
- pr " const char *%s = String_val (%sv);\n" n n;
- pr " size_t %s_size = caml_string_length (%sv);\n" n n
+ pr " size_t %s_size = caml_string_length (%sv);\n" n n;
+ pr " char *%s = guestfs_safe_memdup (g, String_val (%sv), %s_size);\n" n n n
| StringList n | DeviceList n ->
pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
| Bool n ->
@@ -8613,13 +8616,15 @@ copy_table (char * const * argv)
pr ";\n";
pr " caml_leave_blocking_section ();\n";
+ (* Free strings if we copied them above. *)
List.iter (
function
+ | Pathname n | Device n | Dev_or_Path n | String n | OptString n
+ | FileIn n | FileOut n | BufferIn n ->
+ pr " free (%s);\n" n
| StringList n | DeviceList n ->
pr " ocaml_guestfs_free_strings (%s);\n" n;
- | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
- | Bool _ | Int _ | Int64 _
- | FileIn _ | FileOut _ | BufferIn _ -> ()
+ | Bool _ | Int _ | Int64 _ -> ()
) (snd style);
pr " if (r == %s)\n" error_code;