From 6d5ca5199c509904a202dc2c4f9fba24471d8151 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 25 Sep 2020 17:13:45 +0000 Subject: [PATCH] Fix compat32 on mips64 Summary: Two bugs: * Elf32_Auxinfo is broken, using pointers in the union, which are 64-bits not 32. * freebsd32_sysarch() doesn't update the 'user local' register when handling MIPS_SET_TLS, leading to a NULL pointer dereference in the 32-bit application. Reviewed by: #mips, brooks MFC after: 1 week Sponsored by: Juniper Networks, Inc Differential Revision: https://reviews.freebsd.org/D26556 --- sys/mips/include/elf.h | 2 -- sys/mips/mips/freebsd32_machdep.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/sys/mips/include/elf.h b/sys/mips/include/elf.h index d62b237fdac0..a0263bb3a975 100644 --- a/sys/mips/include/elf.h +++ b/sys/mips/include/elf.h @@ -105,8 +105,6 @@ typedef struct { /* Auxiliary vector entry on initial stack */ int a_type; /* Entry type. */ union { int a_val; /* Integer value. */ - void *a_ptr; /* Address. */ - void (*a_fcn)(void); /* Function pointer (not used). */ } a_un; } Elf32_Auxinfo; diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_machdep.c index 1488edb9fb77..13fe21df99af 100644 --- a/sys/mips/mips/freebsd32_machdep.c +++ b/sys/mips/mips/freebsd32_machdep.c @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -455,6 +456,17 @@ freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap) switch (uap->op) { case MIPS_SET_TLS: td->td_md.md_tls = (void *)(intptr_t)uap->parms; + + /* + * If there is an user local register implementation (ULRI) + * update it as well. Add the TLS and TCB offsets so the + * value in this register is adjusted like in the case of the + * rdhwr trap() instruction handler. + */ + if (cpuinfo.userlocal_reg == true) { + mips_wr_userlocal((unsigned long)(uap->parms + + td->td_md.md_tls_tcb_offset)); + } return (0); case MIPS_GET_TLS: tlsbase = (int32_t)(intptr_t)td->td_md.md_tls;