Bug 187853 - Gnat: ICE on Hello World
Summary: Gnat: ICE on Hello World
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: kernel
Version: 5
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Dave Jones
QA Contact: Brian Brock
URL:
Whiteboard:
: 187687 188412 189289 191543 193969 (view as bug list)
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2006-04-03 22:59 UTC by Björn Persson
Modified: 2015-01-04 22:26 UTC (History)
10 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2006-07-14 05:44:10 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Björn Persson 2006-04-03 22:59:54 UTC
Description of problem:
Gnat crashes with a Storage_Error on even the simplest program.

Version-Release number of selected component (if applicable):
4.1.0-3

How reproducible:
Always.

Steps to Reproduce:
1. yum install gcc-gnat
2. hello_world.adb:
with Ada.Text_IO;

procedure Hello_World is
begin
   Ada.Text_IO.Put_Line("Hello World!");
end Hello_World;

3. gnatmake hello_world.adb
  
Actual results:
gcc -c hello_world.adb
+===========================GNAT BUG DETECTED==============================+
| 4.1.0 20060304 (Red Hat 4.1.0-3) (i386-redhat-linux-gnu) Storage_Error stack
overflow (or erroneous memory access)|
| Error detected at a-tags.adb:448:7                                       |
| Please submit a bug report; see http://gcc.gnu.org/bugs.html.            |
| Use a subject line meaningful to you and us to track the bug.            |
| Include the entire contents of this bug box in the report.               |
| Include the exact gcc or gnatmake command that you entered.              |
| Also include sources listed below in gnatchop format                     |
| (concatenated together with no headers between files).                   |
+==========================================================================+

Please include these source files with error report
Note that list may not be accurate in some cases,
so please double check that the problem can still
be reproduced with the set of files listed.

hello_world.adb

compilation abandoned
gnatmake: "hello_world.adb" compilation error


Expected results:
The compiler should not crash.

Additional info:
Both the system compiler and a home-compiled GCC 4.1.0 worked fine in Fedora 4,
so this must have something to do with some difference between Fedora 4 and 5.

Comment 1 Jakub Jelinek 2006-04-04 09:22:49 UTC
I'd say this is selinux preventing executable stack eventhough gnat1 and
some other gnat utilities are marked with PT_GNU_STACK PT_R|PT_W|PT_X:

execstack /usr/libexec/gcc/*/*/gnat1 /usr/bin/gnat*
X /usr/libexec/gcc/x86_64-redhat-linux/4.1.0/gnat1
- /usr/bin/gnat
X /usr/bin/gnatbind
- /usr/bin/gnatbl
- /usr/bin/gnatchop
- /usr/bin/gnatclean
- /usr/bin/gnatfind
- /usr/bin/gnatgcc
- /usr/bin/gnatkr
- /usr/bin/gnatlink
X /usr/bin/gnatls
X /usr/bin/gnatmake
- /usr/bin/gnatname
- /usr/bin/gnatprep
- /usr/bin/gnatxref

Guess they need to be labeled some way that SELinux allows executable stack for
them, but not sure how exactly.  In any case, that's something
/etc/selinux/targeted/contexts/files/file_contexts needs to include rather than
gcc-gnat.

Comment 2 Daniel Walsh 2006-04-04 10:27:32 UTC
setsebool -P allow_execstack=1 allow_execmem=1 

should make it work for FC5 for now.

You could also label the executables java_exec_t, since the ada policy will be
the same.  jave_t is an unconfined context that allows execstack and execmem.



Comment 3 Björn Persson 2006-04-04 21:06:52 UTC
Setsebool doesn't help. It says "SELinux is disabled", and sure enough, in
/etc/selinux/config I have "SELINUX=disabled".

Can SELinux cause this even though it's disabled?

Comment 4 Daniel Walsh 2006-04-05 12:38:43 UTC
No.

Comment 5 Jakub Jelinek 2006-04-05 12:52:36 UTC
Then it is a kernel bug, it doesn't honor PT_GNU_STACK any longer.
Try:
void
__attribute__((noinline))
bar (void (*fn) (void))
{
  fn ();
}

int
main (void)
{
  int i = 1;
  void foo (void)
  {
    i--;
  }
  bar (foo);
  return i;
}

Compile with gcc -g -o /tmp/test /tmp/test.c
sudo chcon system_u:object_r:java_exec_t /tmp/test # To rule SELinux out
/tmp/test
Clearly, the stack is not executable:
7fffffc96000-7fffffcac000 rw-p 7fffffc96000 00:00 0                      [stack]


Comment 6 Jakub Jelinek 2006-04-05 12:53:51 UTC
*** Bug 187687 has been marked as a duplicate of this bug. ***

Comment 7 Björn Persson 2006-04-05 22:06:43 UTC
I don't understand "7fffffc96000-7fffffcac000 rw-p 7fffffc96000 00:00 0", but
Jakub Jelinek's test program segfaults.

I can confirm Joachim Frieben's observation in bug 187687 that the regression is
in the kernel update. I can also report that the latest kernel for Fedora 4 has
the same problem. If I boot Fedora 4 with Linux 2.6.15-1.1833_FC4 or Fedora 5
with Linux 2.6.15-1.2054_FC5, then Gnat can compile hello_world and Jakub's test
runs without error. If I boot Fedora 4 with Linux 2.6.16-1.2069_FC4 or Fedora 5
with Linux 2.6.16-1.2080_FC5, then Gnat and Jakub's test both crash.


Comment 8 Jakub Jelinek 2006-04-10 09:02:14 UTC
*** Bug 188412 has been marked as a duplicate of this bug. ***

Comment 9 Jakub Jelinek 2006-04-18 20:52:48 UTC
*** Bug 189289 has been marked as a duplicate of this bug. ***

Comment 10 Björn Persson 2006-04-22 22:55:54 UTC
In http://people.redhat.com/mingo/exec-shield/exec-shield-nx-2.6.15.patch, the
variable exec_shield is initialized to 2, which would make stacks non-executable
no matter what. Yet, when I boot Linux 2.6.15-1.2054_FC5 the value found in
/proc/sys/kernel/exec-shield is 1, so somehow the default value gets changed to
honor PT_GNU_STACK.

In exec-shield-nx-2.6.16.patch the default value is 11, which also makes all
stacks non-executable, and this value does not get changed:

$ uname -r
2.6.16-1.2096_FC5
$ cat /proc/sys/kernel/exec-shield
11

Whatever it was that changed exec_shield in Linux 2.6.15 it should be restored
for 2.6.16 to allow executable code on the stack for marked programs. I'd
recommend a value of 9 if the new vDSO mapping feature is desired.

(It's ironic that a security measure against buffer overflows ends up hurting
the compiler for a language that's pretty much immune to buffer overflows. I
find surprisingly few files with the executable stack flag set, but other than
Gnat there are /usr/bin/eu-nm and /usr/lib/libGL.so. Outside of Core there are
also Mplayer and Lame.)

Comment 11 Nicholas Miell 2006-05-13 18:35:10 UTC
I think the following hunk in the current exec-shield patch causes the problem:

+       if (current->personality == PER_LINUX && (exec_shield & 2)) {
+               executable_stack = EXSTACK_DISABLE_X;
+               current->flags |= PF_RANDOMIZE;
+       }
+

It's located immediately after the the check for the presence of a PT_GNU_STACK
 phdr entry and unconditionally disables an exectuable stack for everything,
even binaries which the kernel just decided needed an executable stack.

(On a related note, the "have_pt_gnu_stack" variable is never used after it's
set. Also, gnat binaries don't actually have a PT_GNU_STACK segment, but I don't
think that's an issue.)

Comment 12 Jakub Jelinek 2006-05-22 17:25:11 UTC
*** Bug 191543 has been marked as a duplicate of this bug. ***

Comment 13 Björn Persson 2006-05-22 23:01:21 UTC
My tests indicate that this bug is fixed in kernel-2.6.16-1.2122_FC5.

Comment 14 James Hunt 2006-05-24 07:33:47 UTC
I second that - works fine for me with kernel-2.6.16-1.2122_FC5.

Whoever fixed it, thanks - I can jettison my 2.6.15 kernel now ;-)

Comment 15 Jakub Jelinek 2006-06-05 06:32:13 UTC
*** Bug 193969 has been marked as a duplicate of this bug. ***

Comment 16 Nicholas Miell 2006-06-15 04:13:36 UTC
Summary for the kernel folks (in hopes that this'll actually get fixed instead
of papered over; no 2122 didn't fix it, it just changed the exec-shield sysctl
default from 11 to 9):

Exec Shield does not give an executable stack to apps that are correctly labeled
with an executable PT_GNU_STACK ELF phdr.

My understanding of the semantics of the PT_GNU_STACK phdr (ignoring SELinux):
doesn't exist: app gets the kernel default as specified in bit two of
/proc/sys/kernel/exec-shield
exists, not-executable: app gets a non-executable stack
exists, executable: app gets an executable stack

At the very least, the third case is broken.


--


Björn Persson (rombo.bjorn.persson): you should probably change the
Summary of this bug to something like "exec shield doesn't give an executable
stack to apps that request it" so that it gets better visibility. (I'm not a
sufficiently empowered user, so I can't do it.)

Comment 17 Dave Jones 2006-07-06 17:54:05 UTC
actually, the default change should have been the right thing to do.
setting bit 2 of the execshield sysctl means nothing gets an executable stack,
even apps that request it.  It's the uber-paranoid mode.

Clearly, that's not practical, so changing it so that isn't the default should
mean that everything works again.

I've looked over the section of diff you pointed out vs the .17 based update
kernel, and it looks to be right to me.  We *could* skip that whole section of
elf header parsing to determine EXSTACK, but the way its currently done is less
invasive, and it's only a tiny microoptimisation anyway.

Unless there are applications that are continuing to break with the .17 update
with the sysctls in their default state, I think this can be closed.

Comment 18 Dave Jones 2006-07-06 17:55:48 UTC
(note, when I said 'bit 2' I actually mean 1<<1)
As documented in the patch..

+   (1<<1) 2: noexecstack by default



Comment 19 Björn Persson 2006-07-08 23:34:49 UTC
I agree that it can be closed. I'm using 2.6.17-1.2145_FC5 now, and I no longer
have this problem.


Note You need to log in before you can comment on or make changes to this bug.