Bug 233333 - Building libc WITH_BIND_NOW results in segfault at process start
Summary: Building libc WITH_BIND_NOW results in segfault at process start
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: Ed Maste
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-11-19 18:05 UTC by Ed Maste
Modified: 2021-02-08 01:14 UTC (History)
3 users (show)

See Also:


Attachments
Process plt irelocs together with other relocs early if LD_BIND_NOW is set. (1.13 KB, patch)
2018-11-20 12:21 UTC, Konstantin Belousov
no flags Details | Diff
Process plt irelocs together with other relocs early if LD_BIND_NOW is set. (1.13 KB, patch)
2018-11-20 12:21 UTC, Konstantin Belousov
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Maste freebsd_committer freebsd_triage 2018-11-19 18:05:48 UTC
Reproduction steps:
1. Set WITH_BIND_NOW=yes in /etc/src.conf
2. Install world to some directory
3. Try to chroot execute /bin/sh

# env LD_DEBUG=1 chroot . /bin/sh
/libexec/ld-elf.so.1 is initialized, base address = 0x3f49fd865000
RTLD dynamic = 0x3f49fd888310
RTLD pltgot  = 0
initializing thread locks
...
resolving ifuncs
reloc_jmpslot: *0xdf2395a830 = 0xdf23835630
Segmentation fault (core dumped)
Comment 1 commit-hook freebsd_committer freebsd_triage 2018-11-19 18:12:45 UTC
A commit references this bug:

Author: emaste
Date: Mon Nov 19 18:12:39 UTC 2018
New revision: 340640
URL: https://svnweb.freebsd.org/changeset/base/340640

Log:
  libc: forcibly disable BIND_NOW

  Building libc WITH_BIND_NOW results in segfault at process start.  For
  now force BIND_NOW off until the root cause can be identified and fixed.

  PR:		233333
  Sponsored by:	The FreeBSD Foundation

Changes:
  head/lib/libc/Makefile
Comment 2 Shawn Webb 2018-11-19 18:43:40 UTC
We did the same in HardenedBSD: https://github.com/HardenedBSD/hardenedBSD/commit/ccb4ab6b7607a05b680b167fc899abb27673b3c1

I wonder if the ifunc resolver must be called prior to BIND_NOW being activated by the RTLD.
Comment 3 Konstantin Belousov freebsd_committer freebsd_triage 2018-11-20 12:21:20 UTC
Created attachment 199379 [details]
Process plt irelocs together with other relocs early if LD_BIND_NOW is set.
Comment 4 Konstantin Belousov freebsd_committer freebsd_triage 2018-11-20 12:21:56 UTC
Created attachment 199380 [details]
Process plt irelocs together with other relocs early if LD_BIND_NOW is set.
Comment 5 Ed Maste freebsd_committer freebsd_triage 2018-11-20 13:56:50 UTC
Tested patch w/ r340640 reverted; works for me.
Comment 6 commit-hook freebsd_committer freebsd_triage 2018-11-20 14:53:43 UTC
A commit references this bug:

Author: kib
Date: Tue Nov 20 14:52:44 UTC 2018
New revision: 340675
URL: https://svnweb.freebsd.org/changeset/base/340675

Log:
  rtld: when immediate bind mode is requested, process irelocs in PLT
  immediately after other PLT relocs.

  Otherwise, if the object has relro page, we write to readonly page,
  and we would need to use mprotect(2) two more times to fix it.  Note
  that resolve_object_ifunc() does nothing when called second time, so
  there is no need to avoid existing call.

  Reported and tested by:	emaste
  PR:	233333
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Changes:
  head/libexec/rtld-elf/rtld.c
Comment 7 commit-hook freebsd_committer freebsd_triage 2018-11-26 13:56:31 UTC
A commit references this bug:

Author: emaste
Date: Mon Nov 26 13:56:19 UTC 2018
New revision: 340969
URL: https://svnweb.freebsd.org/changeset/base/340969

Log:
  revert r340640 "libc: forcibly disable BIND_NOW"

  When immediate bind mode is requested, as of r340675 rtld processes
  irelocs in PLT immediately after other PLT relocs.  That addresses the
  libc + BIND_NOW startup crash the workaround is no longer needed.

  PR:		233333

Changes:
  head/lib/libc/Makefile
Comment 8 commit-hook freebsd_committer freebsd_triage 2018-12-03 16:00:50 UTC
A commit references this bug:

Author: emaste
Date: Mon Dec  3 15:59:47 UTC 2018
New revision: 341429
URL: https://svnweb.freebsd.org/changeset/base/341429

Log:
  disable BIND_NOW in libc, libthr, and rtld

  An issue remains with BIND_NOW and processes using threads.  For now,
  restore libc's BIND_NOW disable, and also disable BIND_NOW in rtld and
  libthr.

  A patch is in review (D18400) that likely fixes this issue, but just
  disable BIND_NOW pending further testing after it is committed.

  PR:		233333
  Sponsored by:	The FreeBSD Foundation

Changes:
  head/lib/libc/Makefile
  head/lib/libthr/Makefile
  head/libexec/rtld-elf/Makefile
Comment 9 Ed Maste freebsd_committer freebsd_triage 2019-03-26 21:11:40 UTC
D18400 is committed, but reverting 341429 (tested in combination with WITH_RETPOLINE WITH_BIND_NOW WITH_PIE) still fails.
Comment 10 commit-hook freebsd_committer freebsd_triage 2019-03-28 02:12:55 UTC
A commit references this bug:

Author: emaste
Date: Thu Mar 28 02:12:33 UTC 2019
New revision: 345625
URL: https://svnweb.freebsd.org/changeset/base/345625

Log:
  revert r341429 "disable BIND_NOW in libc, libthr, and rtld"

  r345620 by kib@ fixed the rtld issue that caused a crash at startup
  during resolution of libc's ifuncs with BIND_NOW.

  PR:		233333
  Sponsored by:	The FreeBSD Foundation

Changes:
  head/contrib/elftoolchain/readelf/readelf.c
  head/lib/libc/Makefile
  head/lib/libthr/Makefile
  head/libexec/rtld-elf/Makefile
  head/sys/sys/elf_common.h
Comment 11 Ed Maste freebsd_committer freebsd_triage 2021-02-08 01:14:02 UTC
r352752 in stable/12 merged associated changes