[RFC,v13,0/9] Implementation of RTLD_SHARED for dlmopen

Message ID 20210929162642.21985-1-vivek@collabora.com
Headers
Series Implementation of RTLD_SHARED for dlmopen |

Message

Vivek Dasmohapatra Sept. 29, 2021, 4:26 p.m. UTC
  This is a revision of a previous patchset that I posted here
regarding https://sourceware.org/bugzilla/show_bug.cgi?id=22745 

Introduction:

=======================================================================
  As discussed in the URL above dlmopen requires a mechanism for
  [optionally] sharing some objects between more than one namespace.

  The following patchset provides an implementation for this: If an
  object is loaded with the new RTLD_SHARED flag we instead ensure
  that a "master" copy exists (and is flagged as no-delete) in the
  main namespace and a thin wrapper or clone is placed in the target
  namespace.

  In addition a new ELF dynamic section and flag are introduced which
  indicate that the DSO in question should be shared between namespaces
  by default, and the core libc DSOs are tagged as such by default.

  This patch series should address all the comments received on the
  earlier (v1-v12) series.

=======================================================================

Changes from v12:

 - Added NEWS entry.

 - Updated patch series to glibc 2.35 as a base.

 - The following DSOs no longer have the new flag since they are stubs:
   {htl,nptl}/libpthread, dlfcn/libdl, login/libutil, resolv/libanl

Changes from v11:

 - If a DSO is required in a non-base namespace because it is mentioned
   in a DT_NEEDED entry and it is itself flagged DF_GNU_1_UNIQUE then
   a proxy is generated for it.

 - Relocations via non-base namespace proxies work reliably (some code
   paths did not do the address calculation relative to the DSO base
   correctly when a proxy was involved).

 - Tests extended cover the above two scenarios.

Changes from v10:

 - A segfault in a dlmopen error pathway (which does not seem to have existed
   when v10 was applied to the then-HEAD commit) has been fixed.

 - The fallback mechanism for adding DT_GNU_FLAGS_1 sections to the required
   binaries has had some infrastructure moved to the elf/ directory

 - The runstatedir setting introduced by recent autoconf has been omitted from
   the patchset as it is not relevant to this feature.

 - libpthread no longer tagged DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE.
   (with both -z unique supporting linkers and if the .os hack is
   used to add the new flag - this was inconsistent before).

Not changed:

 - There is still some diagnostic info in the config.log when the linker
   layout is acceptable but -z unique is not yet supported. I believe this
   _is_ useful diagnostic information as a developer might otherwise wonder
   why the vanilla linker was being rejected when its layout output seemed
   fine.

I have not yet implemented, but plan to address once this series is
accepted/acceptable:

 - dl_iterate_ns_phdr (cf dl_iterate_phdr but taking a namespace argument)

 - Check RTLD_GLOBAL interacts properly and unsurprisingly with RTLD_SHARED.

