aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tvbuff_subset.c
diff options
context:
space:
mode:
authorGuy Harris <gharris@sonic.net>2021-03-28 17:55:23 -0700
committerGuy Harris <gharris@sonic.net>2021-03-29 01:02:47 +0000
commit2ba52cdc0e4216dafdfc32498fc0210c99449ec9 (patch)
tree44ff0f94da1ee954efda01f4fd00dbd80abace04 /epan/tvbuff_subset.c
parent22cf2cb345b16f9783165e9cfc80ed9a97a11ca0 (diff)
tvbuff_subset: fix its implementation of string scanning.
Both subset_find_guint8() and subset_pbrk_guint8() pass the parent tvbuff to tvb_find_guint8()/tvb_ws_mempbrk_pattern_guint8(), along with the offset in that tvbuff. That means that the offset they get back is relative to that tvbuff, so it must be adjusted to be relative to the tvbuff *they* were handed. For subsets of frame and "real data" tvbuffs, there's a single lump of data containing the content of the subset tvbuff, so they go through the "fast path" and get the offset correct, bypassing the broken code; that's the vast majority of calls to those routines. For subsets of *composite* tvbuffs, however, they don't go through the "fast path", and this bug shows up. This causes both crashes and misdissection of HTTP if the link-layer is PPP with Van Jacobson compression, as the decompression uses composite tvbuffs. Fixes #17254 and its many soon-to-be-duplicates.
Diffstat (limited to 'epan/tvbuff_subset.c')
-rw-r--r--epan/tvbuff_subset.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/epan/tvbuff_subset.c b/epan/tvbuff_subset.c
index c9522df9fb..52a332d878 100644
--- a/epan/tvbuff_subset.c
+++ b/epan/tvbuff_subset.c
@@ -1,4 +1,4 @@
-/* tvbuff_real.c
+/* tvbuff_subset.c
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
*
@@ -62,16 +62,36 @@ static gint
subset_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
+ gint result;
- return tvb_find_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, needle);
+ result = tvb_find_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, needle);
+ if (result == -1)
+ return result;
+
+ /*
+ * Make the result relative to the beginning of the tvbuff we
+ * were handed, *not* relative to the beginning of its parent
+ * tvbuff.
+ */
+ return result - subset_tvb->subset.offset;
}
static gint
subset_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
+ gint result;
- return tvb_ws_mempbrk_pattern_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, pattern, found_needle);
+ result = tvb_ws_mempbrk_pattern_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, pattern, found_needle);
+ if (result == -1)
+ return result;
+
+ /*
+ * Make the result relative to the beginning of the tvbuff we
+ * were handed, *not* relative to the beginning of its parent
+ * tvbuff.
+ */
+ return result - subset_tvb->subset.offset;
}
static tvbuff_t *