From 587aabd3a9457844ab0a22b3f6553321a6216d8b Mon Sep 17 00:00:00 2001 From: Shawn <506895667@qq.com> Date: Fri, 12 Mar 2021 10:54:58 +0800 Subject: [PATCH] fix(emqx): validate mqtt malformed variable byte integer --- src/emqx_frame.erl | 3 +++ test/emqx_frame_SUITE.erl | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/emqx_frame.erl b/src/emqx_frame.erl index a4ef34840b..5fbfc945a9 100644 --- a/src/emqx_frame.erl +++ b/src/emqx_frame.erl @@ -107,6 +107,9 @@ parse_remaining_len(<<0:8, Rest/binary>>, Header, 1, 0, Options) -> %% Match PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK... parse_remaining_len(<<0:1, 2:7, Rest/binary>>, Header, 1, 0, Options) -> parse_frame(Rest, Header, 2, Options); +parse_remaining_len(<<1:1, _Len:7, _Rest/binary>>, _Header, Multiplier, _Value, _Options) + when Multiplier > 2097152 -> + error(malformed_variable_byte_integer); parse_remaining_len(<<1:1, Len:7, Rest/binary>>, Header, Multiplier, Value, Options) -> parse_remaining_len(Rest, Header, Multiplier * ?HIGHBIT, Value + Len * Multiplier, Options); parse_remaining_len(<<0:1, Len:7, Rest/binary>>, Header, Multiplier, Value, diff --git a/test/emqx_frame_SUITE.erl b/test/emqx_frame_SUITE.erl index 8de05e7349..a9340e5140 100644 --- a/test/emqx_frame_SUITE.erl +++ b/test/emqx_frame_SUITE.erl @@ -23,7 +23,8 @@ -include_lib("eunit/include/eunit.hrl"). all() -> - [{group, connect}, + [{group, parse}, + {group, connect}, {group, connack}, {group, publish}, {group, puback}, @@ -36,7 +37,10 @@ all() -> {group, auth}]. groups() -> - [{connect, [parallel], + [{parse, [parallel], + [t_parse_frame_malformed_variable_byte_integer + ]}, + {connect, [parallel], [serialize_parse_connect, serialize_parse_v3_connect, serialize_parse_v4_connect, @@ -105,6 +109,12 @@ init_per_group(_Group, Config) -> end_per_group(_Group, _Config) -> ok. +t_parse_frame_malformed_variable_byte_integer(_) -> + MalformedPayload = << <<16#80>> || _ <- lists:seq(1, 6) >>, + ParseState = emqx_frame:initial_parse_state(#{}), + ?assertError(malformed_variable_byte_integer, + emqx_frame:parse(MalformedPayload, ParseState)). + serialize_parse_connect(_) -> Packet1 = ?CONNECT_PACKET(#mqtt_packet_connect{}), ?assertEqual(Packet1, parse_serialize(Packet1)),