[Top][All Lists]

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

Re: [Gcl-devel] Re: Executable memory: some apps that work on RH9 don't

From: Camm Maguire
Subject: Re: [Gcl-devel] Re: Executable memory: some apps that work on RH9 don't on FC1
Date: 18 Nov 2003 10:57:39 -0500
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2


Roland McGrath <address@hidden> writes:

> how to fix it.  There is at least one known issue of this nature (brk
> address).  Please try to determine if nonexecutability alone is what's


Sounds likely.  What is this?  We make heavy use of sbrk.

> breaking you, and if not, please post the details of your problem so we can
> determine what different problem there might be.
> The status quo ante was that the stack was executable, and the brk area
> (used by malloc for small allocations) was executable, and on x86 pages
> with PROT_READ set but PROT_EXEC did not have any enforcement of
> nonexecutability anyway.  All of these things are either just as they were
> before, or different now, on a per-process granularity (changed by exec 
> calls).

Can't see how executability could result in the reported failure.  My
bet is on the above.

> System-wide, you can disable the exec-shield functionality with:
>       echo 0 > /proc/sys/kernel/exec-shield

Does this only effect PROT_EXEC settings on memory pages?  If so, then
Tim's results indicate that I am wrong, in which case I'd like to
understand where executable maps matter in GCL at the stage of the
reported failure.

> If that doesn't make your binaries work, then you probably have a different
> problem.  If it does, then the system-wide switch is a stop-gap you can use
> while getting your binaries fixed.  We have also overloaded the inherited
> "personality" setting so you can disable it per-process:
>       setarch i386 foobar
> That runs "foobar" with the "personality" bits set such that exec-shield is
> disabled for that process and its children (unless one of them uses setarch
> or is setuid or somesuch).  Again, if that doesn't make your binaries work,
> then you probably have a different problem.

This at least could function as a work-around for now, if we can make
configure figure out when it is needed (cat
/proc/sys/kernel/exec-shield && [ -x setarch ] ?)  If this is the
wisest solution, let me know and I'll protect the image creations with
this command.

