]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Avoid asserting when a segment is mapped both rw and rx.
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 1 Aug 2012 22:27:29 +0000 (22:27 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 1 Aug 2012 22:27:29 +0000 (22:27 +0000)
If a segment is mapped with permission rwx, then map->rx
and map->rw will be true.
But due to the if (map->rx) {
                 ...
               } else if (map->rw) {
                 ...
the  (map->rw) part will not be executed.
If this mapping is the one which "gives" the nonempty rw map,
then this mapping will not be seen, and the following
vg_assert(has_nonempty_rw);
will fail.

This assert can be reproduced by doing
setarch i686 -X
./vg-in-place --tool=none none/tests/map_unmap

Note: the setarch i686 -X above has as effect to make all read
mapping also executable. So, a rw mapping becomes rwx and then
triggers the above asserts.

The setarch i686 -X also introduces a discrepancy between
the kernel mappings (rwx) and the valgrind aspacemgr view
(which believes it is a rw mapping).
This discrepancy causes a crash if giving --sanity-level=3.
A possible fix is to have valgrind calling the personality system call
and detecting if the READ_IMPLIES_EXEC bit (the -X arg to setarch)
was set, and then modify aspacemgr so that all read mapped segments
are automatically mapped x also.

This commit is the minimal fix allowing to run executables
launched with this READ_IMPLIES_EXEC.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12810

coregrind/m_debuginfo/readelf.c

index ef1df5a5a02f6deda91573b29abada82373389d0..dc0b21ccb55d4dd612687ec8cf3f0ea853466cdd 100644 (file)
@@ -1381,15 +1381,12 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
       Bool has_nonempty_rw = False;
       for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
          struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
-         if (map->rx) {
-            if (map->size > 0)
-               has_nonempty_rx = True;
-         } else if (map->rw) {
-            if (map->size > 0)
-               has_nonempty_rw = True;
-         } else
+         if (!map->rx && !map->rw)
             continue;
-
+         if (map->rx && map->size > 0)
+            has_nonempty_rx = True;
+         if (map->rw && map->size > 0)
+            has_nonempty_rw = True;
          /* If this doesn't hold true, it means that m_syswrap/m_aspacemgr
             managed to do a mapping where the start isn't page aligned.
             Which sounds pretty bogus to me. */