diff options
author | Simon MacMullen <simon@rabbitmq.com> | 2014-08-18 11:37:32 +0100 |
---|---|---|
committer | Simon MacMullen <simon@rabbitmq.com> | 2014-08-18 11:37:32 +0100 |
commit | 68b2e6e0f2b9fae37ad4a72fcb7bcc9a4dd4f188 (patch) | |
tree | 6a471a21bbca8efcdcfde98e39fa903c91a7b1a2 /src | |
parent | ee711556d012b7a5292fd25d3696aefbb0c8a89b (diff) | |
download | rabbitmq-server-68b2e6e0f2b9fae37ad4a72fcb7bcc9a4dd4f188.tar.gz |
Prevent malicious channels from sending messages to arbitrary processes with this mechanism.
Diffstat (limited to 'src')
-rw-r--r-- | src/pg_local.erl | 13 | ||||
-rw-r--r-- | src/rabbit_channel.erl | 16 |
2 files changed, 26 insertions, 3 deletions
diff --git a/src/pg_local.erl b/src/pg_local.erl index f535b136..dc6401ca 100644 --- a/src/pg_local.erl +++ b/src/pg_local.erl @@ -34,7 +34,7 @@ %% -module(pg_local). --export([join/2, leave/2, get_members/1]). +-export([join/2, leave/2, get_members/1, in_group/2]). -export([sync/0]). %% intended for testing only; not part of official API -export([start/0, start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]). @@ -50,6 +50,7 @@ -spec(join/2 :: (name(), pid()) -> 'ok'). -spec(leave/2 :: (name(), pid()) -> 'ok'). -spec(get_members/1 :: (name()) -> [pid()]). +-spec(in_group/2 :: (name(), pid()) -> boolean()). -spec(sync/0 :: () -> 'ok'). @@ -81,6 +82,10 @@ get_members(Name) -> ensure_started(), group_members(Name). +in_group(Name, Pid) -> + ensure_started(), + member_present(Name, Pid). + sync() -> ensure_started(), gen_server:call(?MODULE, sync, infinity). @@ -199,6 +204,12 @@ member_in_group(Pid, Name) -> [{{member, Name, Pid}, N}] = ets:lookup(pg_local_table, {member, Name, Pid}), lists:duplicate(N, Pid). +member_present(Name, Pid) -> + case ets:lookup(pg_local_table, {member, Name, Pid}) of + [_] -> true; + [] -> false + end. + member_groups(Pid) -> [Name || [Name] <- ets:match(pg_local_table, {{pid, Pid, '$1'}})]. diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl index a153822e..b61a53f8 100644 --- a/src/rabbit_channel.erl +++ b/src/rabbit_channel.erl @@ -31,7 +31,7 @@ handle_info/2, handle_pre_hibernate/1, prioritise_call/4, prioritise_cast/3, prioritise_info/3, format_message_queue/2]). %% Internal --export([list_local/0]). +-export([list_local/0, deliver_reply_local/3]). -record(ch, {state, protocol, channel, reader_pid, writer_pid, conn_pid, conn_name, limiter, tx, next_tag, unacked_message_q, user, @@ -97,6 +97,9 @@ -spec(deliver/4 :: (pid(), rabbit_types:ctag(), boolean(), rabbit_amqqueue:qmsg()) -> 'ok'). +-spec(deliver_reply/2 :: (binary(), rabbit_types:delivery()) -> 'ok'). +-spec(deliver_reply_local/3 :: + (pid(), binary(), rabbit_types:delivery()) -> 'ok'). -spec(send_credit_reply/2 :: (pid(), non_neg_integer()) -> 'ok'). -spec(send_drained/2 :: (pid(), [{rabbit_types:ctag(), non_neg_integer()}]) -> 'ok'). @@ -146,7 +149,16 @@ deliver(Pid, ConsumerTag, AckRequired, Msg) -> deliver_reply(<<"amq.rabbitmq.reply-to.", Rest/binary>>, Delivery) -> [PidEnc, Key] = binary:split(Rest, <<".">>), Pid = binary_to_term(base64:decode(PidEnc)), - gen_server2:cast(Pid, {deliver_reply, Key, Delivery}). + delegate:invoke_no_result( + Pid, {?MODULE, deliver_reply_local, [Key, Delivery]}). + +%% We want to ensure people can't use this mechanism to send a message +%% to an arbitrary process and kill it! +deliver_reply_local(Pid, Key, Delivery) -> + case pg_local:in_group(rabbit_channels, Pid) of + true -> gen_server2:cast(Pid, {deliver_reply, Key, Delivery}); + false -> ok + end. send_credit_reply(Pid, Len) -> gen_server2:cast(Pid, {send_credit_reply, Len}). |