forked from osmocom/wireshark
![Guy Harris](/assets/img/avatar_default.png)
1) A value that fits in a 32-bit unsigned integer may take more than 4 octets - the uppermost bit of the octet is a "more octets follows" flag, so 4 octets contain only 7*4 - 28 bits of value, so a fifth octet preceding that with the upper 3 bits zero could result in a value that fits in 32 bits, and further octets of 0x80 just add further leading zeroes. We should, instead, check for *overflow*, meaning that if we add more bits at the bottom, the result is *less* than the previous value. 2) When the result overflows, we should clamp it a UINT_MAX, rather than setting it to zero, and should keep accumulating octets, so that we return the correct octet count. That prevents infinite loops where the item's length, and the item itself, are considered zero-length. This should fix bug 14738. Bug: 14738 Change-Id: I1d1b60e22f169959c1573b1fcb7e010e027b5132 Reviewed-on: https://code.wireshark.org/review/27986 Reviewed-by: Guy Harris <guy@alum.mit.edu>
88 lines
2.2 KiB
C
88 lines
2.2 KiB
C
/* packet-wap.c
|
|
*
|
|
* Utility routines for WAP dissectors
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* WAP dissector based on original work by Ben Fowler
|
|
* Updated by Neil Hunter <neil.hunter@energis-squared.com>
|
|
* WTLS support by Alexandre P. Ferreira (Splice IP)
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <epan/packet.h>
|
|
#include "packet-wap.h"
|
|
|
|
/*
|
|
* Accessor to retrieve variable length int as used in WAP protocol.
|
|
* The value is encoded in the lower 7 bits. If the top bit is set, then the
|
|
* value continues into the next byte.
|
|
* The octetCount parameter holds the number of bytes read in order to return
|
|
* the final value. Can be pre-initialised to start at offset+count.
|
|
*/
|
|
guint
|
|
tvb_get_guintvar (tvbuff_t *tvb, guint offset,
|
|
guint *octetCount, packet_info *pinfo, expert_field *ei)
|
|
{
|
|
guint value = 0, previous_value;
|
|
guint octet;
|
|
guint counter = 0;
|
|
|
|
#ifdef DEBUG
|
|
fprintf (stderr,
|
|
"dissect_wap: Starting tvb_get_guintvar at offset %d\n", offset);
|
|
#endif
|
|
|
|
do {
|
|
octet = tvb_get_guint8 (tvb, offset+counter);
|
|
|
|
counter++;
|
|
|
|
previous_value = value;
|
|
value <<= 7; /* Value only exists in 7 of the 8 bits */
|
|
value += (octet & 0x7F);
|
|
if (value < previous_value) {
|
|
/* overflow; clamp the value at UINT_MAX */
|
|
proto_tree_add_expert(NULL, pinfo, ei, tvb, offset, counter);
|
|
value = UINT_MAX;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr,
|
|
"dissect_wap: computing: octet is %d (0x%02x), count=%d, value=%d\n",
|
|
octet, octet, counter, value);
|
|
#endif
|
|
} while (octet & 0x80);
|
|
|
|
#ifdef DEBUG
|
|
fprintf (stderr,
|
|
"dissect_wap: Leaving tvb_get_guintvar count=%d, value=%u\n",
|
|
counter, value);
|
|
#endif
|
|
|
|
if (octetCount)
|
|
*octetCount = counter;
|
|
|
|
return value;
|
|
}
|
|
|
|
/*
|
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
|
*
|
|
* Local variables:
|
|
* c-basic-offset: 4
|
|
* tab-width: 8
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
*/
|