Add version indicators to rtld.

It is wrong to relate on __FreeBSD_version, either from
include/param.h, kernel, or libc, to check for rtld features.
Rtld might be from newer world than the running userspace.

Add special private symbols exported by rtld itself, to indicate the
changes in runtime behavior, and features that cannot be otherwise
detected or deduced at runtime.

Note that the symbols are not exported from libc, so they intentionally
cannot be linked against, and exported from the private namespace from rtld.
Consumers are required to use dlsym(3).  For instance, for
_rtld_version_laddr_offset, user should do
	ptr = dlsym(RTLD_DEFAULT, "_rtld_version_laddr_offset")
or even
	ptr = dlvsym(RTLD_DEFAULT,  "_rtld_version_laddr_offset",
	    "FBSDprivate_1.0");
Non-null ptr means that the change is present.

Also add _rtld_version__FreeBSD_version indicator to report the
headers version used at time of the rtld build.

Reviewed by:	jhb
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D24982
This commit is contained in:
kib 2020-05-26 19:22:46 +00:00
parent 6f2650cf20
commit 6c255e9508
3 changed files with 57 additions and 0 deletions

View File

@ -32,4 +32,6 @@ FBSDprivate_1.0 {
_rtld_get_stack_prot;
_rtld_is_dlopened;
_r_debug_postinit;
_rtld_version__FreeBSD_version;
_rtld_version_laddr_offset;
};

View File

@ -355,6 +355,54 @@ ignores
and is naturally prone to race conditions.
Environments which rely on such restrictions are weak
and breakable on their own.
.Sh VERSIONING
Newer
.Nm
might provide some features or changes in runtime behavior that cannot be
easily detected at runtime by checking of the normal exported symbols.
Note that it is almost always wrong to verify
.Dv __FreeBSD_version
in userspace to detect features, either at compile or at run time,
because either kernel, or libc, or environment variables could not
match the running
.Nm .
.Pp
To solve the problem,
.Nm
exports some feature indicators in the
.Fx
private symbols namespace
.Dv FBSDprivate_1.0 .
Symbols start with the
.Dv _rtld_version
prefix.
Current list of defined symbols and corresponding features is:
.Bl -tag -width indent
.It Dv _rtld_version__FreeBSD_version
Symbol exports the value of the
.Dv __FreeBSD_version
definition as it was provided during the
.Nm
build.
The symbol is always present since the
.Dv _rtld_version
facility was introduced.
.It Dv _rtld_version_laddr_offset
The
.Va l_addr
member of the
.Vt link_map
structure contains the load offset of the shared object.
Before that,
.Va l_addr
contained the base address of the library.
See
.Xr dlinfo 3 .
.Pp
Also it indicates the presence of
.Va l_refname
member of the structure.
.El
.Sh FILES
.Bl -tag -width ".Pa /var/run/ld-elf32.so.hints" -compact
.It Pa /var/run/ld-elf.so.hints
@ -369,6 +417,7 @@ The libmap configuration file for 32-bit binaries on 64-bit system.
.Sh SEE ALSO
.Xr ld 1 ,
.Xr ldd 1 ,
.Xr dlinfo 3 ,
.Xr capsicum 4 ,
.Xr elf 5 ,
.Xr libmap.conf 5 ,

View File

@ -5785,3 +5785,9 @@ realloc(void *cp, size_t nbytes)
return (__crt_realloc(cp, nbytes));
}
extern int _rtld_version__FreeBSD_version __exported;
int _rtld_version__FreeBSD_version = __FreeBSD_version;
extern char _rtld_version_laddr_offset __exported;
char _rtld_version_laddr_offset;