diff options
| author | Michael Klishin <michael@clojurewerkz.org> | 2018-05-11 00:05:07 -0500 |
|---|---|---|
| committer | Michael Klishin <michael@clojurewerkz.org> | 2018-05-11 00:05:07 -0500 |
| commit | 08636f98cef491c62bf67d6b865333d65f0d3b9f (patch) | |
| tree | faac1840593b90e04abc6e291568b6f7ede50cb6 | |
| parent | 54c9b85836199597fb3b633fdeb2d725ab9d45ad (diff) | |
| download | rabbitmq-server-git-08636f98cef491c62bf67d6b865333d65f0d3b9f.tar.gz | |
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]
| -rw-r--r-- | src/rabbit_amqqueue.erl | 9 | ||||
| -rw-r--r-- | src/rabbit_priority_queue.erl | 13 | ||||
| -rw-r--r-- | test/priority_queue_SUITE.erl | 29 |
3 files changed, 43 insertions, 8 deletions
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl index ac79d56358..eb00729baa 100644 --- a/src/rabbit_amqqueue.erl +++ b/src/rabbit_amqqueue.erl @@ -575,7 +575,7 @@ declare_args() -> {<<"x-dead-letter-routing-key">>, fun check_dlxrk_arg/2}, {<<"x-max-length">>, fun check_non_neg_int_arg/2}, {<<"x-max-length-bytes">>, fun check_non_neg_int_arg/2}, - {<<"x-max-priority">>, fun check_non_neg_int_arg/2}, + {<<"x-max-priority">>, fun check_max_priority_arg/2}, {<<"x-overflow">>, fun check_overflow/2}, {<<"x-queue-mode">>, fun check_queue_mode/2}]. @@ -611,6 +611,13 @@ check_message_ttl_arg({Type, Val}, Args) -> Error -> Error end. +check_max_priority_arg({Type, Val}, Args) -> + case check_non_neg_int_arg({Type, Val}, Args) of + ok when Val =< 255 -> ok; + ok -> {error, {max_value_exceeded, Val}}; + Error -> Error + end. + %% Note that the validity of x-dead-letter-exchange is already verified %% by rabbit_channel's queue.declare handler. check_dlxname_arg({longstr, _}, _) -> ok; diff --git a/src/rabbit_priority_queue.erl b/src/rabbit_priority_queue.erl index 5786bed6ba..b1eb83dddc 100644 --- a/src/rabbit_priority_queue.erl +++ b/src/rabbit_priority_queue.erl @@ -128,11 +128,14 @@ collapse_recovery(QNames, DupNames, Recovery) -> priorities(#amqqueue{arguments = Args}) -> Ints = [long, short, signedint, byte, unsignedbyte, unsignedshort, unsignedint], case rabbit_misc:table_lookup(Args, <<"x-max-priority">>) of - {Type, Max} -> case lists:member(Type, Ints) of - false -> none; - true -> lists:reverse(lists:seq(0, Max)) - end; - _ -> none + {Type, RequestedMax} -> + case lists:member(Type, Ints) of + false -> none; + true -> + Max = min(RequestedMax, ?MAX_SUPPORTED_PRIORITY), + lists:reverse(lists:seq(0, Max)) + end; + _ -> none end. %%---------------------------------------------------------------------------- diff --git a/test/priority_queue_SUITE.erl b/test/priority_queue_SUITE.erl index a1ae66dbbb..cfa98b94c7 100644 --- a/test/priority_queue_SUITE.erl +++ b/test/priority_queue_SUITE.erl @@ -17,6 +17,7 @@ -module(priority_queue_SUITE). -include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). -include_lib("amqp_client/include/amqp_client.hrl"). -compile(export_all). @@ -46,7 +47,9 @@ groups() -> simple_order, straight_through, invoke, - gen_server2_stats + gen_server2_stats, + negative_max_priorities, + max_priorities_above_hard_limit ]}, {cluster_size_3, [], [ mirror_queue_auto_ack, @@ -192,6 +195,28 @@ straight_through(Config) -> rabbit_ct_client_helpers:close_connection(Conn), passed. +max_priorities_above_hard_limit(Config) -> + {Conn, Ch} = rabbit_ct_client_helpers:open_connection_and_channel(Config, 0), + Q = <<"max_priorities_above_hard_limit">>, + ?assertExit( + {{shutdown, {server_initiated_close, 406, _}}, _}, + %% Note that lower values (e.g. 300) will cause overflow the byte type here. + %% However, values >= 256 would still be rejected when used by + %% other clients + declare(Ch, Q, 3000)), + rabbit_ct_client_helpers:close_connection(Conn), + passed. + +negative_max_priorities(Config) -> + {Conn, Ch} = rabbit_ct_client_helpers:open_connection_and_channel(Config, 0), + Q = <<"negative_max_priorities">>, + ?assertExit( + {{shutdown, {server_initiated_close, 406, _}}, _}, + declare(Ch, Q, -10)), + rabbit_ct_client_helpers:close_connection(Conn), + passed. + + invoke(Config) -> %% Synthetic test to check the invoke callback, as the bug tested here %% is only triggered with a race condition. @@ -669,7 +694,7 @@ get_ok(Ch, Q, Ack, PBin) -> {#'basic.get_ok'{delivery_tag = DTag}, #amqp_msg{payload = PBin2}} = amqp_channel:call(Ch, #'basic.get'{queue = Q, no_ack = Ack =:= no_ack}), - PBin = PBin2, + ?assertEqual(PBin, PBin2), maybe_ack(Ch, Ack, DTag). get_payload(Ch, Q, Ack, Ps) -> |
