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
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. */