Vivek Das Mohapatra (9):
  Define a new dynamic section tag - DT_GNU_FLAGS_1 (bug 22745)
  Abstract loaded-DSO search code into a helper function
  Use the new DSO finder helper function
  Add DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE to glibc DSOs (bug 22745)
  Implement dlmopen RTLD_SHARED flag (bug 22745)
  Add dlmopen / RTLD_SHARED tests
  Restore separate libc loading for the TLS/namespace storage test
  Drop DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE from merged libraries
  NEWS for RTLD_SHARED, RTLD_ISOLATE & DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE

 Makeconfig                           |   3 +
 Makerules                            |  18 +-
 NEWS                                 |  17 +
 bits/dlfcn.h                         |  10 +
 config.make.in                       |   1 +
 configure                            |  42 +-
 configure.ac                         |  31 +-
 dlfcn/Makefile                       |   1 +
 elf/Makefile                         | 109 +++-
 elf/dl-close.c                       |  43 +-
 elf/dl-deps.c                        |  17 +
 elf/dl-fini.c                        |   6 +-
 elf/dl-init.c                        |   4 +-
 elf/dl-load.c                        | 223 ++++++-
 elf/dl-lookup.c                      |  26 +-
 elf/dl-object.c                      |  78 +++
 elf/dl-open.c                        | 128 +++-
 elf/dl-sym.c                         |  14 +
 elf/dynamic-notes.c                  |   4 +
 elf/elf.h                            |   7 +-
 elf/get-dynamic-info.h               |  12 +
 elf/rtld.c                           |   2 +-
 elf/tst-dlmopen-auditmod.c           |  23 +
 elf/tst-dlmopen-common.h             |  33 +
 elf/tst-dlmopen-main.h               | 879 +++++++++++++++++++++++++++
 elf/tst-dlmopen-modules.h            |  21 +
 elf/tst-dlmopen-rtld-audit-shared1.c |   8 +
 elf/tst-dlmopen-rtld-audit-shared2.c |   8 +
 elf/tst-dlmopen-rtld-audit-shared3.c |   7 +
 elf/tst-dlmopen-rtld-audit-shared4.c |   8 +
 elf/tst-dlmopen-rtld-audit-shared5.c |   8 +
 elf/tst-dlmopen-rtld-audit-shared6.c |   8 +
 elf/tst-dlmopen-rtld-audit-unique1.c |   7 +
 elf/tst-dlmopen-rtld-audit-unique2.c |   7 +
 elf/tst-dlmopen-rtld-audit-unique3.c |   7 +
 elf/tst-dlmopen-rtld-audit-unique4.c |   7 +
 elf/tst-dlmopen-rtld-audit-unique5.c |   7 +
 elf/tst-dlmopen-rtld-audit-unique6.c |   7 +
 elf/tst-dlmopen-rtld-shared1.c       |   7 +
 elf/tst-dlmopen-rtld-shared1.h       |  64 ++
 elf/tst-dlmopen-rtld-shared2.c       |   7 +
 elf/tst-dlmopen-rtld-shared2.h       |  66 ++
 elf/tst-dlmopen-rtld-shared3.c       |   7 +
 elf/tst-dlmopen-rtld-shared3.h       |  43 ++
 elf/tst-dlmopen-rtld-shared4.c       |   7 +
 elf/tst-dlmopen-rtld-shared4.h       |  14 +
 elf/tst-dlmopen-rtld-shared5.c       |   7 +
 elf/tst-dlmopen-rtld-shared5.h       |  25 +
 elf/tst-dlmopen-rtld-shared6.c       |   7 +
 elf/tst-dlmopen-rtld-shared6.h       |  36 ++
 elf/tst-dlmopen-rtld-unique1.c       |   7 +
 elf/tst-dlmopen-rtld-unique1.h       |  86 +++
 elf/tst-dlmopen-rtld-unique2.c       |   7 +
 elf/tst-dlmopen-rtld-unique2.h       |  25 +
 elf/tst-dlmopen-rtld-unique3.c       |   7 +
 elf/tst-dlmopen-rtld-unique3.h       |  13 +
 elf/tst-dlmopen-rtld-unique4.c       |   7 +
 elf/tst-dlmopen-rtld-unique4.h       |  14 +
 elf/tst-dlmopen-rtld-unique5.c       |   7 +
 elf/tst-dlmopen-rtld-unique5.h       |  58 ++
 elf/tst-dlmopen-rtld-unique6.c       |   7 +
 elf/tst-dlmopen-rtld-unique6.h       |  51 ++
 elf/tst-dlmopen-sharedmod-norm.c     |  34 ++
 elf/tst-dlmopen-sharedmod-uniq.c     |  33 +
 elf/tst-dlmopen-std-do-test.c        |  12 +
 elf/tst-tls-ie-dlmopen.c             |   4 +-
 extra-lib.mk                         |  28 +
 htl/Makefile                         |   2 +
 iconvdata/Makefile                   |   3 +
 iconvdata/extra-module.mk            |   4 +
 include/elf.h                        |   2 +
 include/link.h                       |   7 +-
 login/Makefile                       |   1 +
 nptl/Makefile                        |   5 +-
 resolv/Makefile                      |   2 +
 sysdeps/generic/ldsodefs.h           |  11 +
 sysdeps/mips/bits/dlfcn.h            |  10 +
 77 files changed, 2501 insertions(+), 77 deletions(-)
 create mode 100644 elf/dynamic-notes.c
 create mode 100644 elf/tst-dlmopen-auditmod.c
 create mode 100644 elf/tst-dlmopen-common.h
 create mode 100644 elf/tst-dlmopen-main.h
 create mode 100644 elf/tst-dlmopen-modules.h
 create mode 100644 elf/tst-dlmopen-rtld-audit-shared1.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-shared2.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-shared3.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-shared4.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-shared5.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-shared6.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-unique1.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-unique2.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-unique3.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-unique4.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-unique5.c
 create mode 100644 elf/tst-dlmopen-rtld-audit-unique6.c
 create mode 100644 elf/tst-dlmopen-rtld-shared1.c
 create mode 100644 elf/tst-dlmopen-rtld-shared1.h
 create mode 100644 elf/tst-dlmopen-rtld-shared2.c
 create mode 100644 elf/tst-dlmopen-rtld-shared2.h
 create mode 100644 elf/tst-dlmopen-rtld-shared3.c
 create mode 100644 elf/tst-dlmopen-rtld-shared3.h
 create mode 100644 elf/tst-dlmopen-rtld-shared4.c
 create mode 100644 elf/tst-dlmopen-rtld-shared4.h
 create mode 100644 elf/tst-dlmopen-rtld-shared5.c
 create mode 100644 elf/tst-dlmopen-rtld-shared5.h
 create mode 100644 elf/tst-dlmopen-rtld-shared6.c
 create mode 100644 elf/tst-dlmopen-rtld-shared6.h
 create mode 100644 elf/tst-dlmopen-rtld-unique1.c
 create mode 100644 elf/tst-dlmopen-rtld-unique1.h
 create mode 100644 elf/tst-dlmopen-rtld-unique2.c
 create mode 100644 elf/tst-dlmopen-rtld-unique2.h
 create mode 100644 elf/tst-dlmopen-rtld-unique3.c
 create mode 100644 elf/tst-dlmopen-rtld-unique3.h
 create mode 100644 elf/tst-dlmopen-rtld-unique4.c
 create mode 100644 elf/tst-dlmopen-rtld-unique4.h
 create mode 100644 elf/tst-dlmopen-rtld-unique5.c
 create mode 100644 elf/tst-dlmopen-rtld-unique5.h
 create mode 100644 elf/tst-dlmopen-rtld-unique6.c
 create mode 100644 elf/tst-dlmopen-rtld-unique6.h
 create mode 100644 elf/tst-dlmopen-sharedmod-norm.c
 create mode 100644 elf/tst-dlmopen-sharedmod-uniq.c
 create mode 100644 elf/tst-dlmopen-std-do-test.c
  

