Bug 24259

Summary: Call _dl_open_check after relocation is finished, to deal with CET failures
Product: glibc Reporter: H.J. Lu <hjl.tools>
Component: dynamic-linkAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: fweimer, github
Priority: P2 Flags: fweimer: security-
Version: 2.30   
Target Milestone: 2.30   
See Also: https://bugzilla.redhat.com/show_bug.cgi?id=1682954
https://sourceware.org/bugzilla/show_bug.cgi?id=20839
Host: Target:
Build: Last reconfirmed:
Bug Depends on:    
Bug Blocks: 24133    

Description H.J. Lu 2019-02-23 15:17:03 UTC
On Fedora 29, with

/etc/nsswitch.conf:

----
# To use db, put the "db" in front of "files" for entries you want to be
# looked up first in the databases
#
# Example:
#passwd:    db files nisplus nis
#shadow:    db files nisplus nis
#group:     db files nisplus nis

passwd:      files sss systemd
shadow:     files sss
group:       files sss systemd

#hosts:     db files nisplus nis dns
hosts:      files mdns4_minimal [NOTFOUND=return] dns myhostname

# Example - obey only what nisplus tells us...
#services:   nisplus [NOTFOUND=return] files
#networks:   nisplus [NOTFOUND=return] files
#protocols:  nisplus [NOTFOUND=return] files
#rpc:        nisplus [NOTFOUND=return] files
#ethers:     nisplus [NOTFOUND=return] files
#netmasks:   nisplus [NOTFOUND=return] files

bootparams: nisplus [NOTFOUND=return] files

ethers:     files
netmasks:   files
networks:   files
protocols:  files
rpc:        files
services:   files sss

netgroup:   nisplus sss

publickey:  nisplus

automount:  files nisplus
aliases:    files nisplus
---

[hjl@gnu-cet-1 nptl]$ ls /lib64/libnss_*
/lib64/libnss_compat-2.28.so      /lib64/libnss_mdns6.so.2
/lib64/libnss_compat.so.2         /lib64/libnss_mdns_minimal.so.2
/lib64/libnss_dns-2.28.so         /lib64/libnss_mdns.so.2
/lib64/libnss_dns.so.2            /lib64/libnss_myhostname.so.2
/lib64/libnss_files-2.28.so       /lib64/libnss_mymachines.so.2
/lib64/libnss_files.so.2          /lib64/libnss_resolve.so.2
/lib64/libnss_mdns4_minimal.so.2  /lib64/libnss_sss.so.2
/lib64/libnss_mdns4.so.2          /lib64/libnss_systemd.so.2
/lib64/libnss_mdns6_minimal.so.2
[hjl@gnu-cet-1 nptl]$ 

I got

Program received signal SIGSEGV, Segmentation fault.
0x00007ffef74f6e3c in __pthread_initialize_minimal_internal ()
    at nptl-init.c:280
280	  THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
(gdb) f 3
#3  0x00007ffff77e1a5a in call_init (l=0x40df60, argc=argc@entry=2, 
    argv=argv@entry=0x7fffffffd6a8, env=env@entry=0x7fffffffd6c0)
    at dl-init.c:58
