bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/5149] New: PT_GNU_RELRO having PF_R|PF_E even when no section in


From: tcallawa at redhat dot com
Subject: [Bug ld/5149] New: PT_GNU_RELRO having PF_R|PF_E even when no section in it needs exec is a ld bug
Date: 9 Oct 2007 14:42:18 -0000

I caught this bug running the elfutils test suite on sparc (see Red Hat Bugzilla
324031).

I'm quoting Roland McGrath, who helped track this down:

Tom noticed that elflint is giving "loadable segment GNU_RELRO applies to
is executable" for a DSO on sparc (RHBZ#324031).  See the layout after FF
below for reference.

The diagnosis is accurate: p_flags has P_X in both PT_GNU_RELRO and the
PT_LOAD covering that address range.  This bit is "correct" in the PT_LOAD
in that there is a SHF_EXECINSTR|SHF_WRITE .plt section in that segment.
The bit in PT_GNU_RELRO is dubious, since no SHF_EXECINSTR section falls
inside its address range (not that p_flags in PT_GNU_RELRO really matters).

This relro region ends cleanly at a page boundary.  So I think what elflint
would be happy with is splitting that second PT_LOAD into one PF_R|PF_W
that ends where PT_GNU_RELRO ends, and a third PT_LOAD with PF_R|PF_W|PF_X
that covers .got through .bss.  This is clean in this example, but in the
general case I don't know how it flies.

I think this particular example may just be one with a lucky happenstance,
because the relro segment ends exactly on a page boundary just due to the
size of the sections.  With different details, or e.g. -z now where the
.plt itself would go into relro, then there would be a problem.

ld.so does not honor the p_flags either of the PT_LOAD or the PT_GNU_RELRO
when it applies PT_GNU_RELRO, it just mprotect's the area with PROT_READ.
So elflint is right to cite this as a problem.  When PT_GNU_RELRO is
applied, then the PF_X/PROT_EXEC required by the PT_LOAD is no longer in
force.  

I'm not exactly sure what the right fix is here.  It seems like -z now
should put .plt in relro, which means it really does need to start out
writable and then ld.so has to use PROT_READ|PROT_EXEC.  But for this
example (no -z now), it seems preferable to apply the relro as now.

It just seems unkosher when the PT_LOAD says PF_X.  Kosherifying with two
PT_LOADs would mean two mmap's now.  We could first make ld.so optimize
adjacent PT_LOADs with the same protections into a single mmap, and then
special-case a PT_LOAD whose pages are all going to be touched later by
relro so we roll it into any adjacent PT_LOAD with p_flags&PF_W.  Then we'd
get back to the same one mmap + mprotect for the same region we have now.

I'm sure there are at least two cases I'm not thinking through.

There are 38 section headers, starting at offset 0xa5664:

