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. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils