AllJoyn: Add recursion checks
This commit is contained in:
parent
34c90f7a3d
commit
8b0e90d62e
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include <epan/packet.h>
|
||||
#include <proto_data.h>
|
||||
#include <epan/expert.h>
|
||||
#include <wsutil/ws_roundup.h>
|
||||
#include <wsutil/str_util.h>
|
||||
|
@ -29,6 +30,9 @@ static dissector_handle_t alljoyn_handle_ardp;
|
|||
/* DBus limits packet length to 2^27. AllJoyn limits it further to 2^17 + 4096 to allow for 2^17 payload */
|
||||
#define MAX_PACKET_LEN (MAX_ARRAY_LEN + 4096)
|
||||
|
||||
/* Arbitrarily chosen. */
|
||||
#define MAX_RECURSION_DEPTH 10
|
||||
|
||||
/* The following are protocols within a frame.
|
||||
The actual value of the handle is set when the various fields are
|
||||
registered in proto_register_AllJoyn() with a call to
|
||||
|
@ -769,13 +773,17 @@ append_struct_signature(proto_item *item,
|
|||
* @param signature_length is a pointer to the length of the signature.
|
||||
*/
|
||||
static void
|
||||
advance_to_end_of_signature(const guint8 **signature,
|
||||
guint8 *signature_length)
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
advance_to_end_of_signature(packet_info *pinfo, const guint8 **signature, guint8 *signature_length)
|
||||
{
|
||||
gboolean done = FALSE;
|
||||
gint8 current_type;
|
||||
gint8 end_type = ARG_INVALID;
|
||||
|
||||
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_AllJoyn_mess);
|
||||
DISSECTOR_ASSERT(recursion_depth <= MAX_RECURSION_DEPTH);
|
||||
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth + 1);
|
||||
|
||||
while (*signature_length > 0 && **signature && !done) {
|
||||
current_type = *(++(*signature));
|
||||
--*signature_length;
|
||||
|
@ -792,15 +800,15 @@ advance_to_end_of_signature(const guint8 **signature,
|
|||
switch(current_type)
|
||||
{
|
||||
case ARG_ARRAY:
|
||||
advance_to_end_of_signature(signature, signature_length);
|
||||
advance_to_end_of_signature(pinfo, signature, signature_length);
|
||||
break;
|
||||
case ARG_STRUCT:
|
||||
end_type = ')';
|
||||
advance_to_end_of_signature(signature, signature_length);
|
||||
advance_to_end_of_signature(pinfo, signature, signature_length);
|
||||
break;
|
||||
case ARG_DICT_ENTRY:
|
||||
end_type = '}';
|
||||
advance_to_end_of_signature(signature, signature_length);
|
||||
advance_to_end_of_signature(pinfo, signature, signature_length);
|
||||
break;
|
||||
|
||||
case ARG_BYTE:
|
||||
|
@ -825,6 +833,7 @@ advance_to_end_of_signature(const guint8 **signature,
|
|||
break;
|
||||
}
|
||||
}
|
||||
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth);
|
||||
}
|
||||
|
||||
/* This is called to add a padding item. There is not padding done for each call made.
|
||||
|
@ -877,6 +886,7 @@ static void add_padding_item(gint padding_start, gint padding_end, tvbuff_t *tvb
|
|||
* parameters come in.
|
||||
*/
|
||||
static gint
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
parse_arg(tvbuff_t *tvb,
|
||||
packet_info *pinfo,
|
||||
proto_item *header_item,
|
||||
|
@ -941,10 +951,14 @@ parse_arg(tvbuff_t *tvb,
|
|||
add_padding_item(padding_start, offset, tvb, tree);
|
||||
|
||||
if(0 == length) {
|
||||
advance_to_end_of_signature(signature, signature_length);
|
||||
advance_to_end_of_signature(pinfo, signature, signature_length);
|
||||
} else {
|
||||
guint8 sig_length_saved = *signature_length - 1;
|
||||
|
||||
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_AllJoyn_mess);
|
||||
DISSECTOR_ASSERT(recursion_depth <= MAX_RECURSION_DEPTH);
|
||||
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth + 1);
|
||||
|
||||
while((offset - starting_offset) < length) {
|
||||
const guint8 *sig_pointer;
|
||||
guint8 remaining_sig_length;
|
||||
|
@ -970,6 +984,7 @@ parse_arg(tvbuff_t *tvb,
|
|||
*signature = sig_pointer;
|
||||
*signature_length = remaining_sig_length;
|
||||
}
|
||||
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth);
|
||||
}
|
||||
|
||||
if(item) {
|
||||
|
@ -1180,14 +1195,20 @@ parse_arg(tvbuff_t *tvb,
|
|||
offset += length;
|
||||
sig_pointer = sig_saved;
|
||||
|
||||
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_AllJoyn_mess);
|
||||
DISSECTOR_ASSERT(recursion_depth <= MAX_RECURSION_DEPTH);
|
||||
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth + 1);
|
||||
|
||||
/* The signature of the variant has now been taken care of. So now take care of the variant data. */
|
||||
while(((sig_pointer - sig_saved) < (length - 1)) && (tvb_reported_length_remaining(tvb, offset) > 0)) {
|
||||
proto_item_append_text(item, "%c", g_ascii_isprint(*sig_pointer) ? *sig_pointer : '?');
|
||||
|
||||
offset = parse_arg(tvb, pinfo, header_item, encoding, offset, tree, is_reply_to,
|
||||
*sig_pointer, field_code, &sig_pointer, &variant_sig_length, field_starting_offset);
|
||||
|
||||
}
|
||||
|
||||
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth);
|
||||
proto_item_append_text(item, "'");
|
||||
proto_item_set_end(item, tvb, offset);
|
||||
}
|
||||
|
@ -1241,6 +1262,10 @@ parse_arg(tvbuff_t *tvb,
|
|||
(*signature)++; /* Advance past the '(' or '{'. */
|
||||
(*signature_length)--;
|
||||
|
||||
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_AllJoyn_mess);
|
||||
DISSECTOR_ASSERT(recursion_depth <= MAX_RECURSION_DEPTH);
|
||||
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth + 1);
|
||||
|
||||
/* *signature should never be NULL but just make sure to avoid potential issues. */
|
||||
while(*signature && **signature && **signature != type_stop
|
||||
&& tvb_reported_length_remaining(tvb, offset) > 0) {
|
||||
|
@ -1258,6 +1283,8 @@ parse_arg(tvbuff_t *tvb,
|
|||
field_starting_offset);
|
||||
}
|
||||
|
||||
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth);
|
||||
|
||||
proto_item_set_end(item, tvb, offset);
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue