AllJoyn: Add recursion checks
This commit is contained in:
parent
34c90f7a3d
commit
8b0e90d62e
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <epan/packet.h>
|
#include <epan/packet.h>
|
||||||
|
#include <proto_data.h>
|
||||||
#include <epan/expert.h>
|
#include <epan/expert.h>
|
||||||
#include <wsutil/ws_roundup.h>
|
#include <wsutil/ws_roundup.h>
|
||||||
#include <wsutil/str_util.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 */
|
/* 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)
|
#define MAX_PACKET_LEN (MAX_ARRAY_LEN + 4096)
|
||||||
|
|
||||||
|
/* Arbitrarily chosen. */
|
||||||
|
#define MAX_RECURSION_DEPTH 10
|
||||||
|
|
||||||
/* The following are protocols within a frame.
|
/* The following are protocols within a frame.
|
||||||
The actual value of the handle is set when the various fields are
|
The actual value of the handle is set when the various fields are
|
||||||
registered in proto_register_AllJoyn() with a call to
|
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.
|
* @param signature_length is a pointer to the length of the signature.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
advance_to_end_of_signature(const guint8 **signature,
|
// NOLINTNEXTLINE(misc-no-recursion)
|
||||||
guint8 *signature_length)
|
advance_to_end_of_signature(packet_info *pinfo, const guint8 **signature, guint8 *signature_length)
|
||||||
{
|
{
|
||||||
gboolean done = FALSE;
|
gboolean done = FALSE;
|
||||||
gint8 current_type;
|
gint8 current_type;
|
||||||
gint8 end_type = ARG_INVALID;
|
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) {
|
while (*signature_length > 0 && **signature && !done) {
|
||||||
current_type = *(++(*signature));
|
current_type = *(++(*signature));
|
||||||
--*signature_length;
|
--*signature_length;
|
||||||
|
@ -792,15 +800,15 @@ advance_to_end_of_signature(const guint8 **signature,
|
||||||
switch(current_type)
|
switch(current_type)
|
||||||
{
|
{
|
||||||
case ARG_ARRAY:
|
case ARG_ARRAY:
|
||||||
advance_to_end_of_signature(signature, signature_length);
|
advance_to_end_of_signature(pinfo, signature, signature_length);
|
||||||
break;
|
break;
|
||||||
case ARG_STRUCT:
|
case ARG_STRUCT:
|
||||||
end_type = ')';
|
end_type = ')';
|
||||||
advance_to_end_of_signature(signature, signature_length);
|
advance_to_end_of_signature(pinfo, signature, signature_length);
|
||||||
break;
|
break;
|
||||||
case ARG_DICT_ENTRY:
|
case ARG_DICT_ENTRY:
|
||||||
end_type = '}';
|
end_type = '}';
|
||||||
advance_to_end_of_signature(signature, signature_length);
|
advance_to_end_of_signature(pinfo, signature, signature_length);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_BYTE:
|
case ARG_BYTE:
|
||||||
|
@ -825,6 +833,7 @@ advance_to_end_of_signature(const guint8 **signature,
|
||||||
break;
|
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.
|
/* 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.
|
* parameters come in.
|
||||||
*/
|
*/
|
||||||
static gint
|
static gint
|
||||||
|
// NOLINTNEXTLINE(misc-no-recursion)
|
||||||
parse_arg(tvbuff_t *tvb,
|
parse_arg(tvbuff_t *tvb,
|
||||||
packet_info *pinfo,
|
packet_info *pinfo,
|
||||||
proto_item *header_item,
|
proto_item *header_item,
|
||||||
|
@ -941,10 +951,14 @@ parse_arg(tvbuff_t *tvb,
|
||||||
add_padding_item(padding_start, offset, tvb, tree);
|
add_padding_item(padding_start, offset, tvb, tree);
|
||||||
|
|
||||||
if(0 == length) {
|
if(0 == length) {
|
||||||
advance_to_end_of_signature(signature, signature_length);
|
advance_to_end_of_signature(pinfo, signature, signature_length);
|
||||||
} else {
|
} else {
|
||||||
guint8 sig_length_saved = *signature_length - 1;
|
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) {
|
while((offset - starting_offset) < length) {
|
||||||
const guint8 *sig_pointer;
|
const guint8 *sig_pointer;
|
||||||
guint8 remaining_sig_length;
|
guint8 remaining_sig_length;
|
||||||
|
@ -970,6 +984,7 @@ parse_arg(tvbuff_t *tvb,
|
||||||
*signature = sig_pointer;
|
*signature = sig_pointer;
|
||||||
*signature_length = remaining_sig_length;
|
*signature_length = remaining_sig_length;
|
||||||
}
|
}
|
||||||
|
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(item) {
|
if(item) {
|
||||||
|
@ -1180,14 +1195,20 @@ parse_arg(tvbuff_t *tvb,
|
||||||
offset += length;
|
offset += length;
|
||||||
sig_pointer = sig_saved;
|
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. */
|
/* 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)) {
|
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 : '?');
|
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,
|
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);
|
*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_append_text(item, "'");
|
||||||
proto_item_set_end(item, tvb, offset);
|
proto_item_set_end(item, tvb, offset);
|
||||||
}
|
}
|
||||||
|
@ -1241,6 +1262,10 @@ parse_arg(tvbuff_t *tvb,
|
||||||
(*signature)++; /* Advance past the '(' or '{'. */
|
(*signature)++; /* Advance past the '(' or '{'. */
|
||||||
(*signature_length)--;
|
(*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. */
|
/* *signature should never be NULL but just make sure to avoid potential issues. */
|
||||||
while(*signature && **signature && **signature != type_stop
|
while(*signature && **signature && **signature != type_stop
|
||||||
&& tvb_reported_length_remaining(tvb, offset) > 0) {
|
&& tvb_reported_length_remaining(tvb, offset) > 0) {
|
||||||
|
@ -1258,6 +1283,8 @@ parse_arg(tvbuff_t *tvb,
|
||||||
field_starting_offset);
|
field_starting_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_set_proto_depth(pinfo, proto_AllJoyn_mess, recursion_depth);
|
||||||
|
|
||||||
proto_item_set_end(item, tvb, offset);
|
proto_item_set_end(item, tvb, offset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue