4

I have a Raspberry Pi 3 with the Raspbian GNU/Linux 8 (Jessie) OS.

I wrote this simple program. I compiled it with gcc -o hello hello.c.

#include <stdio.h>

void main(){
  printf("hello!\n");
}

From from the readelf output everything seems OK:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x0004cc 0x000104cc 0x000104cc 0x00008 0x00008 R   0x4
  PHDR           0x000034 0x00010034 0x00010034 0x00120 0x00120 R E 0x4
  INTERP         0x000154 0x00010154 0x00010154 0x00019 0x00019 R   0x1
      [Requesting program interpreter: /lib/ld-linux-armhf.so.3]
  LOAD           0x000000 0x00010000 0x00010000 0x004d8 0x004d8 R E 0x10000
  LOAD           0x000f0c 0x00020f0c 0x00020f0c 0x0011c 0x00120 RW  0x10000
  DYNAMIC        0x000f18 0x00020f18 0x00020f18 0x000e8 0x000e8 RW  0x4
  NOTE           0x000170 0x00010170 0x00010170 0x00044 0x00044 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x000f0c 0x00020f0c 0x00020f0c 0x000f4 0x000f4 R   0x1

But when I run the program the stack is executable:

0x7efdf000 0x7f000000 0x00000000 rwx [stack]

I try to compile also with the option -z noexecstack, but nothing change.

I try also to download the version of libarmmem.so that have this code:

#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

But nothing change.

Why is the stack segment executable on Raspberry Pi?

Edit I add the output of the LD_DEBUG=files ./hello command

     23110: 
     23110: file=/usr/lib/arm-linux-gnueabihf/libarmmem.so [0];  needed by ./hello [0]
     23110: file=/usr/lib/arm-linux-gnueabihf/libarmmem.so [0];  generating link map
     23110:   dynamic: 0x76f273fc  base: 0x76f13000   size: 0x00014524
     23110:     entry: 0x76f13568  phdr: 0x76f13034  phnum:          6
     23110: 
     23110: 
     23110: file=libc.so.6 [0];  needed by ./hello [0]
     23110: file=libc.so.6 [0];  generating link map
     23110:   dynamic: 0x76f0ef20  base: 0x76dd4000   size: 0x0013e550
     23110:     entry: 0x76dea840  phdr: 0x76dd4034  phnum:         10
     23110: 
     23110: 
     23110: calling init: /lib/arm-linux-gnueabihf/libc.so.6
     23110: 
     23110: 
     23110: calling init: /usr/lib/arm-linux-gnueabihf/libarmmem.so
     23110: 
     23110: 
     23110: initialize program: ./hello
     23110: 
     23110: 
     23110: transferring control: ./hello
     23110: 
hello!
     23110: 
     23110: calling fini: ./hello [0]
     23110: 
     23110: 
     23110: calling fini: /usr/lib/arm-linux-gnueabihf/libarmmem.so [0]
     23110:

Add more info: I edit the file architecture.S, and after the make I received:

gcc -std=gnu99 -O2 -c -o trampoline.o trampoline.c
gcc -shared -o libarmmem.so architecture.o memcmp.o memcpymove.o memcpymove-a7.o memset.o trampoline.o
`architecture' referenced in section `.text' of trampoline.o: defined in discarded section `.note.GNU-stack' of architecture.o
`architecture' referenced in section `.text' of trampoline.o: defined in discarded section `.note.GNU-stack' of architecture.o
`architecture' referenced in section `.text' of trampoline.o: defined in discarded section `.note.GNU-stack' of architecture.o
`architecture' referenced in section `.text' of trampoline.o: defined in discarded section `.note.GNU-stack' of architecture.o
collect2: error: ld returned 1 exit status
Makefile:13: recipe for target 'libarmmem.so' failed
make: *** [libarmmem.so] Error 1
Livio
  • 205
  • 1
  • 3
  • 9
  • Please forgive my ignorance... How did you get this result: `0x7efdf000 0x7f000000 0x00000000 rwx [stack]`. Is that part of a `trace`? – jww Jul 22 '17 at 11:13
  • @jww no just /proc/`pidof hello`/maps – Livio Jul 22 '17 at 11:26
  • 1
    Please run the program as `LD_DEBUG=files ./hello` and add the output to your post. There are some reports that a `LD_PRELOAD` library causes this. – Florian Weimer Jul 22 '17 at 11:43
  • @FlorianWeimer look also this ` $cat /etc/ld.so.preload /usr/lib/arm-linux-gnueabihf/libarmmem.so` – Livio Jul 22 '17 at 11:52

1 Answers1

3

It is likely that /usr/lib/arm-linux-gnueabihf/libarmmem.so is causing this. I found this source file:

It lacks the non-executable stack annotation, so glibc conservatively makes the stack executable when the DSO is preloaded. The other source files have this:

/* Prevent the stack from becoming executable */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

So you just need to copy this into architecture.S (at the end of the file) and rebuild.

You can verify with eu-readelf -l /usr/lib/arm-linux-gnueabihf/libarmmem.so if this DSO is indeed the culprit. It should show either no GNU_STACK program header at all, or a GNU_STACK program header which is marked RWE in the penultimate column.

Florian Weimer
  • 32,022
  • 3
  • 48
  • 92
  • @Livio, sorry that looks somehow garbled. The comment box isn't a good place to post compiler output messages. Please amend the post to say what you did and what the results were. – Florian Weimer Jul 22 '17 at 12:13
  • 1
    Oh sorry, I missed that `architecture.S` does not have a section directive near the start. You need to place the fragment I posted at the end of the file, or if you leave it at the start, add a `.data` directive after it. – Florian Weimer Jul 22 '17 at 12:52
  • Shouldn't it be enough to add `ASFLAGS += -Wa,--noexecstack`. The compiler driver will do the right thing and invoke the assembler with the proper flags. – jww Jul 22 '17 at 14:05
  • Oh wait... [`trampoline.c`](https://github.com/bavison/arm-mem/blob/master/trampoline.c) causes a loss of NX-stacks under GCC compilers (that's if it is a true tramopline). `libarmmem.so` probably cannot have them. – jww Jul 22 '17 at 14:22
  • @jww, I don't think so. These aren't on-stack trampolines. – Florian Weimer Jul 22 '17 at 14:26