Add a routine to check whether all bytes implied by a 64-bit length exist.

This lets us blow up with oversized 64-bit length values, before casting
them to the 31-bit lengths we can actually handle in Wireshark, rather
than blindly casting them with weird results.

Use that in the MySQL dissector, and, if we get past the test, cast the
lengths to int to squelch warnings.

Change-Id: I3a5e9bd0027fa4ddcb9622f77952dba8f6b23c27
Reviewed-on: https://code.wireshark.org/review/3362
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2014-08-02 11:32:42 -07:00
parent d8880874f2
commit f4d24216be
3 changed files with 30 additions and 3 deletions

View File

@ -834,16 +834,18 @@ add_connattrs_entry_to_tree(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *t
proto_tree_add_uint64(connattrs_tree, hf_mysql_connattrs_name_length, tvb, offset, lenfle, lenstr);
offset += lenfle;
tvb_ensure_bytes_exist64(tvb, offset, lenstr);
proto_tree_add_item(connattrs_tree, hf_mysql_connattrs_name, tvb, offset, (gint)lenstr, ENC_ASCII|ENC_NA);
proto_item_append_text(ti, " - %s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, lenstr, ENC_ASCII|ENC_NA));
proto_item_append_text(ti, " - %s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, (int)lenstr, ENC_ASCII|ENC_NA));
offset += (int)lenstr;
lenfle = tvb_get_fle(tvb, offset, &lenstr, NULL);
proto_tree_add_uint64(connattrs_tree, hf_mysql_connattrs_value_length, tvb, offset, lenfle, lenstr);
offset += lenfle;
tvb_ensure_bytes_exist64(tvb, offset, lenstr);
proto_tree_add_item(connattrs_tree, hf_mysql_connattrs_value, tvb, offset, (gint)lenstr, ENC_ASCII|ENC_NA);
proto_item_append_text(ti, ": %s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, lenstr, ENC_ASCII|ENC_NA));
proto_item_append_text(ti, ": %s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, (int)lenstr, ENC_ASCII|ENC_NA));
offset += (int)lenstr;
proto_item_set_len(ti, offset - orig_offset);
@ -933,7 +935,8 @@ mysql_dissect_login(tvbuff_t *tvb, packet_info *pinfo, int offset,
{
proto_tree *connattrs_tree;
int lenfle;
guint64 length, connattrs_length;
guint64 connattrs_length;
int length;
lenfle = tvb_get_fle(tvb, offset, &connattrs_length, NULL);
tf = proto_tree_add_item(login_tree, hf_mysql_connattrs, tvb, offset, (guint32)connattrs_length, ENC_ASCII|ENC_NA);

View File

@ -502,6 +502,24 @@ tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
return TRUE;
}
/* Validates that 'length' bytes, where 'length' is a 64-bit unsigned
* integer, are available starting from offset (pos/neg). Throws an
* exception if they aren't. */
void
tvb_ensure_bytes_exist64(const tvbuff_t *tvb, const gint offset, const guint64 length)
{
/*
* Make sure the value fits in a signed integer; if not, assume
* that means that it's too big.
*/
if (length > G_MAXINT) {
THROW(ReportedBoundsError);
}
/* OK, now cast it and try it with tvb_ensure_bytes_exist(). */
tvb_ensure_bytes_exist(tvb, offset, (gint)length);
}
/* Validates that 'length' bytes are available starting from
* offset (pos/neg). Throws an exception if they aren't. */
void

View File

@ -248,6 +248,12 @@ WS_DLL_PUBLIC guint tvb_ensure_captured_length_remaining(const tvbuff_t *tvb,
WS_DLL_PUBLIC gboolean tvb_bytes_exist(const tvbuff_t *tvb, const gint offset,
const gint length);
/** Checks that the bytes referred to by 'offset'/'length', where 'length'
* is a 64-bit unsigned integer, actually exist in the buffer, and throws
* an exception if they aren't. */
WS_DLL_PUBLIC void tvb_ensure_bytes_exist64(const tvbuff_t *tvb,
const gint offset, const guint64 length);
/** Checks that the bytes referred to by 'offset'/'length' actually exist
* in the buffer, and throws an exception if they aren't. */
WS_DLL_PUBLIC void tvb_ensure_bytes_exist(const tvbuff_t *tvb,