-1

I am new to basics of gcc compilation. As far as I know the stack is inexecutable for security reasons. Then how can we have code on stack and execute. I observed this in case of a function returning pointer to a function. it does not return pointer to code but rather to a location on stack which has the code to be executed. How is that allowed in linux?

It is already done by gcc. I want to know how is it even possible?

Here is the c code:

     #include<stdio.h>

    typedef int (* funcptr) ();


funcptr f ()
{

  int g ()
  {

}
return (&g);
}


main ()
{
  funcptr fp;
  fp = f();

  fp ();

 }

And here is the portion of the assembly code geerating code on the stack:

    #Starting trampoline code. The trampoline code is a small
    #piece of code set up inside the stack!!!. This code, when
    #executed, loads ecx with the static link and calls the
    #function g
        movb    $-71, (%eax)    # This is B9, the opcode for
                                  "movl address_in_next_loc ecx"
                                  this, when executed, will
                                  load the static link in ecx

        movl    %edx, 1(%eax)   # address_in_next_loc=ebp-16
                                  the static link effectively

        movb    $-23, 5(%eax)   # This is E9. the opcode for
                                  jmp addr_nxt_ins + offset_
                                  in_nxt_loc
                                  Since the offset_in_nxt_loc 
                                  is &g - addr_nxt_ins, this
                                  results in a jump to &g

        movl    $g.1831, %ecx   # Stores &g - addr_nxt_ins
        leal    10(%eax), %edx  #
        subl    %edx, %ecx  # 
        movl    %ecx, %edx  # 
        movl    %edx, 6(%eax)   # 
    #End of trampoline code
Akash Garg
  • 51
  • 10
  • What makes you say gcc does this? – Scott Hunter Mar 30 '16 at 15:32
  • Because I read the assembly created by gcc. I created the assembly and read it. – Akash Garg Mar 30 '16 at 15:32
  • 1
    Can you show this assembly code? – Scott Hunter Mar 30 '16 at 15:34
  • That's how the *pointer to the code* gets on the stack; the *code* for that function is not. – Scott Hunter Mar 30 '16 at 15:40
  • No, I know the difference between pointer and code itself. The stack contains code itself. Maybe I made a typo. return function as an object. and you will see code on the stack(not all the function code but some code). – Akash Garg Mar 30 '16 at 15:52
  • 2
    You would need to provide an example of that. – Martin James Mar 30 '16 at 15:55
  • Functions aren't objects in C; if you have evidence to the contrary, please show it. – Scott Hunter Mar 30 '16 at 16:05
  • I can understand code being copied to a stack - the stack is writeable, so it could happen: a bug could do it, and I would expect a segfault/AV to follow on shortly..... – Martin James Mar 30 '16 at 16:13
  • The entire function code is not copied. When we call a function we need to provide environment pointer along with params & return address. So what happens is it creates two intruction on stack one is to jump to the code and other is to load environment pointer. and returns a pointer to it. So when a call to returned function is made from main it actually executes the code from stack to jump to actual function code. By environment pointer I mean static link. – Akash Garg Mar 30 '16 at 16:29
  • 1
    Sounds like a thunk. Would like to see the _examples_ !!! – CarlH Mar 30 '16 at 16:59
  • I have added an example in the question description. – Akash Garg Mar 31 '16 at 08:08
  • Please 1) remove any unnecessary C code from your example, 2) fix the various compiler warnings (unused variables, missing return types / values), 3) add the *specific* command line you are using to compile / disassemble the code. I was not able to reproduce your results. – DevSolar Mar 31 '16 at 08:25
  • Removed unnecessary code. – Akash Garg Mar 31 '16 at 10:52

3 Answers3

1

You would allocate memory from heap as opposed to the stack. But that might not do the trick, either, as modern processors/OSes allow for distinguishing between memory regions containing code and those containing data (for obvious security reasons).

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
1

Your C code contains a nested function, so GCC will set the .note.GNU-stack section of the generated object file to x (indicating an executable stack is required).

When the linker is invoked, it checks all supplied object files for this section. Because one of the input files has .note.GNU-stack set to x, the linker knows the stack must be executable.

To indicate this, the ELF header GNU_STACK in the final executable has the flag PF_X added to it.

The command:

readelf -l a.out | grep -A1 GNU_STACK

Should allow you to see the RWE flag set instead of RW.

The kernel specifically looks for this header when setting up the memory map for the process.

More details in the original patch

Mikel Rychliski
  • 3,455
  • 5
  • 22
  • 29
0

I suppose you assume that the stack is holding the code itself. That may not be the case. Stack is just a holder for the pointer to the code area.

You can learn more on how stack works here

This SO answer shows that the function pointer or the function itself would need the code location

Community
  • 1
  • 1
Hugo
  • 254
  • 2
  • 6
  • The stack holds some code not the all function code but some code. for jumping and setting static link etc. but the code is there on stack. – Akash Garg Mar 30 '16 at 15:54
  • Maybe this link will help: http://hokstad.com/how-to-implement-closures – CarlH Mar 30 '16 at 17:06