58	    DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
(gdb) p *l
$2 = {l_addr = 140733047566336, 
  l_name = 0x40df00 "/export/build/gnu/tools-build/glibc-cet/build-x86_64-linux/nptl/libpthread.so.0", l_ld = 0x7ffef750ad80, l_next = 0x40cac0, 
  l_prev = 0x40d010, l_real = 0x40df60, l_ns = 0, l_libname = 0x40e3e0, 
  l_info = {0x0, 0x7ffef750ad90, 0x7ffef750ae80, 0x7ffef750ae70, 
    0x7ffef750ae10, 0x7ffef750ae30, 0x7ffef750ae40, 0x7ffef750aeb0, 
    0x7ffef750aec0, 0x7ffef750aed0, 0x7ffef750ae50, 0x7ffef750ae60, 
    0x7ffef750adb0, 0x7ffef750adc0, 0x7ffef750ada0, 0x0, 0x0, 0x0, 0x0, 0x0, 
    0x7ffef750ae90, 0x0, 0x0, 0x7ffef750aea0, 0x0, 0x7ffef750add0, 
    0x7ffef750adf0, 0x7ffef750ade0, 0x7ffef750ae00, 0x0, 0x7ffef750af00, 0x0, 
    0x0, 0x0, 0x0, 0x7ffef750af30, 0x7ffef750af20, 0x7ffef750aef0, 
    0x7ffef750aee0, 0x7ffef750af10, 0x0, 0x7ffef750af50, 0x0, 0x0, 0x0, 0x0, 
    0x0, 0x0, 0x0, 0x0, 0x7ffef750af40, 0x0 <repeats 25 times>, 
    0x7ffef750ae20}, l_phdr = 0x7ffef74ef040, l_entry = 140733047599520, 
  l_phnum = 13, l_ldnum = 35, l_searchlist = {r_list = 0x40f3d0, r_nlist = 3}, 
  l_symbolic_searchlist = {r_list = 0x40e3d8, r_nlist = 0}, l_loader = 0x0, 
  l_versions = 0x4106e0, l_nversions = 20, l_nbuckets = 524, 
  l_gnu_bitmask_idxbits = 31, l_gnu_shift = 11, 
  l_gnu_bitmask = 0x7ffef74f04e8, {l_gnu_buckets = 0x7ffef74f05e8, 
    l_chain = 0x7ffef74f05e8}, {l_gnu_chain_zero = 0x7ffef74f0c90, 
    l_buckets = 0x7ffef74f0c90}, l_direct_opencount = 0, l_type = lt_loaded, 
  l_relocated = 0, l_init_called = 1, l_global = 0, l_reserved = 0, 
  l_phdr_allocated = 0, l_soname_added = 0, l_faked = 0, l_need_tls_init = 0, 
  l_auditing = 0, l_audit_any_plt = 0, l_removed = 0, l_contiguous = 1, 
  l_symbolic_in_local_scope = 0, l_free_initfini = 1, l_cet = 7, 
  l_rpath_dirs = {dirs = 0x0, malloced = 0}, l_reloc_result = 0x0, 
  l_versyms = 0x7ffef74f4b36, 
  l_origin = 0x40e410 "/export/build/gnu/tools-build/glibc-cet/build-x86_64-linux/nptl", l_map_start = 140733047566336, l_map_end = 140733047698592, 
  l_text_end = 140733047656448, l_scope_mem = {0x7ffff77fe450, 0x40cd80, 0x0, 
    0x0}, l_scope_max = 4, l_scope = 0x410fb0, l_local_scope = {0x40e220, 
    0x0}, l_file_id = {dev = 2049, ino = 3020850}, l_runpath_dirs = {
    dirs = 0x0, malloced = 0}, l_initfini = 0x40f3b0, l_reldeps = 0x0, 
  l_reldepsmax = 0, l_used = 1, l_feature_1 = 0, l_flags_1 = 40, l_flags = 16, 
  l_idx = -1, l_mach = {plt = 0, gotplt = 0, tlsdesc_table = 0x0}, 
  l_lookup_cache = {sym = 0x0, type_class = 0, value = 0x0, ret = 0x0}, 
  l_tls_initimage = 0x0, l_tls_initimage_size = 0, l_tls_blocksize = 0, 
  l_tls_align = 0, l_tls_firstbyte_offset = 0, l_tls_offset = 0, 
  l_tls_modid = 0, l_tls_dtor_count = 0, l_relro_addr = 113576, 
  l_relro_size = 1112, l_serial = 13, l_audit = 0x40e3d8}
(gdb) p l->l_relocated
$3 = 0
(gdb) 

DT_INIT is called before libpthread.so.0 is relocated.
Comment 1 H.J. Lu 2019-02-23 15:43:55 UTC
Glibc is built with --enable-cet on CET SDV.
Comment 2 H.J. Lu 2019-02-24 16:04:17 UTC
A patch is posted at

https://sourceware.org/ml/libc-alpha/2019-02/msg00579.html
Comment 3 Sourceware Commits 2019-07-01 19:45:41 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d0093c5cefb7f7a4143f3bb03743633823229cc6

