Fix the powerpc copyout fixup from r356113

Summary:
r356113 used an older patch, which predated the
freebsd_copyout_auxargs() addition.  Fix this by using a private
powerpc_copyout_auxargs() instead, and keep it private to powerpc, not in MI
files.

Reviewed by:	kib, bdragon
Differential Revision:	https://reviews.freebsd.org/D22935
This commit is contained in:
Justin Hibbits 2019-12-27 17:38:25 +00:00
parent 742654c958
commit 741dfd86b3
5 changed files with 128 additions and 104 deletions

View File

@ -1323,102 +1323,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
#define suword __CONCAT(suword, __ELF_WORD_SIZE)
#ifdef __powerpc__
#define OLD_AT_NULL AT_NULL
#define OLD_AT_IGNORE AT_IGNORE
#define OLD_AT_EXECFD AT_EXECFD
#define OLD_AT_PHDR AT_PHDR
#define OLD_AT_PHENT AT_PHENT
#define OLD_AT_PHNUM AT_PHNUM
#define OLD_AT_PAGESZ AT_PAGESZ
#define OLD_AT_BASE AT_BASE
#define OLD_AT_FLAGS AT_FLAGS
#define OLD_AT_ENTRY AT_ENTRY
#define OLD_AT_NOTELF AT_NOTELF
#define OLD_AT_UID AT_UID
#define OLD_AT_EUID AT_EUID
#define OLD_AT_EXECPATH 13
#define OLD_AT_CANARY 14
#define OLD_AT_CANARYLEN 15
#define OLD_AT_OSRELDATE 16
#define OLD_AT_NCPUS 17
#define OLD_AT_PAGESIZES 18
#define OLD_AT_PAGESIZESLEN 19
#define OLD_AT_STACKPROT 21
#define OLD_AT_TIMEKEEP AT_TIMEKEEP
#define OLD_AT_EHDRFLAGS AT_EHDRFLAGS
#define OLD_AT_HWCAP AT_HWCAP
#define OLD_AT_HWCAP2 AT_HWCAP2
#define OLD_AT_COUNT 27 /* Count of defined aux entry types. */
static int
__elfN(freebsd_fixup_old_auxargs)(uintptr_t *stack_base,
struct image_params *imgp)
{
Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs;
Elf_Auxinfo *argarray, *pos;
Elf_Addr *base, *auxbase;
int error;
base = (Elf_Addr *)*stack_base;
auxbase = base + imgp->args->argc + 1 + imgp->args->envc + 1;
argarray = pos = malloc(OLD_AT_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
if (args->execfd != -1)
AUXARGS_ENTRY(pos, OLD_AT_EXECFD, args->execfd);
AUXARGS_ENTRY(pos, OLD_AT_PHDR, args->phdr);
AUXARGS_ENTRY(pos, OLD_AT_PHENT, args->phent);
AUXARGS_ENTRY(pos, OLD_AT_PHNUM, args->phnum);
AUXARGS_ENTRY(pos, OLD_AT_PAGESZ, args->pagesz);
AUXARGS_ENTRY(pos, OLD_AT_FLAGS, args->flags);
AUXARGS_ENTRY(pos, OLD_AT_ENTRY, args->entry);
AUXARGS_ENTRY(pos, OLD_AT_BASE, args->base);
AUXARGS_ENTRY(pos, OLD_AT_EHDRFLAGS, args->hdr_eflags);
if (imgp->execpathp != 0)
AUXARGS_ENTRY(pos, OLD_AT_EXECPATH, imgp->execpathp);
AUXARGS_ENTRY(pos, OLD_AT_OSRELDATE,
imgp->proc->p_ucred->cr_prison->pr_osreldate);
if (imgp->canary != 0) {
AUXARGS_ENTRY(pos, OLD_AT_CANARY, imgp->canary);
AUXARGS_ENTRY(pos, OLD_AT_CANARYLEN, imgp->canarylen);
}
AUXARGS_ENTRY(pos, OLD_AT_NCPUS, mp_ncpus);
if (imgp->pagesizes != 0) {
AUXARGS_ENTRY(pos, OLD_AT_PAGESIZES, imgp->pagesizes);
AUXARGS_ENTRY(pos, OLD_AT_PAGESIZESLEN, imgp->pagesizeslen);
}
if (imgp->sysent->sv_timekeep_base != 0) {
AUXARGS_ENTRY(pos, OLD_AT_TIMEKEEP,
imgp->sysent->sv_timekeep_base);
}
AUXARGS_ENTRY(pos, OLD_AT_STACKPROT, imgp->sysent->sv_shared_page_obj
!= NULL && imgp->stack_prot != 0 ? imgp->stack_prot :
imgp->sysent->sv_stackprot);
if (imgp->sysent->sv_hwcap != NULL)
AUXARGS_ENTRY(pos, OLD_AT_HWCAP, *imgp->sysent->sv_hwcap);
if (imgp->sysent->sv_hwcap2 != NULL)
AUXARGS_ENTRY(pos, OLD_AT_HWCAP2, *imgp->sysent->sv_hwcap2);
AUXARGS_ENTRY(pos, OLD_AT_NULL, 0);
free(imgp->auxargs, M_TEMP);
imgp->auxargs = NULL;
KASSERT(pos - argarray <= OLD_AT_COUNT, ("Too many auxargs"));
error = copyout(argarray, auxbase, sizeof(*argarray) * OLD_AT_COUNT);
free(argarray, M_TEMP);
if (error != 0)
return (error);
base--;
if (suword(base, imgp->args->argc) == -1)
return (EFAULT);
*stack_base = (uintptr_t)base;
return (0);
}
#endif /* __powerpc__ */
int
__elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
{
@ -1479,11 +1383,6 @@ __elfN(freebsd_fixup)(uintptr_t *stack_base, struct image_params *imgp)
{
Elf_Addr *base;
#ifdef __powerpc__
if (imgp->proc->p_osrel < P_OSREL_POWERPC_NEW_AUX_ARGS)
return (__elfN(freebsd_fixup_old_auxargs)(stack_base, imgp));
#endif /* __powerpc__ */
base = (Elf_Addr *)*stack_base;
base--;
if (suword(base, imgp->args->argc) == -1)

View File

@ -114,4 +114,32 @@ __ElfType(Auxinfo);
#define ET_DYN_LOAD_ADDR 0x01010000
#define AT_OLD_NULL AT_NULL
#define AT_OLD_IGNORE AT_IGNORE
#define AT_OLD_EXECFD AT_EXECFD
#define AT_OLD_PHDR AT_PHDR
#define AT_OLD_PHENT AT_PHENT
#define AT_OLD_PHNUM AT_PHNUM
#define AT_OLD_PAGESZ AT_PAGESZ
#define AT_OLD_BASE AT_BASE
#define AT_OLD_FLAGS AT_FLAGS
#define AT_OLD_ENTRY AT_ENTRY
#define AT_OLD_NOTELF AT_NOTELF
#define AT_OLD_UID AT_UID
#define AT_OLD_EUID AT_EUID
#define AT_OLD_EXECPATH 13
#define AT_OLD_CANARY 14
#define AT_OLD_CANARYLEN 15
#define AT_OLD_OSRELDATE 16
#define AT_OLD_NCPUS 17
#define AT_OLD_PAGESIZES 18
#define AT_OLD_PAGESIZESLEN 19
#define AT_OLD_STACKPROT 21
#define AT_OLD_TIMEKEEP AT_TIMEKEEP
#define AT_OLD_EHDRFLAGS AT_EHDRFLAGS
#define AT_OLD_HWCAP AT_HWCAP
#define AT_OLD_HWCAP2 AT_HWCAP2
#define AT_OLD_COUNT 27 /* Count of defined aux entry types. */
#endif /* !_MACHINE_ELF_H_ */

View File

@ -41,6 +41,8 @@
#include <sys/fcntl.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
#include <sys/jail.h>
#include <sys/smp.h>
#include <sys/syscall.h>
#include <sys/sysctl.h>
#include <sys/signalvar.h>
@ -57,6 +59,8 @@
#include <machine/reg.h>
#include <machine/md_var.h>
#include <powerpc/powerpc/elf_common.c>
#ifdef __powerpc64__
#include <compat/freebsd32/freebsd32_proto.h>
#include <compat/freebsd32/freebsd32_util.h>
@ -89,7 +93,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_errtbl = NULL,
.sv_transtrap = NULL,
.sv_fixup = __elfN(freebsd_fixup),
.sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs),
.sv_copyout_auxargs = __elfN(powerpc_copyout_auxargs),
.sv_sendsig = sendsig,
.sv_sigcode = sigcode32,
.sv_szsigcode = &szsigcode32,

View File

@ -38,6 +38,8 @@
#include <sys/fcntl.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
#include <sys/jail.h>
#include <sys/smp.h>
#include <sys/syscall.h>
#include <sys/signalvar.h>
#include <sys/vnode.h>
@ -52,6 +54,8 @@
#include <machine/elf.h>
#include <machine/md_var.h>
#include <powerpc/powerpc/elf_common.c>
static void exec_setregs_funcdesc(struct thread *td, struct image_params *imgp,
uintptr_t stack);
@ -74,7 +78,7 @@ struct sysentvec elf64_freebsd_sysvec_v1 = {
.sv_usrstack = USRSTACK,
.sv_psstrings = PS_STRINGS,
.sv_stackprot = VM_PROT_ALL,
.sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs),
.sv_copyout_auxargs = __elfN(powerpc_copyout_auxargs),
.sv_copyout_strings = exec_copyout_strings,
.sv_setregs = exec_setregs_funcdesc,
.sv_fixlimit = NULL,
@ -112,7 +116,7 @@ struct sysentvec elf64_freebsd_sysvec_v2 = {
.sv_usrstack = USRSTACK,
.sv_psstrings = PS_STRINGS,
.sv_stackprot = VM_PROT_ALL,
.sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs),
.sv_copyout_auxargs = __elfN(powerpc_copyout_auxargs),
.sv_copyout_strings = exec_copyout_strings,
.sv_setregs = exec_setregs,
.sv_fixlimit = NULL,

View File

@ -0,0 +1,89 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2019 Justin Hibbits
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
static int
__elfN(powerpc_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
{
Elf_Auxargs *args;
Elf_Auxinfo *argarray, *pos;
int error;
if (imgp->proc->p_osrel >= P_OSREL_POWERPC_NEW_AUX_ARGS)
return (__elfN(freebsd_copyout_auxargs)(imgp, base));
args = (Elf_Auxargs *)imgp->auxargs;
argarray = pos = malloc(AT_OLD_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
if (args->execfd != -1)
AUXARGS_ENTRY(pos, AT_OLD_EXECFD, args->execfd);
AUXARGS_ENTRY(pos, AT_OLD_PHDR, args->phdr);
AUXARGS_ENTRY(pos, AT_OLD_PHENT, args->phent);
AUXARGS_ENTRY(pos, AT_OLD_PHNUM, args->phnum);
AUXARGS_ENTRY(pos, AT_OLD_PAGESZ, args->pagesz);
AUXARGS_ENTRY(pos, AT_OLD_FLAGS, args->flags);
AUXARGS_ENTRY(pos, AT_OLD_ENTRY, args->entry);
AUXARGS_ENTRY(pos, AT_OLD_BASE, args->base);
AUXARGS_ENTRY(pos, AT_OLD_EHDRFLAGS, args->hdr_eflags);
if (imgp->execpathp != 0)
AUXARGS_ENTRY(pos, AT_OLD_EXECPATH, imgp->execpathp);
AUXARGS_ENTRY(pos, AT_OLD_OSRELDATE,
imgp->proc->p_ucred->cr_prison->pr_osreldate);
if (imgp->canary != 0) {
AUXARGS_ENTRY(pos, AT_OLD_CANARY, imgp->canary);
AUXARGS_ENTRY(pos, AT_OLD_CANARYLEN, imgp->canarylen);
}
AUXARGS_ENTRY(pos, AT_OLD_NCPUS, mp_ncpus);
if (imgp->pagesizes != 0) {
AUXARGS_ENTRY(pos, AT_OLD_PAGESIZES, imgp->pagesizes);
AUXARGS_ENTRY(pos, AT_OLD_PAGESIZESLEN, imgp->pagesizeslen);
}
if (imgp->sysent->sv_timekeep_base != 0) {
AUXARGS_ENTRY(pos, AT_OLD_TIMEKEEP,
imgp->sysent->sv_timekeep_base);
}
AUXARGS_ENTRY(pos, AT_OLD_STACKPROT, imgp->sysent->sv_shared_page_obj
!= NULL && imgp->stack_prot != 0 ? imgp->stack_prot :
imgp->sysent->sv_stackprot);
if (imgp->sysent->sv_hwcap != NULL)
AUXARGS_ENTRY(pos, AT_OLD_HWCAP, *imgp->sysent->sv_hwcap);
if (imgp->sysent->sv_hwcap2 != NULL)
AUXARGS_ENTRY(pos, AT_OLD_HWCAP2, *imgp->sysent->sv_hwcap2);
AUXARGS_ENTRY(pos, AT_OLD_NULL, 0);
free(imgp->auxargs, M_TEMP);
imgp->auxargs = NULL;
KASSERT(pos - argarray <= AT_OLD_COUNT, ("Too many auxargs"));
error = copyout(argarray, (void *)base, sizeof(*argarray) * AT_OLD_COUNT);
free(argarray, M_TEMP);
return (error);
}