0

I compiled this simple program at ubuntu 15.10 x64

char *glob = "hello strings"
void main() {

}

and using the gdb I could find the "hello strings" are located at the

read/execute segment with .text section.

I already know that some strings contained in the ELF header are located in the code segment

but why the user defined strings are located at the same segment with code?

I've also tried to enlarge the size of the strings to 0x1000 for checking

whether it is compiler optimization to locate small sized strings with code section, but

they are also located at the same segment with code.

It's very interesting to me because intuitively strings should be readable not executable.

ruach
  • 1,369
  • 11
  • 21

1 Answers1

1

By default, the Linux linker creates two PT_LOAD segments: a read-only one, containing .text, and a writable one containing .data (initialized data).

Your string literal resides in .rodata section.

Which of the above two segments would you like this section to go into? If it is to be read-only, then it will have to go into the same segment that contains .text, and that segment must be executable. If the section is to go into the writable segment, it will not have execute permissions, but then you would be able to write to these strings, and they would not be shared when multiple instances of your binary run.

You can see the assignment of sections to segments in the output of readelf -l a.out.

With older versions of GCC (before 4.0), you can see that adding -fwritable-strings moves the string into .data, and into non-executable segment.

Gold linker supports --rodata flag, which moves all read-only non-executable sections into a separate PT_LOAD segment. But that increases the number of mmap and mprotect calls that the dynamic loader has to perform, and so is not the default.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362