Skip to content

Commit 4b2be40

Browse files
Merge pull request #1640 from rabbitmq/lrb-vesc-888
Add code_server cache to prevent code:get_object_code abuse
2 parents 1c75310 + 2371531 commit 4b2be40

File tree

3 files changed

+99
-15
lines changed

3 files changed

+99
-15
lines changed

src/code_server_cache.erl

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
2+
%% ex: ts=4 sw=4 et
3+
%% The contents of this file are subject to the Mozilla Public License
4+
%% Version 1.1 (the "License"); you may not use this file except in
5+
%% compliance with the License. You may obtain a copy of the License
6+
%% at http://www.mozilla.org/MPL/
7+
%%
8+
%% Software distributed under the License is distributed on an "AS IS"
9+
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
10+
%% the License for the specific language governing rights and
11+
%% limitations under the License.
12+
%%
13+
%% The Original Code is RabbitMQ.
14+
%%
15+
%% The Initial Developer of the Original Code is GoPivotal, Inc.
16+
%% Copyright (c) 2007-2017 Pivotal Software, Inc. All rights reserved.
17+
%%
18+
19+
-module(code_server_cache).
20+
21+
-behaviour(gen_server).
22+
23+
%% API
24+
-export([start_link/0,
25+
maybe_call_mfa/4]).
26+
27+
%% gen_server callbacks
28+
-export([init/1,
29+
handle_call/3,
30+
handle_cast/2,
31+
handle_info/2,
32+
terminate/2,
33+
code_change/3]).
34+
35+
-record(state, {
36+
modules = #{} :: #{atom() => boolean()}
37+
}).
38+
39+
%% API
40+
start_link() ->
41+
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
42+
43+
maybe_call_mfa(Module, Function, Args, Default) ->
44+
gen_server:call(?MODULE, {maybe_call_mfa, {Module, Function, Args, Default}}).
45+
46+
%% gen_server callbacks
47+
48+
init([]) ->
49+
{ok, #state{}}.
50+
51+
handle_call({maybe_call_mfa, {Mod, _F, _A, _D} = MFA}, _From, #state{modules = ModuleMap} = State0) ->
52+
Value = maps:get(Mod, ModuleMap, true),
53+
{ok, Reply, State1} = handle_maybe_call_mfa(Value, MFA, State0),
54+
{reply, Reply, State1};
55+
handle_call(_Request, _From, State) ->
56+
{reply, ignored, State}.
57+
58+
handle_cast(_Msg, State) ->
59+
{noreply, State}.
60+
61+
handle_info(_Info, State) ->
62+
{noreply, State}.
63+
64+
terminate(_Reason, _State) ->
65+
ok.
66+
67+
code_change(_OldVsn, State, _Extra) ->
68+
{ok, State}.
69+
70+
%% Internal functions
71+
72+
handle_maybe_call_mfa(false, {_M, _F, _A, Default}, State) ->
73+
{ok, Default, State};
74+
handle_maybe_call_mfa(true, {Module, Function, Args, Default}, State) ->
75+
try
76+
Reply = erlang:apply(Module, Function, Args),
77+
{ok, Reply, State}
78+
catch
79+
error:undef ->
80+
handle_maybe_call_mfa_error(Module, Default, State);
81+
Err:Reason ->
82+
rabbit_log:error("Calling ~p:~p failed: ~p:~p~n",
83+
[Module, Function, Err, Reason]),
84+
handle_maybe_call_mfa_error(Module, Default, State)
85+
end.
86+
87+
handle_maybe_call_mfa_error(Module, Default, #state{modules = ModuleMap0} = State0) ->
88+
ModuleMap1 = maps:put(Module, false, ModuleMap0),
89+
State1 = State0#state{modules = ModuleMap1},
90+
{ok, Default, State1}.

src/rabbit.erl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,17 @@
7474
{requires, database},
7575
{enables, external_infrastructure}]}).
7676

77+
-rabbit_boot_step({code_server_cache,
78+
[{description, "code_server cache server"},
79+
{mfa, {rabbit_sup, start_child, [code_server_cache]}},
80+
{requires, rabbit_alarm},
81+
{enables, file_handle_cache}]}).
82+
7783
-rabbit_boot_step({file_handle_cache,
7884
[{description, "file handle cache server"},
7985
{mfa, {rabbit, start_fhc, []}},
8086
%% FHC needs memory monitor to be running
81-
{requires, rabbit_alarm},
87+
{requires, code_server_cache},
8288
{enables, worker_pool}]}).
8389

8490
-rabbit_boot_step({worker_pool,

src/rabbit_direct.erl

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -135,20 +135,8 @@ maybe_call_connection_info_module(Protocol, Creds, VHost, Pid, Infos) ->
135135
Module = rabbit_data_coercion:to_atom(string:to_lower(
136136
"rabbit_" ++ rabbit_data_coercion:to_list(Protocol) ++ "_connection_info")
137137
),
138-
case code:get_object_code(Module) of
139-
{_Module, _Binary, _Filename} ->
140-
try
141-
Module:additional_authn_params(Creds, VHost, Pid, Infos)
142-
catch
143-
_:Reason ->
144-
rabbit_log:error("Calling ~p:additional_authn_params/4 failed:~p~n", [Module, Reason]),
145-
[]
146-
end;
147-
error ->
148-
[];
149-
_ ->
150-
[]
151-
end.
138+
Args = [Creds, VHost, Pid, Infos],
139+
code_server_cache:maybe_call_mfa(Module, additional_authn_params, Args, []).
152140

153141
is_vhost_alive(VHost, {Username, _Password}, Pid) ->
154142
PrintedUsername = case Username of

0 commit comments

Comments
 (0)