aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2014-09-03 17:13:22 +0200
committerSverker Eriksson <[email protected]>2014-09-03 17:13:22 +0200
commitb182aa2cfab793e566c92183c361e78f4d6f84cb (patch)
tree4821839fdc9c5ea0d8bdd81bd5b02785f0937ccc /erts/emulator/beam
parentc472c3f5aafc81a409d0443c4601de43bafb53cb (diff)
downloadotp-b182aa2cfab793e566c92183c361e78f4d6f84cb.tar.gz
otp-b182aa2cfab793e566c92183c361e78f4d6f84cb.tar.bz2
otp-b182aa2cfab793e566c92183c361e78f4d6f84cb.zip
erts: Fix bug with enif_make_copy reallocating writable binary
that could invalidate a pointer received from an earlier call to enif_inspect_binary. Solution: Emasculate writable binary at enif_inspect_binary. There are room for optimizations here as we now do an unconditional emasculation even though enif_make_copy is not called later in the NIF.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/erl_nif.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index ff551ea3af..8c4bf73dbe 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -472,6 +472,18 @@ int enif_inspect_binary(ErlNifEnv* env, Eterm bin_term, ErlNifBinary* bin)
struct enif_tmp_obj_t* tmp;
byte* raw_ptr;
}u;
+
+ if (is_boxed(bin_term) && *binary_val(bin_term) == HEADER_SUB_BIN) {
+ ErlSubBin* sb = (ErlSubBin*) binary_val(bin_term);
+ if (sb->is_writable) {
+ ProcBin* pb = (ProcBin*) binary_val(sb->orig);
+ ASSERT(pb->thing_word == HEADER_PROC_BIN);
+ if (pb->flags) {
+ erts_emasculate_writable_binary(pb);
+ sb->is_writable = 0;
+ }
+ }
+ }
u.tmp = NULL;
bin->data = erts_get_aligned_binary_bytes_extra(bin_term, &u.raw_ptr, allocator,
sizeof(struct enif_tmp_obj_t));