_pre_mem_asciiz handlers in both tools: don't segfault if passed an
obviously invalid address. Fixes #255009. Investigation & initial
patch by Philippe Waroquiers (philippe.waroquiers@skynet.be)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11533 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/drd/drd_main.c b/drd/drd_main.c
index 239f498..7398404 100644
--- a/drd/drd_main.c
+++ b/drd/drd_main.c
@@ -51,6 +51,7 @@
#include "pub_tool_replacemalloc.h"
#include "pub_tool_threadstate.h" // VG_(get_running_tid)()
#include "pub_tool_tooliface.h"
+#include "pub_tool_aspacemgr.h" // VG_(am_is_valid_for_client)
/* Local variables. */
@@ -257,6 +258,13 @@
const char* p = (void*)a;
SizeT size = 0;
+ // Don't segfault if the string starts in an obviously stupid
+ // place. Actually we should check the whole string, not just
+ // the start address, but that's too much trouble. At least
+ // checking the first byte is better than nothing. See #255009.
+ if (!VG_(am_is_valid_for_client) (a, 1, VKI_PROT_READ))
+ return;
+
/* Note: the expression '*p' reads client memory and may crash if the */
/* client provided an invalid pointer ! */
while (*p)
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index 6af1a73..d68cd10 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -53,6 +53,7 @@
#include "pub_tool_redir.h" // sonames for the dynamic linkers
#include "pub_tool_vki.h" // VKI_PAGE_SIZE
#include "pub_tool_libcproc.h" // VG_(atfork)
+#include "pub_tool_aspacemgr.h" // VG_(am_is_valid_for_client)
#include "hg_basics.h"
#include "hg_wordset.h"
@@ -1797,7 +1798,12 @@
if (SHOW_EVENTS >= 1)
VG_(printf)("evh__pre_mem_asciiz(ctid=%d, \"%s\", %p)\n",
(Int)tid, s, (void*)a );
- // FIXME: think of a less ugly hack
+ // Don't segfault if the string starts in an obviously stupid
+ // place. Actually we should check the whole string, not just
+ // the start address, but that's too much trouble. At least
+ // checking the first byte is better than nothing. See #255009.
+ if (!VG_(am_is_valid_for_client) (a, 1, VKI_PROT_READ))
+ return;
len = VG_(strlen)( (Char*) a );
shadow_mem_cread_range( map_threads_lookup(tid), a, len+1 );
if (len >= SCE_BIGRANGE_T && (HG_(clo_sanity_flags) & SCE_BIGRANGE))