File 1159-erts-Fix-leak-in-erlang-trace-3-bif.patch of Package erlang
From 465cca7df433f1b3d9e310ab7ca827bb9a5c73ab Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Mon, 8 Mar 2021 21:18:27 +0100
Subject: [PATCH 2/2] 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
---
erts/emulator/beam/erl_bif_trace.c | 9 ++++++++-
erts/emulator/test/trace_SUITE.erl | 12 ++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
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_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
--
2.26.2