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.
This commit is contained in:
Guy Harris 2021-03-28 17:55:23 -07:00
parent 22cf2cb345
commit 2ba52cdc0e
1 changed files with 23 additions and 3 deletions

View File

@ -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 *