grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Non-static variables and nested function pointers [bug #28392]


From: Grégoire Sutre
Subject: Re: Non-static variables and nested function pointers [bug #28392]
Date: Sat, 26 Dec 2009 19:43:45 +0100
User-agent: Thunderbird 2.0.0.23 (X11/20091027)

Robert Millan wrote:

The following snippet (kern/misc.c) comes to mind:

#ifdef NEED_ENABLE_EXECUTE_STACK
/* Some gcc versions generate a call to this function
   in trampolines for nested functions.  */
void __enable_execute_stack (void *addr __attribute__ ((unused)))
{
}
#endif

I was away from my email, sorry for the delay.  I hunted this
segfault down in the meantime, and I came to the same
conclusion.  If I remove `grub_CHECK_ENABLE_EXECUTE_STACK' from
configure.ac then the segfault in grub-probe disappear.


We added this for NetBSD in fact.  In that platform, GCC generates references
to this function, which are usually satisfied by libc, but we don't link with
libc, so we made it happy with an empty stub.

Yes, I realized that this was NetBSD specific from the archives of the mailing list -- kind of ironic ;-)

On my NetBSD/i386 5.0 system, if I compile the attached example, the symbol __enable_execute_stack does indeed appear in the executable (according to nm). This holds for gcc 4.1.3 (the system's default compiler) and for gcc 4.4.1. And the symbol __enable_execute_stack is found in libgcc_s.so.1.


But this is only supposed to happen when building real GRUB.  For util/
stuff, we should use the libc facility instead.  Maybe that's not the case?

I guess that it's not the case: util programs that are linked with kern/misc.c do not use the libc's __enable_execute_stack (if NEED_ENABLE_EXECUTE_STACK is defined in config.h).


In case that helps, and to continue the discussion regarding
executable stack on NetBSD, I made a few experiments on i386 and
amd64 on a simplified example (see below).  From what I could
read, NetBSD implements memory protection with PaX.

* NetBSD/i386:

                 | with dummy __enable_execute_stack |
                 |       no        |       yes       |
-----------------+-----------------+-----------------+
PaX MPROTECT off |       ok        |    segfault     |
-----------------+-----------------+-----------------+
PaX MPROTECT on  |    segfault     |    segfault     |
-----------------+-----------------+-----------------+

However, in all four cases, there is no segfault if the variable
j in main is declared static. And in that case, the generated executable does not contain the symbol __enable_execute_stack (according to nm).

* NetBSD/amd64: in all four cases, no segfault.

Also, on NetBSD/amd64, the segfault problem I experienced in grub-probe completely disappears.

Grégoire
#include <stdio.h>

#ifdef BAD
/* Some gcc versions generate a call to this function
   in trampolines for nested functions.  */
void __enable_execute_stack (void *addr __attribute__ ((unused)))
{
}
#endif

int apply(void (*hook) (int *))
{
   int a = 0;
   hook(&a);
   hook(&a);
   return a;
}

int main (int argc, char *argv[])
{
   /* static */ int j = 5;
   int res;

   void hook(int *n)
   {
      *n = *n + j;
      j--;
   }

   res = apply(hook);
   printf("result: %d, j=%d\n", res, j);
   return 0;
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]