forked from osmocom/wireshark
epan: Make AT_NUMERIC behave more safely
Implement a better handling of byte sizes as well as preventing possible memory bleeds Fixes: 18147
This commit is contained in:
parent
39fc49b792
commit
4c768f54a7
|
@ -28,6 +28,12 @@ extern "C" {
|
|||
* If an address type is added here, it must be "registered" within address_types.c
|
||||
* For dissector address types, just use the address_type_dissector_register function
|
||||
* from address_types.h
|
||||
*
|
||||
* AT_NUMERIC - a numeric address type can consist of a guint8, guint16, guint32 or guint64
|
||||
* little-endian value. If no correct length is provided, to avoid data bleed, a guint8 is
|
||||
* assumed. If the value represented is originating from a big-endian system, it is the
|
||||
* responsibility of the dissector to do the proper conversion. Only representation (aka
|
||||
* conversion of value to string) is implemented for this type.
|
||||
*/
|
||||
typedef enum {
|
||||
AT_NONE, /* no link-layer address */
|
||||
|
@ -42,7 +48,7 @@ typedef enum {
|
|||
AT_IB, /* Infiniband GID/LID */
|
||||
AT_AX25, /* AX.25 */
|
||||
AT_VINES, /* Banyan Vines address */
|
||||
AT_NUMERIC, /* Numeric address type */
|
||||
AT_NUMERIC, /* Numeric address type. */
|
||||
|
||||
AT_END_OF_LIST /* Must be last in list */
|
||||
} address_type;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "wsutil/str_util.h"
|
||||
#include "wsutil/inet_addr.h"
|
||||
#include <wsutil/ws_assert.h>
|
||||
#include <wsutil/pint.h>
|
||||
|
||||
struct _address_type_t {
|
||||
int addr_type; /* From address_type enumeration or registered value */
|
||||
|
@ -522,19 +523,44 @@ static int vines_len(void)
|
|||
* AT_NUMERIC
|
||||
******************************************************************************/
|
||||
|
||||
static int numeric_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
|
||||
{
|
||||
const guint32 *addr_data = (const guint32 *)addr->data;
|
||||
|
||||
memset(buf, '\0', 14);
|
||||
snprintf(buf, 14, "%d", *addr_data);
|
||||
|
||||
return (int)strlen(buf);
|
||||
}
|
||||
/* G_MAXUINT64 is defined as 0xffffffffffffffffU which in itself represents
|
||||
* 18,446,744,073,709,551,615 as decimal, which has 20 characters. Adding 21
|
||||
* as for null-byte termination.
|
||||
* All values are derived from the counterparts defined in glib/basic-types */
|
||||
const size_t MAX_UINT64_WIDTH = 21;
|
||||
const size_t MAX_UINT32_WIDTH = 11;
|
||||
const size_t MAX_UINT16_WIDTH = 6;
|
||||
const size_t MAX_UINT8_WIDTH = 4;
|
||||
|
||||
static int numeric_addr_str_len(const address* addr _U_)
|
||||
{
|
||||
return 14;
|
||||
if (addr->len == (int) sizeof(guint64)) {
|
||||
return (int) MAX_UINT64_WIDTH;
|
||||
} else if (addr->len == (int) sizeof(guint32)) {
|
||||
return (int) MAX_UINT32_WIDTH;
|
||||
} else if (addr->len == (int) sizeof(guint16)) {
|
||||
return (int) MAX_UINT16_WIDTH;
|
||||
}
|
||||
|
||||
return (int) MAX_UINT8_WIDTH;
|
||||
}
|
||||
|
||||
static int numeric_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
|
||||
{
|
||||
int len = numeric_addr_str_len(addr);
|
||||
|
||||
memset(buf, '\0', len);
|
||||
if (addr->len == (int) sizeof(guint64)) {
|
||||
snprintf(buf, len, "%"PRIu64, pletoh64(addr->data));
|
||||
} else if (addr->len == (int) sizeof(guint32)) {
|
||||
snprintf(buf, len, "%u", pletoh32(addr->data));
|
||||
} else if (addr->len == (int) sizeof(guint16)) {
|
||||
snprintf(buf, len, "%u", pletoh16(addr->data));
|
||||
} else {
|
||||
snprintf(buf, len, "%u", *((guint8*) (addr->data)));
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
Loading…
Reference in New Issue