aboutsummaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-06-12 22:10:03 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-06-12 22:10:03 +0000
commit510b525fa5fd77d2d52a6e72c848c1cb9a04f8e1 (patch)
tree5e8a64bf094b2ff8d74363e5799c87f34656736c /libexec
parent3e6e3de0aa0a25d4e2ddc43e19ed4686353ceb44 (diff)
downloadsrc-510b525fa5fd77d2d52a6e72c848c1cb9a04f8e1.tar.gz
src-510b525fa5fd77d2d52a6e72c848c1cb9a04f8e1.zip
rtld: set osrel when in the direct exec mode.
Rtld itself is a shared object which does not have vendor note, so after the direct exec of ld-elf.so.1 process has p_osrel set to zero. This affects the ABI of syscalls. Set osrel to the __FreeBSD_version value at compile time right after rtld identified direct exec mode. Then, switch to the osrel read from the binary note or zero if no note, right before starting calling ifunc resolvers, which is the first byte of the user code. Sponsored by: The FreeBSD Foundation MFC after: 1 week
Notes
Notes: svn path=/head/; revision=362128
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/rtld-libc/Makefile.inc2
-rw-r--r--libexec/rtld-elf/rtld.c33
2 files changed, 32 insertions, 3 deletions
diff --git a/libexec/rtld-elf/rtld-libc/Makefile.inc b/libexec/rtld-elf/rtld-libc/Makefile.inc
index 2134c1e6f095..e5759b5dcf91 100644
--- a/libexec/rtld-elf/rtld-libc/Makefile.inc
+++ b/libexec/rtld-elf/rtld-libc/Makefile.inc
@@ -46,7 +46,7 @@ _libc_string_objects= bcmp bcopy bzero memset memchr memcmp memcpy memmove \
# Also use all the syscall .o files from libc_nossp_pic:
_libc_other_objects= sigsetjmp lstat stat fstat fstatat fstatfs syscall \
cerror geteuid getegid sigfastblock munmap mprotect \
- sysarch __sysctl issetugid __getcwd utrace \
+ sysarch __sysctl issetugid __getcwd utrace getpid \
thr_self thr_kill pread mmap lseek _exit _fstat _fstatat _fstatfs \
getdirentries _getdirentries _close _fcntl _open _openat _read \
_sigprocmask _write readlink __realpathat _setjmp setjmp setjmperr
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 5c747582af33..2e96e86ba690 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -384,11 +384,12 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
const char *argv0, *binpath;
caddr_t imgentry;
char buf[MAXPATHLEN];
- int argc, fd, i, phnum, rtld_argc;
+ int argc, fd, i, mib[4], old_osrel, osrel, phnum, rtld_argc;
+ size_t sz;
#ifdef __powerpc__
int old_auxv_format = 1;
#endif
- bool dir_enable, explicit_fd, search_in_path;
+ bool dir_enable, direct_exec, explicit_fd, search_in_path;
/*
* On entry, the dynamic linker itself has not been relocated yet.
@@ -451,6 +452,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
ld_fast_sigblock = true;
trust = !issetugid();
+ direct_exec = false;
md_abi_variant_hook(aux_info);
@@ -466,6 +468,21 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
argv0);
rtld_die();
}
+ direct_exec = true;
+
+ /*
+ * Set osrel for us, it is later reset to the binary'
+ * value before first instruction of code from the binary
+ * is executed.
+ */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_OSREL;
+ mib[3] = getpid();
+ osrel = __FreeBSD_version;
+ sz = sizeof(old_osrel);
+ (void)sysctl(mib, 4, &old_osrel, &sz, &osrel, sizeof(osrel));
+
dbg("opening main program in direct exec mode");
if (argc >= 2) {
rtld_argc = parse_args(argv, argc, &search_in_path, &fd, &argv0);
@@ -804,6 +821,18 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
*/
pre_init();
+ if (direct_exec) {
+ /* Set osrel for direct-execed binary */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_OSREL;
+ mib[3] = getpid();
+ osrel = obj_main->osrel;
+ sz = sizeof(old_osrel);
+ dbg("setting osrel to %d", osrel);
+ (void)sysctl(mib, 4, &old_osrel, &sz, &osrel, sizeof(osrel));
+ }
+
wlock_acquire(rtld_bind_lock, &lockstate);
dbg("resolving ifuncs");