[v3,00/32] RELRO linkmaps

Message ID cover.1701944612.git.fweimer@redhat.com
Headers
Series RELRO linkmaps |

Message

Florian Weimer Dec. 7, 2023, 10:30 a.m. UTC
  This is a rebase on top of the current development branch.  There were
quite a few conflicts.

Is the struct link_map_private change something we want?  (We currently
have different definitions of struct link_map within glibc and for
applications, resulting in conflicting debugging information.)  I can
submit that as a separate patch.

Likewise, I'd like to move the dl_rtld_map out of _rtld_global because
it makes the internal GLIBC_PRIVATE ABI more stable.  This series
achieves this as a side effect because the link map is now allocated
using the protected memory allocator.  But if the entire series can't
land in 2.39, I'd like to submit this separately as well, along with the
“_dl_rtld_map should not exist in static builds” cleanup.

Thanks,
Florian

Florian Weimer (32):
  support: Add <support/memprobe.h> for protection flags probing
  misc: Enable internal use of memory protection keys
  elf: Remove _dl_sysdep_open_object hook function
  elf: Eliminate second loop in find_version in dl-version.c
  elf: In rtld_setup_main_map, assume ld.so has a DYNAMIC segment
  elf: Remove version assert in check_match in elf/dl-lookup.c
  elf: Disambiguate some failures in _dl_load_cache_lookup
  elf: Eliminate alloca in open_verify
  Do not export <alloc_buffer.h> functions from libc
  elf: Make <alloc_buffer.h> usable in ld.so
  elf: Merge the three implementations of _dl_dst_substitute
  elf: Move __rtld_malloc_init_stubs call into _dl_start_final
  elf: Merge __dl_libc_freemem into __rtld_libc_freeres
  elf: Use struct link_map_private for the internal link map
  elf: Remove run-time-writable fields from struct link_map_private
  elf: Move l_tls_offset into read-write part of link map
  elf: Allocate auditor state after read-write link map
  elf: Move link map fields used by dependency sorting to writable part
  elf: Split _dl_lookup_map, _dl_map_new_object from _dl_map_object
  elf: Add l_soname accessor function for DT_SONAME values
  elf: _dl_rtld_map should not exist in static builds
  elf: Introduce GLPM accessor for the protected memory area
  elf: Bootstrap allocation for future protected memory allocator
  elf: Implement a basic protected memory allocator
  elf: Move most of the _dl_find_object data to the protected heap
  elf: Switch to a region-based protected memory allocator
  elf: Determine the caller link map in _dl_open
  elf: Add fast path to dlopen for fully-opened maps
  elf: Use _dl_find_object instead of _dl_find_dso_for_object in dlopen
  elf: Put critical _dl_find_object pointers into protected memory area
  elf: Add hash tables to speed up DT_NEEDED, dlopen lookups
  elf: Use memory protection keys for the protected memory allocator

 NEWS                                          |   4 +
 csu/libc-start.c                              |   7 +-
 csu/libc-tls.c                                |   8 +-
 debug/backtracesyms.c                         |   4 +-
 debug/backtracesymsfd.c                       |   6 +-
 dlfcn/dladdr1.c                               |   7 +-
 dlfcn/dlinfo.c                                |   4 +-
 dlfcn/tst-dlinfo-phdr.c                       |  15 +-
 elf/Makefile                                  |  24 +
 elf/circleload1.c                             |  18 +-
 elf/dl-addr-obj.c                             |   4 +-
 elf/dl-addr.c                                 |  13 +-
 elf/dl-audit.c                                |  25 +-
 elf/dl-cache.c                                |  33 +-
 elf/dl-call-libc-early-init.c                 |   2 +-
 elf/dl-call_fini.c                            |  11 +-
 elf/dl-close.c                                | 187 ++---
 elf/dl-debug.c                                |  12 -
 elf/dl-deps.c                                 | 177 +++--
 elf/dl-diagnostics.c                          |   2 +
 elf/dl-find_object.c                          | 167 ++---
 elf/dl-find_object.h                          |  21 +-
 elf/dl-fini.c                                 |  16 +-
 elf/dl-fptr.c                                 |   6 +-
 elf/dl-init.c                                 |  22 +-
 elf/dl-iteratephdr.c                          |  11 +-
 elf/dl-libc.c                                 | 115 +--
 elf/dl-libc_freeres.c                         |  94 ++-
 elf/dl-libname.c                              | 281 ++++++++
 elf/dl-libname.h                              | 121 ++++
 elf/dl-load.c                                 | 501 ++++++-------
 elf/dl-load.h                                 |   6 +-
 elf/dl-lookup-direct.c                        |   5 +-
 elf/dl-lookup.c                               | 150 ++--
 elf/dl-machine-reject-phdr.h                  |   4 +-
 elf/dl-map-segments.h                         |  16 +-
 elf/dl-minimal.c                              |   4 +-
 elf/dl-misc.c                                 |  20 -
 elf/dl-object.c                               | 181 +++--
 elf/dl-open.c                                 | 227 +++---
 elf/dl-profile.c                              |   4 +-
 elf/dl-protmem-internal.h                     | 100 +++
 elf/dl-protmem.c                              | 679 ++++++++++++++++++
 elf/dl-protmem.h                              | 102 +++
 elf/dl-protmem_bootstrap.h                    |  36 +
 elf/dl-reloc-static-pie.c                     |   7 +-
 elf/dl-reloc.c                                |  46 +-
 elf/dl-runtime.c                              |   6 +-
 elf/dl-setup_hash.c                           |   2 +-
 elf/dl-sort-maps.c                            |  53 +-
 elf/dl-static-tls.h                           |  10 +-
 elf/dl-support.c                              |  46 +-
 elf/dl-sym-post.h                             |   6 +-
 elf/dl-sym.c                                  |  10 +-
 elf/dl-symaddr.c                              |   2 +-
 elf/dl-sysdep-open.h                          |  45 --
 elf/dl-tls.c                                  |  61 +-
 elf/dl-tunables.list                          |   6 +
 elf/dl-unmap-segments.h                       |   2 +-
 elf/dl-usage.c                                |   2 +-
 elf/dl-version.c                              |  77 +-
 elf/do-rel.h                                  |  19 +-
 elf/dynamic-link.h                            |  14 +-
 elf/get-dynamic-info.h                        |  12 +-
 elf/libc-early-init.h                         |   6 +-
 elf/loadtest.c                                |  34 +-
 elf/neededtest.c                              |  18 +-
 elf/neededtest2.c                             |  18 +-
 elf/neededtest3.c                             |  18 +-
 elf/neededtest4.c                             |  18 +-
 elf/pldd-xx.c                                 |  19 +-
 elf/pldd.c                                    |   1 +
 elf/rtld.c                                    | 454 ++++++------
 elf/rtld_static_init.c                        |   2 +-
 elf/setup-vdso.h                              |  46 +-
 elf/sotruss-lib.c                             |   5 +-
 elf/sprof.c                                   |  27 +-
 elf/tlsdeschtab.h                             |   4 +-
 elf/tst-_dl_addr_inside_object.c              |  13 +-
 elf/tst-audit19a.c                            |   2 +-
 elf/tst-dl-protmem.c                          | 364 ++++++++++
 elf/tst-dl_find_object-threads.c              |   6 +-
 elf/tst-dl_find_object.c                      |  19 +-
 elf/tst-relro-linkmap-disabled-mod1.c         |  46 ++
 elf/tst-relro-linkmap-disabled-mod2.c         |   2 +
 elf/tst-relro-linkmap-disabled.c              |  64 ++
 elf/tst-relro-linkmap-mod1.c                  |  42 ++
 elf/tst-relro-linkmap-mod2.c                  |   2 +
 elf/tst-relro-linkmap-mod3.c                  |   2 +
 elf/tst-relro-linkmap.c                       | 112 +++
 elf/tst-rtld-list-tunables.exp                |   1 +
 elf/tst-rtld-nomem.c                          | 177 +++++
 elf/tst-tls6.c                                |   8 +-
 elf/tst-tls7.c                                |   8 +-
 elf/tst-tls8.c                                |  24 +-
 elf/unload.c                                  |  10 +-
 elf/unload2.c                                 |  10 +-
 htl/pt-alloc.c                                |   7 +-
 include/alloc_buffer.h                        |  26 +-
 include/dlfcn.h                               |   6 +-
 include/link.h                                | 178 +++--
 include/rtld-malloc.h                         |   5 +-
 include/set-freeres.h                         |   1 -
 libio/vtables.c                               |   2 +-
 malloc/Makefile                               |   6 +-
 malloc/Versions                               |   7 -
 malloc/alloc_buffer_alloc_array.c             |   1 -
 malloc/alloc_buffer_allocate.c                |   1 -
 malloc/alloc_buffer_copy_bytes.c              |   1 -
 malloc/alloc_buffer_copy_string.c             |   1 -
 malloc/alloc_buffer_create_failure.c          |   7 +-
 malloc/set-freeres.c                          |   2 -
 malloc/tst-alloc_buffer.c                     |   4 +
 manual/tunables.texi                          |  29 +
 nptl/Versions                                 |   3 +-
 nptl/pthread_create.c                         |   8 +
 nptl_db/db_info.c                             |   3 +-
 nptl_db/structs.def                           |   3 +-
 nptl_db/td_thr_tlsbase.c                      |  12 +-
 nss/Makefile                                  |   4 +-
 stdlib/cxa_thread_atexit_impl.c               |  10 +-
 stdlib/tst-tls-atexit.c                       |  10 +-
 support/Makefile                              |   3 +
 support/memprobe.h                            |  43 ++
 support/support-alloc_buffer.c                |  26 +
 support/support_memprobe.c                    | 251 +++++++
 support/tst-support_memprobe.c                | 118 +++
 sysdeps/aarch64/dl-bti.c                      |  14 +-
 sysdeps/aarch64/dl-lookupcfg.h                |   4 +-
 sysdeps/aarch64/dl-machine.h                  |  29 +-
 sysdeps/aarch64/dl-prop.h                     |  12 +-
 sysdeps/aarch64/dl-tlsdesc.h                  |   2 +-
 sysdeps/aarch64/tlsdesc.c                     |   2 +-
 sysdeps/alpha/dl-machine.h                    |  24 +-
 sysdeps/arc/dl-machine.h                      |  21 +-
 sysdeps/arm/dl-lookupcfg.h                    |   4 +-
 sysdeps/arm/dl-machine.h                      |  43 +-
 sysdeps/arm/dl-tlsdesc.h                      |   2 +-
 sysdeps/arm/tlsdesc.c                         |   2 +-
 sysdeps/csky/dl-machine.h                     |  22 +-
 sysdeps/generic/dl-debug.h                    |   2 +-
 sysdeps/generic/dl-early_mmap.h               |  35 +
 sysdeps/generic/dl-fptr.h                     |   4 +-
 sysdeps/generic/dl-prop.h                     |   8 +-
 sysdeps/generic/dl-protected.h                |  10 +-
 sysdeps/generic/dl-protmem-pkey.h             |  20 +
 sysdeps/generic/ldsodefs.h                    | 280 +++++---
 sysdeps/generic/rtld_static_init.h            |   3 +-
 sysdeps/hppa/dl-fptr.c                        |  10 +-
 sysdeps/hppa/dl-lookupcfg.h                   |   6 +-
 sysdeps/hppa/dl-machine.h                     |  29 +-
 sysdeps/hppa/dl-runtime.c                     |   4 +-
 sysdeps/hppa/dl-runtime.h                     |   2 +-
 sysdeps/hppa/dl-symaddr.c                     |   2 +-
 sysdeps/htl/pthreadP.h                        |   2 +-
 sysdeps/i386/dl-machine.h                     |  41 +-
 sysdeps/i386/dl-tlsdesc.h                     |   2 +-
 sysdeps/i386/tlsdesc.c                        |   2 +-
 sysdeps/ia64/dl-lookupcfg.h                   |   6 +-
 sysdeps/ia64/dl-machine.h                     |  29 +-
 sysdeps/loongarch/dl-machine.h                |  19 +-
 sysdeps/loongarch/dl-tls.h                    |   2 +-
 sysdeps/m68k/dl-machine.h                     |  20 +-
 sysdeps/m68k/dl-tls.h                         |   2 +-
 sysdeps/microblaze/dl-machine.h               |  23 +-
 sysdeps/mips/Makefile                         |   6 +
 sysdeps/mips/dl-debug.h                       |   2 +-
 sysdeps/mips/dl-machine-reject-phdr.h         |  20 +-
 sysdeps/mips/dl-machine.h                     |  74 +-
 sysdeps/mips/dl-tls.h                         |   2 +-
 sysdeps/mips/dl-trampoline.c                  |  19 +-
 sysdeps/nios2/dl-init.c                       |   6 +-
 sysdeps/nios2/dl-machine.h                    |  19 +-
 sysdeps/nios2/dl-tls.h                        |   2 +-
 sysdeps/nptl/dl-mutex.c                       |   2 +-
 sysdeps/or1k/dl-machine.h                     |  20 +-
 sysdeps/powerpc/dl-tls.h                      |   2 +-
 sysdeps/powerpc/powerpc32/dl-machine.c        |  19 +-
 sysdeps/powerpc/powerpc32/dl-machine.h        |  40 +-
 sysdeps/powerpc/powerpc64/dl-machine.c        |   8 +-
 sysdeps/powerpc/powerpc64/dl-machine.h        |  48 +-
 sysdeps/riscv/dl-machine.h                    |  26 +-
 sysdeps/riscv/dl-tls.h                        |   2 +-
 sysdeps/s390/s390-32/dl-machine.h             |  29 +-
 sysdeps/s390/s390-64/dl-machine.h             |  29 +-
 sysdeps/sh/dl-machine.h                       |  36 +-
 sysdeps/sparc/sparc32/dl-machine.h            |  24 +-
 sysdeps/sparc/sparc64/dl-irel.h               |   2 +-
 sysdeps/sparc/sparc64/dl-machine.h            |  27 +-
 sysdeps/sparc/sparc64/dl-plt.h                |   4 +-
 sysdeps/unix/sysv/linux/dl-early_allocate.c   |  17 +-
 sysdeps/unix/sysv/linux/dl-early_mmap.h       |  41 ++
 sysdeps/unix/sysv/linux/dl-origin.c           |   1 -
 sysdeps/unix/sysv/linux/dl-protmem-pkey.h     |  23 +
 sysdeps/unix/sysv/linux/dl-sysdep.c           |   2 +
 sysdeps/unix/sysv/linux/dl-vdso.h             |   2 +-
 .../sysv/linux/include/bits/mman-shared.h     |  16 +
 sysdeps/unix/sysv/linux/pkey_get.c            |   5 +-
 sysdeps/unix/sysv/linux/pkey_mprotect.c       |   4 +-
 sysdeps/unix/sysv/linux/pkey_set.c            |   5 +-
 sysdeps/unix/sysv/linux/powerpc/libc-start.c  |   2 +-
 .../sysv/linux/powerpc/powerpc64/ldsodefs.h   |  14 +-
 .../sysv/linux/powerpc/powerpc64/pkey_get.c   |   4 +-
 .../sysv/linux/powerpc/powerpc64/pkey_set.c   |   4 +-
 .../sysv/linux/powerpc/rtld_static_init.h     |   3 +-
 sysdeps/unix/sysv/linux/syscalls.list         |   4 +-
 sysdeps/unix/sysv/linux/x86/dl-protmem-pkey.h |  26 +
 sysdeps/unix/sysv/linux/x86/pkey_get.c        |   5 +-
 sysdeps/unix/sysv/linux/x86/pkey_set.c        |   5 +-
 sysdeps/x86/dl-cet.c                          |   4 +-
 sysdeps/x86/dl-lookupcfg.h                    |   4 +-
 sysdeps/x86/dl-prop.h                         |  29 +-
 sysdeps/x86_64/dl-machine.h                   |  39 +-
 sysdeps/x86_64/dl-tlsdesc.h                   |   2 +-
 sysdeps/x86_64/tlsdesc.c                      |   2 +-
 215 files changed, 5267 insertions(+), 2446 deletions(-)
 create mode 100644 elf/dl-libname.c
 create mode 100644 elf/dl-libname.h
 create mode 100644 elf/dl-protmem-internal.h
 create mode 100644 elf/dl-protmem.c
 create mode 100644 elf/dl-protmem.h
 create mode 100644 elf/dl-protmem_bootstrap.h
 delete mode 100644 elf/dl-sysdep-open.h
 create mode 100644 elf/tst-dl-protmem.c
 create mode 100644 elf/tst-relro-linkmap-disabled-mod1.c
 create mode 100644 elf/tst-relro-linkmap-disabled-mod2.c
 create mode 100644 elf/tst-relro-linkmap-disabled.c
 create mode 100644 elf/tst-relro-linkmap-mod1.c
 create mode 100644 elf/tst-relro-linkmap-mod2.c
 create mode 100644 elf/tst-relro-linkmap-mod3.c
 create mode 100644 elf/tst-relro-linkmap.c
 create mode 100644 elf/tst-rtld-nomem.c
 create mode 100644 support/memprobe.h
 create mode 100644 support/support-alloc_buffer.c
 create mode 100644 support/support_memprobe.c
 create mode 100644 support/tst-support_memprobe.c
 create mode 100644 sysdeps/generic/dl-early_mmap.h
 create mode 100644 sysdeps/generic/dl-protmem-pkey.h
 create mode 100644 sysdeps/unix/sysv/linux/dl-early_mmap.h
 create mode 100644 sysdeps/unix/sysv/linux/dl-protmem-pkey.h
 create mode 100644 sysdeps/unix/sysv/linux/include/bits/mman-shared.h
 create mode 100644 sysdeps/unix/sysv/linux/x86/dl-protmem-pkey.h