Section Headers:
[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
[ 0]                      NULL         00000000 000000 000000  0        0   0  0
[ 1] .note.gnu.build-id   NOTE         00000114 000114 000024  0 A      0   0  4
[ 2] .gnu.hash            GNU_HASH     00000138 000138 0003b4  4 A      3   0  4
[ 3] .dynsym              DYNSYM       000004ec 0004ec 000930 16 A      4   3  4
[ 4] .dynstr              STRTAB       00000e1c 000e1c 00073c  0 A      0   0  1
[ 5] .gnu.version         GNU_versym   00001558 001558 000126  2 A      3   0  2
[ 6] .gnu.version_d       GNU_verdef   00001680 001680 0000a4  0 A      4   5  4
[ 7] .gnu.version_r       GNU_verneed  00001724 001724 000070  0 A      4   1  4
[ 8] .rela.dyn            RELA         00001794 001794 0007d4 12 A      3   0  4
[ 9] .rela.plt            RELA         00001f68 001f68 0001d4 12 A      3  22  4
[10] .init                PROGBITS     00002140 002140 000038  0 AX     0   0 32
[11] .text                PROGBITS     00002180 002180 015360  0 AX     0   0 32
[12] .fini                PROGBITS     000174e0 0174e0 000030  0 AX     0   0 32
[13] .rodata              PROGBITS     00017510 017510 0014b0  0 A      0   0  8
[14] .eh_frame_hdr        PROGBITS     000189c0 0189c0 0003e4  0 A      0   0  4
[15] .eh_frame            PROGBITS     00018da4 018da4 000b6c  0 A      0   0  4
[16] .ctors               PROGBITS     00029e50 019e50 000008  0 WA     0   0  4
[17] .dtors               PROGBITS     00029e58 019e58 000008  0 WA     0   0  4
[18] .jcr                 PROGBITS     00029e60 019e60 000004  0 WA     0   0  4
[19] .data.rel.ro         PROGBITS     00029e64 019e64 0000c4  0 WA     0   0  4
[20] .dynamic             DYNAMIC      00029f28 019f28 0000d8  8 WA     4   0  4
[21] .got                 PROGBITS     0002a000 01a000 0001dc  4 WA     0   0  4
[22] .plt                 PROGBITS     0002a1dc 01a1dc 000208  0 WAX    0   0  4
[23] .data                PROGBITS     0002a3e4 01a3e4 000004  0 WA     0   0  4
[24] .bss                 NOBITS       0002a3e8 01a3e8 000020  0 WA     0   0  4
[25] .comment             PROGBITS     00000000 01a3e8 00147c  0        0   0  1
[26] .debug_aranges       PROGBITS     00000000 01b864 000d60  0        0   0  1
[27] .debug_pubnames      PROGBITS     00000000 01c5c4 001034  0        0   0  1
[28] .debug_info          PROGBITS     00000000 01d5f8 060c6e  0        0   0  1
[29] .debug_abbrev        PROGBITS     00000000 07e266 00b652  0        0   0  1
[30] .debug_line          PROGBITS     00000000 0898b8 0096ae  0        0   0  1
[31] .debug_frame         PROGBITS     00000000 092f68 0015c0  0        0   0  4
[32] .debug_str           PROGBITS     00000000 094528 002244  1 MS     0   0  1
[33] .debug_loc           PROGBITS     00000000 09676c 00a905  0        0   0  1
[34] .debug_ranges        PROGBITS     00000000 0a1071 004480  0        0   0  1
[35] .shstrtab            STRTAB       00000000 0a54f1 000171  0        0   0  1
[36] .symtab              SYMTAB       00000000 0a5c54 001c80 16       37 312  4
[37] .strtab              STRTAB       00000000 0a78d4 001a24  0        0   0  1

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x019910 0x019910 R E 0x10000
  LOAD           0x019e50 0x00029e50 0x00029e50 0x000598 0x0005b8 RWE 0x10000
  DYNAMIC        0x019f28 0x00029f28 0x00029f28 0x0000d8 0x0000d8 RW  0x4
  NOTE           0x000114 0x00000114 0x00000114 0x000024 0x000024 R   0x4
  GNU_EH_FRAME   0x0189c0 0x000189c0 0x000189c0 0x0003e4 0x0003e4 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x000000 0x000000 RW  0x4
  GNU_RELRO      0x019e50 0x00029e50 0x00029e50 0x0001b0 0x0001b0 R E 0x1

 Section to Segment mapping:
  Segment Sections...
   00      [RO: .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version
.gnu.version_d .gnu.version_r .rela.dyn .rela.plt .init .text .fini .rodata
.eh_frame_hdr .eh_frame]
   01      [RELRO: .ctors .dtors .jcr .data.rel.ro .dynamic] .got .plt .data 
.bss
   02      [RELRO: .dynamic]
   03      [RO: .note.gnu.build-id]
   04      [RO: .eh_frame_hdr]
   05     
   06      [RELRO: .ctors .dtors .jcr .data.rel.ro .dynamic]
b

-- 
           Summary: PT_GNU_RELRO having PF_R|PF_E even when no section in it
                    needs exec is a ld bug
           Product: binutils
           Version: 2.19 (HEAD)
            Status: NEW
          Severity: normal
          Priority: P2
         Component: ld
        AssignedTo: unassigned at sources dot redhat dot com
        ReportedBy: tcallawa at redhat dot com
                CC: bug-binutils at gnu dot org


http://sourceware.org/bugzilla/show_bug.cgi?id=5149

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]