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
4
  • Please forgive my ignorance... How did you get this result: 0x7efdf000 0x7f000000 0x00000000 rwx [stack]. Is that part of a trace? Commented Jul 22, 2017 at 11:13
  • @jww no just /proc/pidof hello/maps Commented Jul 22, 2017 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. Commented Jul 22, 2017 at 11:43
  • @FlorianWeimer look also this ` $cat /etc/ld.so.preload /usr/lib/arm-linux-gnueabihf/libarmmem.so` Commented Jul 22, 2017 at 11:52

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

@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.
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.
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.
Oh wait... 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, I don't think so. These aren't on-stack trampolines.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.