[PATCH] ld.so: Handle read-only dynamic section gracefully [BZ #28340]

Florian Weimer fweimer@redhat.com
Thu Sep 16 05:46:30 GMT 2021


* Siddhesh Poyarekar:

> On 9/16/21 10:18 AM, Florian Weimer wrote:
>> * H. J. Lu:
>> 
>>> There is nothing wrong with read-only dynamic segment.
>> A relocated DYNAMIC array is part of the ABI for !DL_RO_DYN_SECTION.
>> ELF requires that DT_STRTAB is present.  DT_STRTAB needs relocation.
>> This means that for !DL_RO_DYN_SECTION, the dynamic segment cannot be in
>> a read-ony LOAD segment for a valid ELF file.
>
> I think what H. J. means here is that we just never adjust DT_STRTAB
> and add l_addr to it every time we use it.

I understood that.  But applications expected that DT_STRTAB value has
been relocated.

See the discussion about the setting of DL_RO_DYN_SECTION for RISC-V and
libphobos.  Quoting libphobos/libdruntime/gcc/sections/elf.d:

| if (dyn.d_tag == DT_STRTAB)
| {
|     version (CRuntime_Musl)
|         strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
|     else version (linux)
|     {
|         // This might change in future glibc releases (after 2.29) as dynamic sections
|         // are not required to be read-only on RISC-V. This was copy & pasted from MIPS
|         // while upstreaming RISC-V support. Otherwise MIPS is the only arch which sets
|         // in glibc: #define DL_RO_DYN_SECTION 1
|         version (RISCV_Any)
|             strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
|         else version (MIPS_Any)
|             strtab = cast(const(char)*)(info.dlpi_addr + dyn.d_un.d_ptr); // relocate
|         else
|             strtab = cast(const(char)*)dyn.d_un.d_ptr;
|     }

Thanks,
Florian



More information about the Libc-alpha mailing list