SMB2: Add recursion checks

This commit is contained in:
Gerald Combs 2024-02-22 18:50:24 -08:00
parent 40b210e1d6
commit 1515b211e2
1 changed files with 26 additions and 1 deletions

View File

@ -22,6 +22,7 @@
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <epan/prefs.h>
#include <epan/proto_data.h>
#include <epan/expert.h>
#include <epan/tap.h>
#include <epan/srt_table.h>
@ -1289,6 +1290,7 @@ static const value_string file_full_ea_information_flags[] = {
{ 0, NULL }
};
#define MAX_RECURSION_DEPTH 10 // Arbitrarily chosen.
static int dissect_windows_sockaddr_storage(tvbuff_t *, packet_info *, proto_tree *, int, int);
static void dissect_smb2_error_data(tvbuff_t *, packet_info *, proto_tree *, int, int, smb2_info_t *);
@ -4070,6 +4072,7 @@ dissect_smb2_STATUS_STOPPED_ON_SYMLINK(tvbuff_t *tvb, packet_info *pinfo _U_, pr
}
static int
// NOLINTNEXTLINE(misc-no-recursion)
dissect_smb2_error_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, int offset, smb2_info_t *si _U_)
{
proto_tree *tree;
@ -4098,6 +4101,7 @@ dissect_smb2_error_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *pa
* Assumes it is being called with a sub-tvb (dissects at offsets 0)
*/
static void
// NOLINTNEXTLINE(misc-no-recursion)
dissect_smb2_error_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
int error_context_count, int error_id,
smb2_info_t *si _U_)
@ -4128,8 +4132,13 @@ dissect_smb2_error_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *paren
break;
}
} else {
for (i = 0; i < error_context_count; i++)
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_smb2);
DISSECTOR_ASSERT(recursion_depth <= MAX_RECURSION_DEPTH);
p_set_proto_depth(pinfo, proto_smb2, recursion_depth + 1);
for (i = 0; i < error_context_count; i++) {
offset += dissect_smb2_error_context(tvb, pinfo, tree, offset, si);
}
p_set_proto_depth(pinfo, proto_smb2, recursion_depth);
}
}
@ -7460,6 +7469,7 @@ dissect_windows_sockaddr_storage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
#define NETWORK_INTERFACE_CAP_RDMA 0x00000002
static void
// NOLINTNEXTLINE(misc-no-recursion)
dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
guint32 next_offset;
@ -7541,7 +7551,11 @@ dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tre
next_tvb = tvb_new_subset_remaining(tvb, next_offset);
/* next extra info */
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_smb2);
DISSECTOR_ASSERT(recursion_depth <= MAX_RECURSION_DEPTH);
p_set_proto_depth(pinfo, proto_smb2, recursion_depth + 1);
dissect_smb2_NETWORK_INTERFACE_INFO(next_tvb, pinfo, parent_tree);
p_set_proto_depth(pinfo, proto_smb2, recursion_depth);
}
}
@ -9444,6 +9458,7 @@ get_create_context_data_tag_dissectors(const char *tag)
}
static void
// NOLINTNEXTLINE(misc-no-recursion)
dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, smb2_info_t *si)
{
offset_length_buffer_t tag_olb;
@ -9519,7 +9534,11 @@ dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pa
chain_tvb = tvb_new_subset_remaining(tvb, chain_offset);
/* next extra info */
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_smb2);
DISSECTOR_ASSERT(recursion_depth <= MAX_RECURSION_DEPTH);
p_set_proto_depth(pinfo, proto_smb2, recursion_depth + 1);
dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si);
p_set_proto_depth(pinfo, proto_smb2, recursion_depth);
}
}
@ -11343,6 +11362,7 @@ dissect_smb2_signature(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree
}
static int
// NOLINTNEXTLINE(misc-no-recursion)
dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolean first_in_chain)
{
int msg_type;
@ -11386,6 +11406,10 @@ dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolea
break;
}
unsigned recursion_depth = p_get_proto_depth(pinfo, proto_smb2);
DISSECTOR_ASSERT(recursion_depth <= MAX_RECURSION_DEPTH);
p_set_proto_depth(pinfo, proto_smb2, recursion_depth + 1);
/* find which conversation we are part of and get the data for that
* conversation
*/
@ -11700,6 +11724,7 @@ dissect_smb2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, gboolea
offset = dissect_smb2(next_tvb, pinfo, parent_tree, FALSE);
}
p_set_proto_depth(pinfo, proto_smb2, recursion_depth);
return offset;
}