aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2008-08-05 02:23:35 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2008-08-05 02:23:35 +0000
commit230d917776d73a08b0e4dc11d2fc04a5678fc792 (patch)
tree02407e766260b6514816a5b3c0e51ab2f6a2c0ed
parent6916eaf58779ba194d63a86200001f5523b790e1 (diff)
Add a debug helper for EP memory corruption
if compiled in and the env var WIRESHARK_DEBUG_EP_CANARY is set: will check for canary integrity at every call to EP_CHECK_CANARY() if corruption is found it exits pronting the prior location and the location in which corruption was found. Hopefully it stops running while the corruptor is still in the stack. see EP_CHECK_CANARY() calls in packet.c as an example. svn path=/trunk/; revision=25927
-rw-r--r--epan/emem.c54
-rw-r--r--epan/emem.h15
-rw-r--r--epan/packet.c19
3 files changed, 85 insertions, 3 deletions
diff --git a/epan/emem.c b/epan/emem.c
index 4545520f96..be64881b04 100644
--- a/epan/emem.c
+++ b/epan/emem.c
@@ -42,6 +42,7 @@
#endif
#include <glib.h>
+
#include <proto.h>
#include "emem.h"
@@ -100,7 +101,9 @@ static int dev_zero_fd;
#ifdef DEBUG_USE_CANARIES
#define EMEM_CANARY_SIZE 8
#define EMEM_CANARY_DATA_SIZE (EMEM_CANARY_SIZE * 2 - 1)
-static guint8 ep_canary[EMEM_CANARY_DATA_SIZE], se_canary[EMEM_CANARY_DATA_SIZE];
+
+/* this should be static, but if it were gdb would had problems finding it */
+guint8 ep_canary[EMEM_CANARY_DATA_SIZE], se_canary[EMEM_CANARY_DATA_SIZE];
#endif /* DEBUG_USE_CANARIES */
typedef struct _emem_chunk_t {
@@ -173,6 +176,50 @@ emem_canary_pad (size_t allocation) {
#endif
#endif /* DEBUG_USE_CANARIES */
+/* used for debugging canaries, will block */
+#ifdef DEBUG_INTENSE_CANARY_CHECKS
+gboolean intense_canary_checking = FALSE;
+
+/* used to intensivelly check ep canaries
+ */
+void ep_check_canary_integrity(const char* fmt, ...) {
+ va_list ap;
+ static gchar there[128] = {
+ 'L','a','u','n','c','h',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+ gchar here[128];
+ emem_chunk_t* npc = NULL;
+
+ if (! intense_canary_checking ) return;
+
+ here[126] = '\0';
+ here[127] = '\0';
+
+ va_start(ap,fmt);
+ g_vsnprintf(here, 126,fmt, ap);
+ va_end(ap);
+
+ for (npc = ep_packet_mem.free_list; npc != NULL; npc = npc->next) {
+ static unsigned i_ctr;
+
+ if (npc->c_count > 0x00ffffff) {
+ g_error("ep_packet_mem.free_list was corrupted\nbetween: %s\nand: %s",there, here);
+ }
+
+ for (i_ctr = 0; i_ctr < npc->c_count; i_ctr++) {
+ if (memcmp(npc->canary[i_ctr], &ep_canary, npc->cmp_len[i_ctr]) != 0) {
+ g_error("Per-packet memory corrupted\nbetween: %s\nand: %s",there, here);
+ }
+ }
+ }
+
+ strncpy(there,here,126);
+
+}
+#endif
+
/* Initialize the packet-lifetime memory allocation pool.
* This function should be called only once when Wireshark or TShark starts
@@ -184,6 +231,10 @@ ep_init_chunk(void)
ep_packet_mem.free_list=NULL;
ep_packet_mem.used_list=NULL;
+#ifdef DEBUG_INTENSE_CANARY_CHECKS
+ intense_canary_checking = (gboolean)getenv("WIRESHARK_DEBUG_EP_CANARY");
+#endif
+
#ifdef DEBUG_USE_CANARIES
emem_canary(ep_canary);
#endif /* DEBUG_USE_CANARIES */
@@ -667,6 +718,7 @@ gchar* se_strdup_printf(const gchar* fmt, ...) {
return dst;
}
+
/* release all allocated memory back to the pool.
*/
void
diff --git a/epan/emem.h b/epan/emem.h
index c9ea0d83c0..aaf1e0ac83 100644
--- a/epan/emem.h
+++ b/epan/emem.h
@@ -365,7 +365,22 @@ gboolean emem_tree_foreach(emem_tree_t* emem_tree, tree_foreach_func callback, v
+/* #define DEBUG_INTENSE_CANARY_CHECKS */
+/* Helper to troubleshoot ep memory corruption
+ * if compiled and the environment variable WIRESHARK_DEBUG_EP_CANARY exists
+ * it will check the canaries and when found corrupt stop there in the hope
+ * the corruptor is still there in the stack.
+ * Some checkpoints are already set in packet.c in strategic points
+ * before and after dissection of a frame or a dissector call.
+ */
+#ifdef DEBUG_INTENSE_CANARY_CHECKS
+void ep_check_canary_integrity(const char* fmt, ...);
+#define EP_CHECK_CANARY(sprintf_args) ep_check_canary_integrity sprintf_args
+#else
+#define EP_CHECK_CANARY(dummy)
+#endif
+
void emem_print_tree(emem_tree_t* emem_tree);
diff --git a/epan/packet.c b/epan/packet.c
index 07c93b2cb7..dbf6953ab4 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -51,6 +51,7 @@
#include "tvbuff.h"
#include "plugins.h"
#include "epan_dissect.h"
+
#include "emem.h"
#include <epan/reassemble.h>
@@ -320,6 +321,8 @@ dissect_packet(epan_dissect_t *edt, union wtap_pseudo_header *pseudo_header,
edt->pi.clnp_srcref = 0;
edt->pi.clnp_dstref = 0;
+ EP_CHECK_CANARY(("before dissecting frame %d",fd->num));
+
TRY {
edt->tvb = tvb_new_real_data(pd, fd->cap_len, fd->pkt_len);
/* Add this tvbuffer into the data_src list */
@@ -348,6 +351,8 @@ dissect_packet(epan_dissect_t *edt, union wtap_pseudo_header *pseudo_header,
RETHROW;
}
ENDTRY;
+
+ EP_CHECK_CANARY(("after dissecting frame %d",fd->num));
fd->flags.visited = 1;
}
@@ -392,9 +397,13 @@ call_dissector_through_handle(dissector_handle_t handle, tvbuff_t *tvb,
}
if (handle->is_new) {
+ EP_CHECK_CANARY(("before calling handle->dissector.new for %s",handle->name));
ret = (*handle->dissector.new)(tvb, pinfo, tree);
+ EP_CHECK_CANARY(("after calling handle->dissector.new for %s",handle->name));
} else {
+ EP_CHECK_CANARY(("before calling handle->dissector.old for %s",handle->name));
(*handle->dissector.old)(tvb, pinfo, tree);
+ EP_CHECK_CANARY(("after calling handle->dissector.old for %s",handle->name));
ret = tvb_length(tvb);
if (ret == 0) {
/*
@@ -1592,11 +1601,17 @@ dissector_try_heuristic(heur_dissector_list_t sub_dissectors,
proto_get_protocol_filter_name(proto_get_id(dtbl_entry->protocol)));
}
}
-
+ EP_CHECK_CANARY(("before calling heuristic dissector for protocol: %s",
+ proto_get_protocol_filter_name(proto_get_id(dtbl_entry->protocol))));
if ((*dtbl_entry->dissector)(tvb, pinfo, tree)) {
+ EP_CHECK_CANARY(("after heuristic dissector for protocol: %s has accepted and dissected packet",
+ proto_get_protocol_filter_name(proto_get_id(dtbl_entry->protocol))));
status = TRUE;
break;
} else {
+ EP_CHECK_CANARY(("after heuristic dissector for protocol: %s has returned true",
+ proto_get_protocol_filter_name(proto_get_id(dtbl_entry->protocol))));
+
/*
* That dissector didn't accept the packet, so
* remove its protocol's name from the list
@@ -1605,7 +1620,7 @@ dissector_try_heuristic(heur_dissector_list_t sub_dissectors,
if (pinfo->layer_names != NULL) {
g_string_truncate(pinfo->layer_names,
saved_layer_names_len);
- }
+ }
}
}
pinfo->current_proto = saved_proto;