> If disabling exec-shield momentarily does work around your problem, then
> you want to figure out why you had to do that.  The most common situation
> is that you were using executable stack in some way that you don't really
> need to, e.g. GCC nested function trampolines.  You can avoid that by
> rewriting the code not to use trampolines (i.e. take the address of a
> nested function that uses its parent's local variables).  Things like Lisp

To my knowledge, we have no nested functions, nor rely on an
executable C stack.

> systems that produce executable code at run time should generally avoid
> using stack space for that.  You also should not be using malloc or direct
> brk/sbrk calls to get memory that you need to be executable--you have never
> had a specified guarantee that malloc returns executable memory.  For

We get all pages via sbrk, and redefine malloc to a call to a native
memory management system which in turn calls sbrk as needed.  If an
executable lisp object is loaded into one of these pages, the pages
are explicitly mprotected with PROT_EXEC.  The reported failure is
well in advance of this stage.

> dynamic allocation of memory where you need to put executable code, use
> mmap with PROT_READ|PROT_WRITE|PROT_EXEC.  It is also fine to mmap with
> different protections and then use mprotect with e.g. PROT_READ|PROT_EXEC
> later.  It is not proper to call mprotect on memory returned by malloc,
> because when you free that memory later it may be reused in ways that don't
> require the executability.  

This is probably not an issue with us, as we only effectively use
sbrk, and the pages are never freed.  We do on occasion re-mprotected
previously mprotected pages, e.g. when setting a gbc write barrier
with the call (si::sgc-on t).

> The same goes for the brk area.  (It's also the
> case that no specification guarantees that mprotect is meaningful on
> malloc-returned space, though in fact it will also work as you expect on
> malloc and brk/sbrk space in Linux and probably all Unixoid systems.)

>From this, my current understanding is that we should be OK as is.

> If you have a genuine need for executable stack, you can put a marker in
> your binary to tell the system that's what you want.  This marker goes in
> ELF executables (and DSOs) as the PT_GNU_STACK phdr entry, with p_flags
> containing PF_X to indicate need for executable stack and not containing
> PF_X to indicate no need for executable stack.  I'll describe how to
> compile those markers in a little later.  When a binary does not have any
> PT_GNU_STACK marker at all, as is the case with binaries produced by all
> older tool versions, it's treated as needing executable stack to be safe.
> That should retain compatibility with older systems.

As stated above, I can't see where we would need this, though its nice
to know.

> The story is the same for DSOs as for executable files.  The difference is
> that while the kernel looks for the marker in executable files at exec
> time, the dynamic linker looks at the marker in DSOs when it's loading
> them.  This is because an executable file that itself does not require an
> executable stack might load a DSO at runtime (either as a needed library or
> by using dlopen, e.g. for plug-in libraries) that does require executable
> stack.  In this instance, the dynamic linker stops and makes all the stacks
> executable before completing the load of the DSO in question.  Note that
> this support applies only to the stack--if a DSO dynamically allocates
> memory it needs to be executable and does that the wrong way, no marker
> will work around it, the code just has to be fixed.
> If you have an old DSO binary that it's not feasible for you to rebuild for
> some reason (e.g. 3rd-party plug-ins for your applications), you can try
> marking it using the `execstack' utility (part of the `prelink' rpm).
> execstack edits an existing ELF binary for you, either to add a
> PT_GNU_STACK phdr if it's missing or to set or clear the PF_X flag.
> `execstack -q FILE' will tell you the current status of that file: X for
> executable, - for not, and ? for an old binary with no marker at all.  (You
> can also use readelf -l or objdump -p to see the phdrs.)  Note that there

Are these utils in any (unstable) Debian packages?

> should never really be a need to add a marker to an old executable file
> because of the compatibility default--a good thing, since execstack cannot
> move things around to make room for the phdr in an executable as it can in
> a DSO.  Remember, the default when there is no marking is to assume
> executable stack is required for compatibility with older systems.  Ergo,
> you don't need to add a marker if it would have PF_X set.  The reason to
> add a marker is to avoid enabling executable stack at runtime when it's not
> really needed.  

Would be interesting to check if a raw_pre_gcl compiled on an older
system would run on this new exec-shield kernel.

> When compiling from source with current tools (including those in FC1), you
> don't usually need to do anything special to get the right markers into
> your binaries.  The way it works is that the linker produces the
> PT_GNU_STACK marker when there are special marker sections in the input
> object files, called ".note.GNU-stack".  The flags of these sections
> determine the flags of the PT_GNU_STACK entry.  Your object files (.o) will
> normally have these sections because GCC emits them in its assembler
> output.  When GCC compiles nested function trampoline code, it emits a
> .note.GNU-stack section with the SHF_EXECINSTR flag set:
>       .section .note.GNU-stack, "x", @progbits
>       .previous
> When GCC compiles a module that does not contain any code requiring
> executable stack, it emits the complementary marker section with no
> SHF_EXECINSTR flag bit:
>       .section .note.GNU-stack, "", @progbits
>       .previous

So even with nested functions, code should compile and run from
source, right?  Further indication that executable stack is likely not

> If you have assembly code of your own, then you need to add these markers.
> The best way is to amend the source code with one of the assembly
> directives above.  If that is problematic for some reason, another thing
> you can do is tell the assembler directly what to emit on the command line
> using -Wa,--execstack or -Wa,--noexecstack.  Finally, if you want to punt
> altogether on marking your .o files properly, you can tell the linker to
> ignore the marker sections and override its output setting directly on the
> command using -Wl,-z,execstack or -Wl,-z,noexecstack.

We don't use any asm.

Thank you for this very intersting and informative note!  I'll keep it
for future reference.

Take care,

> Thanks,
> Roland
> _______________________________________________
> Gcl-devel mailing list
> address@hidden
> http://mail.gnu.org/mailman/listinfo/gcl-devel

Camm Maguire                                            address@hidden
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah

reply via email to

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