grub-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] NetBSD/i386 port


From: Peter Jones
Subject: Re: [PATCH] NetBSD/i386 port
Date: Thu, 01 Dec 2005 14:07:51 -0500

On Thu, 2005-12-01 at 10:00 -0600, Hollis Blanchard wrote:
> On Dec 1, 2005, at 7:48 AM, Marco Gerards wrote:
> >> Files affected: kern/mm.c, normal/misc.c
> >>
> >> This is probably more a gcc issue (my is gcc version 3.3.3 (NetBSD nb3
> >> 20040520)). As of 2.0, NetBSD/i386 uses non-executable mapping of 
> >> stack
> >> and thus when nested functions are used it generates call to
> >> __enable_execute_stack() (which is actually in libgcc) even if 
> >> -nostdlib
> >> is used. Since I know no way to disable this behavior (but there 
> >> might be
> >> some) only workaround known to me is providing dumb 
> >> __enable_execute_stack()
> >> functions where apropriate.
> >
> > When is this required?  When using grub-emu or any other userland
> > utility?  In that case GRUB is linked to the C library.

It hits when you use any userland utility that has nested functions, so
I think we're talking about grub-emu and grub-install.  GCC (and
possibly other compilers, I don't really know) uses stack trampolines
generated during execution to implement nested functions.  So whether
you're using libc or not, you need to write to the stack.  In recent
versions of Fedora and RHEL, a program by default doesn't have an
executable stack, and that's enforced by the hardware.  So when we hit
one of these trampolines, if the stack isn't executable, you get a
segfault.

On Linux with GCC, executables may have an elf note that states that
they need an executable stack, and that should work.  For nested
functions it should be automatically generated with any recent version
of GCC.  In general this is true of any code GCC generates that uses a
writable stack, but untrue in the case where e.g. inline assembly writes
to the stack.  There's a utility called "execstack" that can query, set,
or clear the flags for a binary.

Even though the elf notes provide us with the ability to annotate that a
program needs an executable stack, we'd prefer not to do that.  We
strongly prefer not to ship *any* programs that use an executable stack
at all.  With GRUB Legacy, which we're currently shipping on x86 and
x86_64, we patch grub in such a way that it no longer has nested
functions in the paths that grub-install hits.  We also ship a patch I
sent to bug-grub several months ago which mprotects grub's "test" stack
correctly.

> > In the case it is used for GRUB itself, it is useless.  GRUB executes
> > within its own environment.  So in that case we should just make sure
> > this doesn't show up.  Perhaps by using different compiler flags.

Yeah, it shouldn't matter with grub itself at all, because no memory the
bootloader is mapped into should have any protection.

> I think this is a problem Peter Jones was telling me about with Fedora 
> as well (non-executable stack conflicting with nested functions).
> 
> Peter, do you know anything about that __enable_execute_stack()? 
> http://gcc.gnu.org/ml/gcc-patches/2004-07/msg01700.html seems to 
> indicate it's only for Solaris, NetBSD, FreeBSD/SPARC64 and OSF, but it 
> sounds like we need it on Linux as well?

I don't know what, if anything, this libgcc call does on linux.  In
general to use an executable stack here, we need either the elf notes in
the binary to say they need it.  It's also possible (but not really
recommended, of course) to allocate your own stack and mark it PROT_EXEC
with mprotect(), but that should really only be used on memory that you
have access to as the result of a malloc() call from within the program.

-- 
  Peter





reply via email to

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