Browse Source

Merge branch 'freebsd/12-stable/master' into hardened/12-stable/master

* freebsd/12-stable/master:
  MFC r362342: Fix execution of linux binary from multithreaded non-Linux process.
  MFC r362347: rtld: Apply relro to itself.
  MFC r362346: rtld: Parse own phdr and notes.
remotes/github/hardened/12-stable/master
HardenedBSD Sync Service 3 months ago
parent
commit
38baec26fb
2 changed files with 57 additions and 14 deletions
  1. +31
    -0
      libexec/rtld-elf/rtld.c
  2. +26
    -14
      sys/compat/linux/linux_emul.c

+ 31
- 0
libexec/rtld-elf/rtld.c View File

@@ -2162,6 +2162,34 @@ process_z(Obj_Entry *root)
}
}
}

static void
parse_rtld_phdr(Obj_Entry *obj)
{
const Elf_Phdr *ph;
Elf_Addr note_start, note_end;

obj->stack_flags = PF_X | PF_R | PF_W;
for (ph = obj->phdr; (const char *)ph < (const char *)obj->phdr +
obj->phsize; ph++) {
switch (ph->p_type) {
case PT_GNU_STACK:
obj->stack_flags = ph->p_flags;
break;
case PT_GNU_RELRO:
obj->relro_page = obj->relocbase +
trunc_page(ph->p_vaddr);
obj->relro_size = round_page(ph->p_memsz);
break;
case PT_NOTE:
note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr;
note_end = note_start + ph->p_filesz;
digest_notes(obj, note_start, note_end);
break;
}
}
}

/*
* Initialize the dynamic linker. The argument is the address at which
* the dynamic linker has been mapped into memory. The primary task of
@@ -2231,6 +2259,9 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo **aux_info)
/* Replace the path with a dynamically allocated copy. */
obj_rtld.path = xstrdup(ld_path_rtld);

parse_rtld_phdr(&obj_rtld);
obj_enforce_relro(&obj_rtld);

r_debug.r_brk = r_debug_state;
r_debug.r_state = RT_CONSISTENT;
}


+ 26
- 14
sys/compat/linux/linux_emul.c View File

@@ -261,22 +261,13 @@ linux_common_execve(struct thread *td, struct image_args *eargs)
void
linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
{
struct thread *td = curthread;
struct thread *td;
struct thread *othertd;
#if defined(__amd64__)
struct linux_pemuldata *pem;
#endif

/*
* In a case of execing from Linux binary properly detach
* other threads from the user space.
*/
if (__predict_false(SV_PROC_ABI(p) == SV_ABI_LINUX)) {
FOREACH_THREAD_IN_PROC(p, othertd) {
if (td != othertd)
(p->p_sysent->sv_thread_detach)(othertd);
}
}
td = curthread;

/*
* In a case of execing to Linux binary we create Linux
@@ -284,11 +275,32 @@ linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
*/
if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) ==
SV_ABI_LINUX)) {

if (SV_PROC_ABI(p) == SV_ABI_LINUX)
if (SV_PROC_ABI(p) == SV_ABI_LINUX) {
/*
* Process already was under Linuxolator
* before exec. Update emuldata to reflect
* single-threaded cleaned state after exec.
*/
linux_proc_init(td, NULL, 0);
else
} else {
/*
* We are switching the process to Linux emulator.
*/
linux_proc_init(td, td, 0);

/*
* Create a transient td_emuldata for all suspended
* threads, so that p->p_sysent->sv_thread_detach() ==
* linux_thread_detach() can find expected but unused
* emuldata.
*/
FOREACH_THREAD_IN_PROC(td->td_proc, othertd) {
if (othertd != td) {
linux_proc_init(td, othertd,
LINUX_CLONE_THREAD);
}
}
}
#if defined(__amd64__)
/*
* An IA32 executable which has executable stack will have the


Loading…
Cancel
Save