title: GDB cannot access memory at ... why does it matter where it returns in mapped and executable memory?
body: <p>I have the following short program which sets the return address on the stack to some value so that when it returns it will jump to this set address:</p>
  
  <pre><code>(gdb) disas main
  Dump of assembler code for function main:
     0x000000000040051c &lt;+0&gt;:     push   rbp
     0x000000000040051d &lt;+1&gt;:     mov    rbp,rsp
     0x0000000000400520 &lt;+4&gt;:     mov    DWORD PTR [rbp-0x14],edi
     0x0000000000400523 &lt;+7&gt;:     mov    QWORD PTR [rbp-0x20],rsi
     0x0000000000400527 &lt;+11&gt;:    lea    rax,[rbp-0x1]
     0x000000000040052b &lt;+15&gt;:    add    rax,0x9
     0x000000000040052f &lt;+19&gt;:    mov    QWORD PTR [rax],0x400520
     0x0000000000400536 &lt;+26&gt;:    mov    eax,0x0
     0x000000000040053b &lt;+31&gt;:    pop    rbp
     0x000000000040053c &lt;+32&gt;:    ret    
  End of assembler dump.
  </code></pre>
  
  <p>Why does it matter what the address that I put into [rax] is? (0x400520 in this example, i.e. main+4)</p>
  
  <p>When I try various addresses it might succeed or fail with the error: "Cannot access memory at address 0x8", here (with main+4) it fails:</p>
  
  <pre><code>(gdb) b *0x000000000040053c
  Breakpoint 1 at 0x40053c
  (gdb) run 
  Breakpoint 1, 0x000000000040053c in main ()
  =&gt; 0x000000000040053c &lt;main+32&gt;:        c3      ret    
  (gdb) x/a $rsp
  0x7fffffffdd18: 0x400520 &lt;main+4&gt;
  (gdb) si
  Cannot access memory at address 0x8
  (gdb) x/i $rip
  =&gt; 0x400520 &lt;main+4&gt;:   mov    DWORD PTR [rbp-0x14],edi
  </code></pre>
  
  <p>What is the problem here? The address it returns to is mapped, readable and executable. "si" steps only one instruction, hence it executes only the ret instruction.</p>
  
  <p>I also see that the address that the rip was set to contains a valid instruction to execute.</p>
  
  <p>It might be of interest to mention that manually setting $rip to the same address seems to incur no issues (e.g. just set $rip=0x400520 and then si).</p>
  
  <p>From where does this attempt to access address 0x8 come from? Why is there such an access at all, and from where does "0x8" come from? ret only pops from the stack into rip. Surely there is something obvious that I'm missing here?</p>
  
  <p>If I return to different addresses, e.g. main+0 or main+32, it works, but most others seem to fail.</p>
  
  <p>The C program is simply (the magic +9 is just arrived at by using gdb to see how much I needed, it might need to be adjusted for a different system):</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdint.h&gt;
  
  int main(int argc, char **argv)
  {
          char stack; 
  
          *((uint64_t *) (&amp;stack + 9)) = 0x0000000000400520;
  
          return 0;
  }
  </code></pre>
  
  <p>I am using GNU gdb (Gentoo 7.6.2 p1) 7.6.2, but I've also noticed the issue with GNU gdb (GDB) 7.5-4.0.61. I am using gcc (Gentoo 4.7.3-r1 p1.4, pie-0.5.5) 4.7.3.</p>