summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSverker Eriksson <sverker@erlang.org>2021-03-08 21:18:27 +0100
committerSverker Eriksson <sverker@erlang.org>2021-03-10 12:48:04 +0100
commit465cca7df433f1b3d9e310ab7ca827bb9a5c73ab (patch)
tree5cd39e4307756a5b91fe745061d93147df9e58d5
parent3404d7a2d13539b851bb058dbe3277f6d1415021 (diff)
downloaderlang-465cca7df433f1b3d9e310ab7ca827bb9a5c73ab.tar.gz
erts: Fix leak in erlang:trace/3 bif
* if more than one {tracer, Pid} in list * if {tracer, Pid} followed by invalid flag or improper list * if {tracer, Pid} but failed to seize code write permission
-rw-r--r--erts/emulator/beam/erl_bif_trace.c9
-rw-r--r--erts/emulator/test/trace_SUITE.erl12
2 files changed, 20 insertions, 1 deletions
diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c
index ab42bc15f0..b688e82e70 100644
--- a/erts/emulator/beam/erl_bif_trace.c
+++ b/erts/emulator/beam/erl_bif_trace.c
@@ -465,19 +465,25 @@ erts_trace_flags(Eterm List,
cpu_timestamp = !0;
#endif
} else if (is_tuple(item)) {
+ ERTS_TRACER_CLEAR(&tracer);
tracer = erts_term_to_tracer(am_tracer, item);
if (tracer == THE_NON_VALUE)
goto error;
} else goto error;
list = CDR(list_val(list));
}
- if (is_not_nil(list)) goto error;
+ if (is_not_nil(list)) {
+ goto error;
+ }
if (mask) *pMask = mask;
if (!ERTS_TRACER_IS_NIL(tracer)) *pTracer = tracer;
if (cpu_timestamp) *pCpuTimestamp = cpu_timestamp;
return !0;
+
error:
+ if (tracer != THE_NON_VALUE)
+ ERTS_TRACER_CLEAR(&tracer);
return 0;
}
@@ -541,6 +547,7 @@ Eterm erts_internal_trace_3(BIF_ALIST_3)
}
if (!erts_try_seize_code_write_permission(BIF_P)) {
+ ERTS_TRACER_CLEAR(&tracer);
ERTS_BIF_YIELD3(&bif_trap_export[BIF_erts_internal_trace_3],
BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
}
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index 025f5282fb..951502cb61 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.erl
@@ -1684,6 +1684,18 @@ bad_flag(Config) when is_list(Config) ->
{'EXIT', {badarg, _}} = (catch erlang:trace(new,
true,
[not_a_valid_flag])),
+
+ %% Leaks of {tracer,_} in OTP 23.2
+ Pid = spawn(fun() -> receive die -> ok end end),
+ 1 = erlang:trace(Pid, true, [{tracer, self()},
+ {tracer, self()}]),
+ Pid ! die,
+ {'EXIT', {badarg, _}} =
+ (catch erlang:trace(new, true, [{tracer, self()}
+ | improper])),
+ {'EXIT', {badarg, _}} =
+ (catch erlang:trace(new, true, [{tracer, self()},
+ not_a_valid_flag])),
ok.
%% Test erlang:trace_delivered/1