base-commit: 958478889c6a7a12b35b857b9788b7ad8706a01e
  

Comments

Andreas Schwab Dec. 7, 2023, 10:53 a.m. UTC | #1
Can you please provide a summary?
  
Florian Weimer Dec. 7, 2023, 10:56 a.m. UTC | #2
* Andreas Schwab:

> Can you please provide a summary?

The original cover letter is quite elaborate:

  <https://inbox.sourceware.org/libc-alpha/cover.1688499219.git.fweimer@redhat.com/>

Please let me know if you need something else.

Thanks,
Florian
  
Andreas Schwab Dec. 7, 2023, 11:34 a.m. UTC | #3
On Dez 07 2023, Florian Weimer wrote:

> * Andreas Schwab:
>
>> Can you please provide a summary?
>
> The original cover letter is quite elaborate:

Please either repeat it, or add is as References so that it can be found.
  
Adhemerval Zanella March 1, 2024, 2:45 p.m. UTC | #4
On 07/12/23 07:56, Florian Weimer wrote:
> * Andreas Schwab:
> 
>> Can you please provide a summary?
> 
> The original cover letter is quite elaborate:
> 
>   <https://inbox.sourceware.org/libc-alpha/cover.1688499219.git.fweimer@redhat.com/>
> 
> Please let me know if you need something else.

