From 9832eea250319578590068af01fdccb744809721 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Mon, 27 Sep 2021 14:52:11 +0800 Subject: [PATCH] fix(frame): safely parsings. --- apps/emqx/src/emqx_frame.erl | 43 ++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/apps/emqx/src/emqx_frame.erl b/apps/emqx/src/emqx_frame.erl index dab987f60..c38d2fd9c 100644 --- a/apps/emqx/src/emqx_frame.erl +++ b/apps/emqx/src/emqx_frame.erl @@ -444,7 +444,10 @@ parse_property(<<16#28, Val, Bin/binary>>, Props) -> parse_property(<<16#29, Val, Bin/binary>>, Props) -> parse_property(Bin, Props#{'Subscription-Identifier-Available' => Val}); parse_property(<<16#2A, Val, Bin/binary>>, Props) -> - parse_property(Bin, Props#{'Shared-Subscription-Available' => Val}). + parse_property(Bin, Props#{'Shared-Subscription-Available' => Val}); +parse_property(<>, _Props) -> + ?PARSE_ERR(#{invalid_property_code => Property}). +%% TODO: invalid property in specific packet. parse_variable_byte_integer(Bin) -> parse_variable_byte_integer(Bin, 1, 0). @@ -468,7 +471,23 @@ parse_reason_codes(Bin) -> parse_utf8_pair(<>) -> - {{Key, Val}, Rest}. + {{Key, Val}, Rest}; +parse_utf8_pair(<>) + when LenK > byte_size(Rest) -> + ?PARSE_ERR(#{ hint => user_property_not_enough_bytes + , parsed_key_length => LenK + , remaining_bytes_length => byte_size(Rest)}); +parse_utf8_pair(<>) + when LenV > byte_size(Rest) -> + ?PARSE_ERR(#{ hint => malformed_user_property_value + , parsed_key_length => LenK + , parsed_value_length => LenV + , remaining_bytes_length => byte_size(Rest)}); +parse_utf8_pair(Bin) + when 4 > byte_size(Bin) -> + ?PARSE_ERR(#{ hint => user_property_not_enough_bytes + , total_bytes => byte_size(Bin)}). parse_utf8_string(Bin, false) -> {undefined, Bin}; @@ -476,10 +495,26 @@ parse_utf8_string(Bin, true) -> parse_utf8_string(Bin). parse_utf8_string(<>) -> - {Str, Rest}. + {Str, Rest}; +parse_utf8_string(<>) + when Len > byte_size(Rest) -> + ?PARSE_ERR(#{ hint => malformed_utf8_string + , parsed_length => Len + , remaining_bytes_length => byte_size(Rest)}); +parse_utf8_string(Bin) + when 2 > byte_size(Bin) -> + ?PARSE_ERR(malformed_utf8_string_length). parse_binary_data(<>) -> - {Data, Rest}. + {Data, Rest}; +parse_binary_data(<>) + when Len > byte_size(Rest) -> + ?PARSE_ERR(#{ hint => malformed_binary_data + , parsed_length => Len + , remaining_bytes_length => byte_size(Rest)}); +parse_binary_data(Bin) + when 2 > byte_size(Bin) -> + ?PARSE_ERR(malformed_binary_data_length). %%-------------------------------------------------------------------- %% Serialize MQTT Packet