Bug 187114

Summary: rtld(1) does not expand $ORIGIN unless DF_ORIGIN flag is set
Product: Base System Reporter: Ed Maste <emaste>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Some People Flags: emaste: mfc-stable10+
Priority: Normal    
Version: CURRENT   
Hardware: Any   
OS: Any   

Description Ed Maste freebsd_committer freebsd_triage 2014-02-27 16:30:01 UTC
rtld-elf requires the DF_ORIGIN flag to be set, in order to substitute
$ORIGIN in rpath.  This is not required by Linux's runtime linker, and
apparently not by any other system.

Based on old SCO documentation of the DF_ORIGIN flag it appears the
purpose of the flag is to force early resolution of $ORIGIN for the case
of an executable that does not use $ORIGIN in rpath, but later expects to
dlopen() a library that does.

http://www.sco.com/developers/gabi/2003-12-17/ch5.dynamic.html

The GNU ld documentation describes "-z origin" as "Marks the object may
contain $ORIGIN," which is not particularly helpful.  The GNU gold
linker though hints at the interpretation above: "Mark DSO to indicate
that needs immediate $ORIGIN processing at runtime."
Comment 1 Ed Maste freebsd_committer freebsd_triage 2015-04-24 18:06:16 UTC
When the dynamic linker loads an object that uses $ORIGIN, it must calculate the pathname of the directory containing the object. Because this calculation can be computationally expensive, implementations may want to avoid the calculation for objects that do not use $ORIGIN. If an object calls dlopen() with a string containing $ORIGIN and does not use $ORIGIN in one if its dynamic array entries, the dynamic linker may not have calculated the pathname for the object until the dlopen() actually occurs. Since the application may have changed its current working directory before the dlopen() call, the calculation may not yield the correct result. To avoid this possibility, an object may signal its intention to reference $ORIGIN by setting the DF_ORIGIN flag. An implementation may reject an attempt to use $ORIGIN within a dlopen() call from an object that did not set the DF_ORIGIN flag and did not use $ORIGIN within its dynamic array.
Comment 2 Ed Maste freebsd_committer freebsd_triage 2015-04-24 18:11:19 UTC
(In reply to Ed Maste from comment #1)
(text above from http://www.sco.com/developers/gabi/2003-12-17/ch5.dynamic.html#substitution)
Comment 3 Ed Maste freebsd_committer freebsd_triage 2015-04-25 00:55:47 UTC
It turns out I had a conclusive answer on this a couple of months ago, but unfortunately forgot about it:

> Ed is correct.   The handling of ${ORIGIN} was introduced the Generic
> Application Binary Interface by July of 2000.
>
> The DF_ORIGIN is only necessary if the a.out does not use ${ORIGIN} in a 
> DT_NEEDED or DT_RUNPATH tag. and expects or anticipates that a $ORIGIN 
> may be encountered later in the execution such as a dlopen() call.   
> DF_ORIGIN was provided as a means of insuring correct results in these 
> delayed pathname resolutions without requiring every a.out to incur the 
> cost of a realpath() for its true location when started.

http://lists.cs.uiuc.edu/pipermail/lldb-dev/2014-February/003428.html
Comment 4 Ed Maste freebsd_committer freebsd_triage 2015-04-27 18:45:57 UTC
Committed in r282109
https://svnweb.freebsd.org/changeset/base/282109
Comment 5 Ed Maste freebsd_committer freebsd_triage 2016-01-04 21:01:48 UTC
Merged to stable/10 in 282412