commit d0093c5cefb7f7a4143f3bb03743633823229cc6
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jul 1 12:23:10 2019 -0700

    Call _dl_open_check after relocation [BZ #24259]
    
    This is a workaround for [BZ #20839] which doesn't remove the NODELETE
    object when _dl_open_check throws an exception.  Move it after relocation
    in dl_open_worker to avoid leaving the NODELETE object mapped without
    relocation.
    
    	[BZ #24259]
    	* elf/dl-open.c (dl_open_worker): Call _dl_open_check after
    	relocation.
    	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-5a,
    	tst-cet-legacy-5b, tst-cet-legacy-6a and tst-cet-legacy-6b.
    	(modules-names): Add tst-cet-legacy-mod-5a, tst-cet-legacy-mod-5b,
    	tst-cet-legacy-mod-5c, tst-cet-legacy-mod-6a, tst-cet-legacy-mod-6b
    	and tst-cet-legacy-mod-6c.
    	(CFLAGS-tst-cet-legacy-5a.c): New.
    	(CFLAGS-tst-cet-legacy-5b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5c.c): Likewise.
    	(CFLAGS-tst-cet-legacy-6a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-6b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6c.c): Likewise.
    	($(objpfx)tst-cet-legacy-5a): Likewise.
    	($(objpfx)tst-cet-legacy-5a.out): Likewise.
    	($(objpfx)tst-cet-legacy-mod-5a.so): Likewise.
    	($(objpfx)tst-cet-legacy-mod-5b.so): Likewise.
    	($(objpfx)tst-cet-legacy-5b): Likewise.
    	($(objpfx)tst-cet-legacy-5b.out): Likewise.
    	(tst-cet-legacy-5b-ENV): Likewise.
    	($(objpfx)tst-cet-legacy-6a): Likewise.
    	($(objpfx)tst-cet-legacy-6a.out): Likewise.
    	($(objpfx)tst-cet-legacy-mod-6a.so): Likewise.
    	($(objpfx)tst-cet-legacy-mod-6b.so): Likewise.
    	($(objpfx)tst-cet-legacy-6b): Likewise.
    	($(objpfx)tst-cet-legacy-6b.out): Likewise.
    	(tst-cet-legacy-6b-ENV): Likewise.
    	* sysdeps/x86/tst-cet-legacy-5.c: New file.
    	* sysdeps/x86/tst-cet-legacy-5a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-5b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5c.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6c.c: Likewise.
Comment 4 Sourceware Commits 2019-10-31 21:24:04 UTC
The release/2.28/master branch has been updated by DJ Delorie <dj@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=0d3905b110000463775b3fb189213833acaebf81

commit 0d3905b110000463775b3fb189213833acaebf81
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jul 1 12:23:10 2019 -0700

    Call _dl_open_check after relocation [BZ #24259]
    
    This is a workaround for [BZ #20839] which doesn't remove the NODELETE
    object when _dl_open_check throws an exception.  Move it after relocation
    in dl_open_worker to avoid leaving the NODELETE object mapped without
    relocation.
    
    	[BZ #24259]
    	* elf/dl-open.c (dl_open_worker): Call _dl_open_check after
    	relocation.
    	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-5a,
    	tst-cet-legacy-5b, tst-cet-legacy-6a and tst-cet-legacy-6b.
    	(modules-names): Add tst-cet-legacy-mod-5a, tst-cet-legacy-mod-5b,
    	tst-cet-legacy-mod-5c, tst-cet-legacy-mod-6a, tst-cet-legacy-mod-6b
    	and tst-cet-legacy-mod-6c.
    	(CFLAGS-tst-cet-legacy-5a.c): New.
    	(CFLAGS-tst-cet-legacy-5b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5c.c): Likewise.
    	(CFLAGS-tst-cet-legacy-6a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-6b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6c.c): Likewise.
    	($(objpfx)tst-cet-legacy-5a): Likewise.
    	($(objpfx)tst-cet-legacy-5a.out): Likewise.
    	($(objpfx)tst-cet-legacy-mod-5a.so): Likewise.
    	($(objpfx)tst-cet-legacy-mod-5b.so): Likewise.
    	($(objpfx)tst-cet-legacy-5b): Likewise.
    	($(objpfx)tst-cet-legacy-5b.out): Likewise.
    	(tst-cet-legacy-5b-ENV): Likewise.
    	($(objpfx)tst-cet-legacy-6a): Likewise.
    	($(objpfx)tst-cet-legacy-6a.out): Likewise.
    	($(objpfx)tst-cet-legacy-mod-6a.so): Likewise.
    	($(objpfx)tst-cet-legacy-mod-6b.so): Likewise.
    	($(objpfx)tst-cet-legacy-6b): Likewise.
    	($(objpfx)tst-cet-legacy-6b.out): Likewise.
    	(tst-cet-legacy-6b-ENV): Likewise.
    	* sysdeps/x86/tst-cet-legacy-5.c: New file.
    	* sysdeps/x86/tst-cet-legacy-5a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-5b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5c.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6c.c: Likewise.
    
    (cherry picked from commit d0093c5cefb7f7a4143f3bb03743633823229cc6)
Comment 5 Sourceware Commits 2019-10-31 21:29:32 UTC
The release/2.29/master branch has been updated by DJ Delorie <dj@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=5e1548a6d9c5c544f13cb71f4462b3f38e87a3c6

commit 5e1548a6d9c5c544f13cb71f4462b3f38e87a3c6
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Jul 1 12:23:10 2019 -0700

    Call _dl_open_check after relocation [BZ #24259]
    
    This is a workaround for [BZ #20839] which doesn't remove the NODELETE
    object when _dl_open_check throws an exception.  Move it after relocation
    in dl_open_worker to avoid leaving the NODELETE object mapped without
    relocation.
    
    	[BZ #24259]
    	* elf/dl-open.c (dl_open_worker): Call _dl_open_check after
    	relocation.
    	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-5a,
    	tst-cet-legacy-5b, tst-cet-legacy-6a and tst-cet-legacy-6b.
    	(modules-names): Add tst-cet-legacy-mod-5a, tst-cet-legacy-mod-5b,
    	tst-cet-legacy-mod-5c, tst-cet-legacy-mod-6a, tst-cet-legacy-mod-6b
    	and tst-cet-legacy-mod-6c.
    	(CFLAGS-tst-cet-legacy-5a.c): New.
    	(CFLAGS-tst-cet-legacy-5b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-5c.c): Likewise.
    	(CFLAGS-tst-cet-legacy-6a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-6b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6a.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6b.c): Likewise.
    	(CFLAGS-tst-cet-legacy-mod-6c.c): Likewise.
    	($(objpfx)tst-cet-legacy-5a): Likewise.
    	($(objpfx)tst-cet-legacy-5a.out): Likewise.
    	($(objpfx)tst-cet-legacy-mod-5a.so): Likewise.
    	($(objpfx)tst-cet-legacy-mod-5b.so): Likewise.
    	($(objpfx)tst-cet-legacy-5b): Likewise.
    	($(objpfx)tst-cet-legacy-5b.out): Likewise.
    	(tst-cet-legacy-5b-ENV): Likewise.
    	($(objpfx)tst-cet-legacy-6a): Likewise.
    	($(objpfx)tst-cet-legacy-6a.out): Likewise.
    	($(objpfx)tst-cet-legacy-mod-6a.so): Likewise.
    	($(objpfx)tst-cet-legacy-mod-6b.so): Likewise.
    	($(objpfx)tst-cet-legacy-6b): Likewise.
    	($(objpfx)tst-cet-legacy-6b.out): Likewise.
    	(tst-cet-legacy-6b-ENV): Likewise.
    	* sysdeps/x86/tst-cet-legacy-5.c: New file.
    	* sysdeps/x86/tst-cet-legacy-5a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-5b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-6b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-5c.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6a.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6b.c: Likewise.
    	* sysdeps/x86/tst-cet-legacy-mod-6c.c: Likewise.
    
    (cherry picked from commit d0093c5cefb7f7a4143f3bb03743633823229cc6)
Comment 6 Sourceware Commits 2019-11-27 20:21:28 UTC
The master branch has been updated by Florian Weimer <fw@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=e37c2cf299b61ce18f62852f6c5624c27829b610

commit e37c2cf299b61ce18f62852f6c5624c27829b610
Author: Florian Weimer <fweimer@redhat.com>
Date:   Thu Oct 31 18:48:43 2019 +0100

    Move _dl_open_check to its original place in dl_open_worker
    
    This reverts the non-test change from commit d0093c5cefb7f7a4143f
    ("Call _dl_open_check after relocation [BZ #24259]"), given that
    the underlying bug has been fixed properly in commit 61b74477fa7f63
    ("Remove all loaded objects if dlopen fails, ignoring NODELETE
    [BZ #20839]").
    
    Tested on x86-64-linux-gnu, with and without --enable-cet.
    
    Change-Id: I995a6cfb89f25d2b0cf5e606428c2a93eb48fc33