Also could you describe with more details the possible attack that targets
l_info[DT_FINI] and l_infi[DT_FINI_ARRAY]?  I would like to understand
better the attack vector mainly because this patchset re-adds a potential
startup failure (the _dl_protmem_bootstrap) now that we just removed it
from tunable initialization.
  
Florian Weimer March 11, 2024, 5:24 p.m. UTC | #5
* Adhemerval Zanella Netto:

> On 07/12/23 07:56, Florian Weimer wrote:
>> * Andreas Schwab:
>> 
>>> Can you please provide a summary?
>> 
>> The original cover letter is quite elaborate:
>> 
>>   <https://inbox.sourceware.org/libc-alpha/cover.1688499219.git.fweimer@redhat.com/>
>> 
>> Please let me know if you need something else.
>
> Also could you describe with more details the possible attack that targets
> l_info[DT_FINI] and l_infi[DT_FINI_ARRAY]?  I would like to understand
> better the attack vector mainly because this patchset re-adds a potential
> startup failure (the _dl_protmem_bootstrap) now that we just removed it
> from tunable initialization.

I think this has some details:

  Nightmare: One Byte to ROP // Alternate Solution
  <https://github.com/LMS57/Nightmare-Writeup>

I'm not sure if the first write-up that was shared with me is public.

