Skip to content

Commit 08636f9

Browse files
Reject max-priority arguments >= 256
This is the value we advertise in the docs and it should be enforced to avoid process explosion e.g. when an overflow value is provided. Part of #1590. [#157380396]
1 parent 54c9b85 commit 08636f9

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

src/rabbit_amqqueue.erl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ declare_args() ->
575575
{<<"x-dead-letter-routing-key">>, fun check_dlxrk_arg/2},
576576
{<<"x-max-length">>, fun check_non_neg_int_arg/2},
577577
{<<"x-max-length-bytes">>, fun check_non_neg_int_arg/2},
578-
{<<"x-max-priority">>, fun check_non_neg_int_arg/2},
578+
{<<"x-max-priority">>, fun check_max_priority_arg/2},
579579
{<<"x-overflow">>, fun check_overflow/2},
580580
{<<"x-queue-mode">>, fun check_queue_mode/2}].
581581

@@ -611,6 +611,13 @@ check_message_ttl_arg({Type, Val}, Args) ->
611611
Error -> Error
612612
end.
613613

614+
check_max_priority_arg({Type, Val}, Args) ->
615+
case check_non_neg_int_arg({Type, Val}, Args) of
616+
ok when Val =< 255 -> ok;
617+
ok -> {error, {max_value_exceeded, Val}};
618+
Error -> Error
619+
end.
620+
614621
%% Note that the validity of x-dead-letter-exchange is already verified
615622
%% by rabbit_channel's queue.declare handler.
616623
check_dlxname_arg({longstr, _}, _) -> ok;

src/rabbit_priority_queue.erl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,14 @@ collapse_recovery(QNames, DupNames, Recovery) ->
128128
priorities(#amqqueue{arguments = Args}) ->
129129
Ints = [long, short, signedint, byte, unsignedbyte, unsignedshort, unsignedint],
130130
case rabbit_misc:table_lookup(Args, <<"x-max-priority">>) of
131-
{Type, Max} -> case lists:member(Type, Ints) of
132-
false -> none;
133-
true -> lists:reverse(lists:seq(0, Max))
134-
end;
135-
_ -> none
131+
{Type, RequestedMax} ->
132+
case lists:member(Type, Ints) of
133+
false -> none;
134+
true ->
135+
Max = min(RequestedMax, ?MAX_SUPPORTED_PRIORITY),
136+
lists:reverse(lists:seq(0, Max))
137+
end;
138+
_ -> none
136139
end.
137140

138141
%%----------------------------------------------------------------------------

test/priority_queue_SUITE.erl

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
-module(priority_queue_SUITE).
1818

1919
-include_lib("common_test/include/ct.hrl").
20+
-include_lib("eunit/include/eunit.hrl").
2021
-include_lib("amqp_client/include/amqp_client.hrl").
2122

2223
-compile(export_all).
@@ -46,7 +47,9 @@ groups() ->
4647
simple_order,
4748
straight_through,
4849
invoke,
49-
gen_server2_stats
50+
gen_server2_stats,
51+
negative_max_priorities,
52+
max_priorities_above_hard_limit
5053
]},
5154
{cluster_size_3, [], [
5255
mirror_queue_auto_ack,
@@ -192,6 +195,28 @@ straight_through(Config) ->
192195
rabbit_ct_client_helpers:close_connection(Conn),
193196
passed.
194197

198+
max_priorities_above_hard_limit(Config) ->
199+
{Conn, Ch} = rabbit_ct_client_helpers:open_connection_and_channel(Config, 0),
200+
Q = <<"max_priorities_above_hard_limit">>,
201+
?assertExit(
202+
{{shutdown, {server_initiated_close, 406, _}}, _},
203+
%% Note that lower values (e.g. 300) will cause overflow the byte type here.
204+
%% However, values >= 256 would still be rejected when used by
205+
%% other clients
206+
declare(Ch, Q, 3000)),
207+
rabbit_ct_client_helpers:close_connection(Conn),
208+
passed.
209+
210+
negative_max_priorities(Config) ->
211+
{Conn, Ch} = rabbit_ct_client_helpers:open_connection_and_channel(Config, 0),
212+
Q = <<"negative_max_priorities">>,
213+
?assertExit(
214+
{{shutdown, {server_initiated_close, 406, _}}, _},
215+
declare(Ch, Q, -10)),
216+
rabbit_ct_client_helpers:close_connection(Conn),
217+
passed.
218+
219+
195220
invoke(Config) ->
196221
%% Synthetic test to check the invoke callback, as the bug tested here
197222
%% is only triggered with a race condition.
@@ -669,7 +694,7 @@ get_ok(Ch, Q, Ack, PBin) ->
669694
{#'basic.get_ok'{delivery_tag = DTag}, #amqp_msg{payload = PBin2}} =
670695
amqp_channel:call(Ch, #'basic.get'{queue = Q,
671696
no_ack = Ack =:= no_ack}),
672-
PBin = PBin2,
697+
?assertEqual(PBin, PBin2),
673698
maybe_ack(Ch, Ack, DTag).
674699

675700
get_payload(Ch, Q, Ack, Ps) ->

0 commit comments

Comments
 (0)