Comments

Joseph Myers Sept. 29, 2021, 4:43 p.m. UTC | #1
On Wed, 29 Sep 2021, Vivek Das Mohapatra via Libc-alpha wrote:

>  - The following DSOs no longer have the new flag since they are stubs:
>    {htl,nptl}/libpthread, dlfcn/libdl, login/libutil, resolv/libanl

The HTL libpthread implementation hasn't been merged into libc, unlike 
NPTL.  Probably it *should* be, but it hasn't happened yet.  (And, thus, 
on Hurd, libanl hasn't been merged into libc because it depends on 
libpthread.)

On the other hand, librt has been merged into libc on Linux (not Hurd, for 
the same reason of dependency on libpthread), despite that not being 
mentioned in the NEWS entry for 2.34.
  
Vivek Dasmohapatra Sept. 29, 2021, 5:32 p.m. UTC | #2
On Wed, 29 Sep 2021, Joseph Myers wrote:

> On Wed, 29 Sep 2021, Vivek Das Mohapatra via Libc-alpha wrote:
>
>>  - The following DSOs no longer have the new flag since they are stubs:
>>    {htl,nptl}/libpthread, dlfcn/libdl, login/libutil, resolv/libanl
>
> The HTL libpthread implementation hasn't been merged into libc, unlike
> NPTL.  Probably it *should* be, but it hasn't happened yet.  (And, thus,
> on Hurd, libanl hasn't been merged into libc because it depends on
> libpthread.)

Hm. Ok. Thanks for the heads up.

I can restore the flag for htl/pthread easily enough.

I'm less certain how to do this properly conditionaly for anl but I'll
look into it. Possibly I'll just restore the flag for libanl (see below).

> On the other hand, librt has been merged into libc on Linux (not Hurd, for
> the same reason of dependency on libpthread), despite that not being
> mentioned in the NEWS entry for 2.34.

It's harmless for a stub library to have the flag if it doesn't need it,
so I'll probably leave librt tagged until it's fully merged (unless it's
easy to to do conditionally given the current setup).

Not worth introducing a ton of complexity into the build system for imo.
  
Adhemerval Zanella Sept. 29, 2021, 6:33 p.m. UTC | #3
On 29/09/2021 13:26, Vivek Das Mohapatra via Libc-alpha wrote:
> This is a revision of a previous patchset that I posted here
> regarding https://sourceware.org/bugzilla/show_bug.cgi?id=22745 
> 
> Introduction:
> 
> =======================================================================
>   As discussed in the URL above dlmopen requires a mechanism for
>   [optionally] sharing some objects between more than one namespace.
> 
>   The following patchset provides an implementation for this: If an
>   object is loaded with the new RTLD_SHARED flag we instead ensure
>   that a "master" copy exists (and is flagged as no-delete) in the
>   main namespace and a thin wrapper or clone is placed in the target
>   namespace.
> 
>   In addition a new ELF dynamic section and flag are introduced which
>   indicate that the DSO in question should be shared between namespaces
>   by default, and the core libc DSOs are tagged as such by default.
> 
>   This patch series should address all the comments received on the
>   earlier (v1-v12) series.
> 
> =======================================================================
> 
> Changes from v12:
> 
>  - Added NEWS entry.
> 
>  - Updated patch series to glibc 2.35 as a base.
> 
>  - The following DSOs no longer have the new flag since they are stubs:
>    {htl,nptl}/libpthread, dlfcn/libdl, login/libutil, resolv/libanl
You seemed to have completely ignored my last review (for instance
https://sourceware.org/pipermail/libc-alpha/2021-August/129961.html),
so I won't bother to spent time checking on this version. 

All of them were done on August [1] and I have even sent a message
added that I fixed fixed the issues I found [2] (I also sent a private
email about it).

Anyway, if someone else want to review this version fell free.

[1] https://sourceware.org/pipermail/libc-alpha/2021-August/thread.html
[2] https://sourceware.org/pipermail/libc-alpha/2021-August/129982.html
  
Vivek Dasmohapatra Sept. 29, 2021, 7:30 p.m. UTC | #4
> You seemed to have completely ignored my last review (for instance
> https://sourceware.org/pipermail/libc-alpha/2021-August/129961.html),
> so I won't bother to spent time checking on this version.

I do apologise, I was busy with other work and I must have missed those.
I'll go through them.