Thanks,
Florian
  
Adhemerval Zanella March 12, 2024, 12:51 p.m. UTC | #6
On 11/03/24 14:24, Florian Weimer wrote:
> * Adhemerval Zanella Netto:
> 
>> On 07/12/23 07:56, Florian Weimer wrote:
>>> * Andreas Schwab:
>>>
>>>> Can you please provide a summary?
>>>
>>> The original cover letter is quite elaborate:
>>>
>>>   <https://inbox.sourceware.org/libc-alpha/cover.1688499219.git.fweimer@redhat.com/>
>>>
>>> Please let me know if you need something else.
>>
>> Also could you describe with more details the possible attack that targets
>> l_info[DT_FINI] and l_infi[DT_FINI_ARRAY]?  I would like to understand
>> better the attack vector mainly because this patchset re-adds a potential
>> startup failure (the _dl_protmem_bootstrap) now that we just removed it
>> from tunable initialization.
> 
> I think this has some details:
> 
>   Nightmare: One Byte to ROP // Alternate Solution
>   <https://github.com/LMS57/Nightmare-Writeup>
> 
> I'm not sure if the first write-up that was shared with me is public.

But how feasible is this attack in real work case? Reading through the
report, it requires some access no only to the binary, but to the
runtime as well to brute force the addresses, and it also seems to
rely on lazy resolution. With this reports, it does not indicate 
how useful is this kind of attack without adding a lot of priors.