This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: Increase the size of .data.rel section for -z relro check


On Thu, Jul 14, 2011 at 07:47:18PM -0700, Roland McGrath wrote:
> Thanks for the explanation.  I still don't really understand why ld
> doesn't produce a PT_GNU_RELRO for that test (which gold does).  But I
> gleaned enough to adjust the test so that F15's ld, and trunk ld, and
> trunk gold all pass it.
> 
> In fact, it does not work just to have a small writable data section.
> (What I tried was 'int data = 1;'.)  However, that did work with -z now
> added, for some reason.  I had to use an initialized data section of
> substantial size to make it work.  It also didn't work with just .bss,
> i.e. uninitialized data, no matter what the size.

Ah, the explanation of that is easy too.  On x86_64/i686 (and other targets
with separate .got.plt section) we want to align to commonpage boundary
not the end of some section, but the middle of the .got.plt section.
So, the linker script is using e.g. on x86_64:
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
  .dynamic        : { *(.dynamic) }
  .got            : { *(.got) *(.igot) }
  . = DATA_SEGMENT_RELRO_END (24, .);
  .got.plt        : { *(.got.plt)  *(.igot.plt) }
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
and the linker behaves exactly as documented here, it tries to
align . + 24 to commonpage boundary.  Which is fine if there is
.got.plt section because it starts with the 24 bytes that should be
protected and is followed by other bytes that aren't protected.
But in your artificial testcase there is no .got.plt section.
We'd want to use something like:
  . = DATA_SEGMENT_RELRO_END ((SIZEOF(.got.plt) >= 24 ? 24 : 0), .);
instead, except that the linker doesn't allow that, because
SIZEOF can't be used before the section is defined in the linker script
and DATA_SEGMENT_RELRO_END has to come before that.
If somebody really wants to do something about it, the solution could
be to add another linker builtin macro, which would tell you say
if there are any input sections of that name or something similar, and
you could use
  . = DATA_SEGMENT_RELRO_END ((INPUT_SECTION_EXISTS (*(.got.plt)) ? 24 : 0), .);
or similar.

When using -z relro -z now, the linker script is different:
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
  .dynamic        : { *(.dynamic) }
  .got            : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
  . = DATA_SEGMENT_RELRO_END (0, .);
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
because then we want to protect the whole .got.plt section.

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]