add generic linux compat ELF copyargs function

this gives:
* linux sysconf(_SC_CLK_TCK) gives correct value for linux binaries (hz)
  even if hz != 100
* glibc gets proper information on real/effective uid and enables
  secure mode for suid binaries

g/c LINUX_COPYARGS_FUNCTION, replaced by linux ELF copyargs function
g/c alpha-specific linux ELF copyargs function and linux ELF defines
This commit is contained in:
jdolecek 2002-11-13 15:16:27 +00:00
parent 9def367548
commit cee43b67cc
12 changed files with 133 additions and 215 deletions

View File

@ -1,8 +1,7 @@
# $NetBSD: files.linux_alpha,v 1.6 2002/05/13 05:41:26 matt Exp $ # $NetBSD: files.linux_alpha,v 1.7 2002/11/13 15:16:29 jdolecek Exp $
# #
# Config file description for alpha-dependent Linux compat code. # Config file description for alpha-dependent Linux compat code.
file compat/linux/arch/alpha/linux_exec_alpha.c compat_linux
file compat/linux/arch/alpha/linux_machdep.c compat_linux file compat/linux/arch/alpha/linux_machdep.c compat_linux
file compat/linux/arch/alpha/linux_pipe.c compat_linux file compat/linux/arch/alpha/linux_pipe.c compat_linux
file compat/linux/arch/alpha/linux_syscalls.c compat_linux file compat/linux/arch/alpha/linux_syscalls.c compat_linux

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec.h,v 1.6 2002/08/26 21:06:00 christos Exp $ */ /* $NetBSD: linux_exec.h,v 1.7 2002/11/13 15:16:29 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -51,55 +51,9 @@
*/ */
#define LINUX_ATEXIT_SIGNATURE 1 #define LINUX_ATEXIT_SIGNATURE 1
#define LINUX_COPYARGS_FUNCTION ELFNAME2(linux,copyargs)
/* /*
* Alpha specific ELF defines. * Alpha specific ELF defines.
*
* If this is common to more than one linux port move it
* to common/linux_exec.h.
*/ */
#define LINUX_AT_NOTELF 10 #define LINUX_ELF_AUX_ARGSIZ howmany(sizeof(Aux64Info) * LINUX_ELF_AUX_ENTRIES, sizeof(char *))
#define LINUX_AT_UID 11
#define LINUX_AT_EUID 12
#define LINUX_AT_GID 13
#define LINUX_AT_EGID 14
#define LINUX_AT_PLATFORM 15
#define LINUX_AT_HWCAP 16
#define LINUX_ELF_AUX_ENTRIES 12
#define LINUX_ELF_AUX_ARGSIZ howmany(sizeof(LinuxAuxInfo) * LINUX_ELF_AUX_ENTRIES, sizeof(char *))
typedef struct {
Elf32_Sword a_type;
Elf32_Word a_v;
} LinuxAux32Info;
typedef struct {
Elf64_Word a_type;
Elf64_Word a_v;
} LinuxAux64Info;
#if defined(ELFSIZE) && (ELFSIZE == 32)
#define LinuxAuxInfo LinuxAux32Info
#else
#define LinuxAuxInfo LinuxAux64Info
#endif
#ifdef _KERNEL
__BEGIN_DECLS
#ifdef EXEC_ELF32
int linux_elf32_copyargs __P((struct proc *p, struct exec_package *,
struct ps_strings *, char **, void *));
#endif
#ifdef EXEC_ELF64
int linux_elf64_copyargs __P((struct proc *p, struct exec_package *,
struct ps_strings *, char **, void *));
#endif
__END_DECLS
#endif /* !_KERNEL */
#endif /* !_ALPHA_LINUX_EXEC_H */ #endif /* !_ALPHA_LINUX_EXEC_H */

View File

@ -1,115 +0,0 @@
/* $NetBSD: linux_exec_alpha.c,v 1.5 2002/08/26 21:06:00 christos Exp $ */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_exec_alpha.c,v 1.5 2002/08/26 21:06:00 christos Exp $");
#define ELFSIZE 64
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/exec_elf.h>
#include <compat/linux/common/linux_exec.h>
/*
* Alpha specific linux copyargs function.
*
* XXX Figure out if this is common to more than one linux
* XXX port. If so, move it to common/linux_exec_elf32.c
* XXX included based on some define.
*/
int
ELFNAME2(linux,copyargs)(struct proc *p, struct exec_package *pack,
struct ps_strings *arginfo, char **stackp, void *argp)
{
size_t len;
LinuxAuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a;
struct elf_args *ap;
int error;
if ((error = copyargs(p, pack, arginfo, stackp, argp)) != 0)
return error;
memset(ai, 0, sizeof(LinuxAuxInfo) * LINUX_ELF_AUX_ENTRIES);
a = ai;
/*
* Push extra arguments on the stack needed by dynamically
* linked binaries.
*/
if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
a->a_type = AT_PHDR;
a->a_v = ap->arg_phaddr;
a++;
a->a_type = AT_PHENT;
a->a_v = ap->arg_phentsize;
a++;
a->a_type = AT_PHNUM;
a->a_v = ap->arg_phnum;
a++;
a->a_type = AT_PAGESZ;
a->a_v = NBPG;
a++;
a->a_type = AT_BASE;
a->a_v = ap->arg_interp;
a++;
a->a_type = AT_FLAGS;
a->a_v = 0;
a++;
a->a_type = AT_ENTRY;
a->a_v = ap->arg_entry;
a++;
a->a_type = AT_BASE;
a->a_v = ap->arg_interp;
a++;
#if 0
/*
* The exec_package doesn't have a proc pointer and it's not
* exactly trivial to add one since the credentials are changing.
*/
a->a_type = LINUX_AT_UID;
a->a_v = pack->p->p_cred->p_ruid;
a++;
a->a_type = LINUX_AT_EUID;
a->a_v = pack->p->p_ucred->cr_uid;
a++;
a->a_type = LINUX_AT_GID;
a->a_v = pack->p->p_cred->p_rgid;
a++;
a->a_type = LINUX_AT_EGID;
a->a_v = pack->p->p_ucred->cr_gid;
a++;
#endif
free((char *)ap, M_TEMP);
pack->ep_emul_arg = NULL;
}
a->a_type = AT_NULL;
a->a_v = 0;
a++;
len = (a - ai) * sizeof(LinuxAuxInfo);
if ((error = copyout(ai, *stackp, len)) != 0)
return error;
*stackp += len;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec.h,v 1.2 2002/01/17 17:19:03 bjh21 Exp $ */ /* $NetBSD: linux_exec.h,v 1.3 2002/11/13 15:16:30 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -43,12 +43,7 @@
#define LINUX_MID_MACHINE LINUX_M_ARM #define LINUX_MID_MACHINE LINUX_M_ARM
#define LINUX_ELF_AUX_ARGSIZ \ #define LINUX_ELF_AUX_ARGSIZ \
(howmany(ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr))) (howmany(LINUX_ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr)))
#ifdef ELF32NAME
#define LINUX_COPYARGS_FUNCTION ELF32NAME(copyargs)
#else
#define LINUX_COPYARGS_FUNCTION ELFNAME(copyargs)
#endif
#define LINUX_SYSCALL_FUNCTION linux_syscall #define LINUX_SYSCALL_FUNCTION linux_syscall

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec.h,v 1.4 2000/11/21 00:37:53 jdolecek Exp $ */ /* $NetBSD: linux_exec.h,v 1.5 2002/11/13 15:16:30 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -44,12 +44,7 @@
#define LINUX_GCC_SIGNATURE 1 #define LINUX_GCC_SIGNATURE 1
#define LINUX_ELF_AUX_ARGSIZ \ #define LINUX_ELF_AUX_ARGSIZ \
(howmany(ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr))) (howmany(LINUX_ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr)))
#ifdef ELF32NAME
#define LINUX_COPYARGS_FUNCTION ELF32NAME(copyargs)
#else
#define LINUX_COPYARGS_FUNCTION ELFNAME(copyargs)
#endif
#endif /* !_I386_LINUX_EXEC_H */ #endif /* !_I386_LINUX_EXEC_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec.h,v 1.5 2002/07/13 08:28:41 scw Exp $ */ /* $NetBSD: linux_exec.h,v 1.6 2002/11/13 15:16:31 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -48,11 +48,6 @@
#define LINUX_GCC_SIGNATURE 1 #define LINUX_GCC_SIGNATURE 1
#define LINUX_ELF_AUX_ARGSIZ \ #define LINUX_ELF_AUX_ARGSIZ \
(howmany(ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr))) (howmany(LINUX_ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr)))
#ifdef ELF32NAME
#define LINUX_COPYARGS_FUNCTION ELF32NAME(copyargs)
#else
#define LINUX_COPYARGS_FUNCTION ELFNAME(copyargs)
#endif
#endif /* !_M68K_LINUX_EXEC_H */ #endif /* !_M68K_LINUX_EXEC_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec.h,v 1.5 2002/08/26 21:06:00 christos Exp $ */ /* $NetBSD: linux_exec.h,v 1.6 2002/11/13 15:16:31 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@ -61,17 +61,10 @@
#define LINUX_ATEXIT_SIGNATURE 1 #define LINUX_ATEXIT_SIGNATURE 1
#define LINUX_GCC_SIGNATURE 1 #define LINUX_GCC_SIGNATURE 1
/* #define LINUX_COPYARGS_FUNCTION linux_elf32_copyargs */
#if defined(ELFSIZE) && (ELFSIZE == 64)
#define LINUX_COPYARGS_FUNCTION ELF64NAME(copyargs)
#else
#define LINUX_COPYARGS_FUNCTION ELF32NAME(copyargs)
#endif
#define LINUX_ELF_AUX_ENTRIES 14 #define LINUX_ELF_AUX_ENTRIES 14
#define LINUX_ELF_AUX_ARGSIZ \ #define LINUX_ELF_AUX_ARGSIZ \
((howmany(ELF_AUX_ENTRIES * sizeof(LinuxAuxInfo), sizeof(Elf32_Addr)))) ((howmany(LINUX_ELF_AUX_ENTRIES * sizeof(LinuxAuxInfo), sizeof(Elf32_Addr))))
typedef struct { typedef struct {
Elf32_Sword a_type; Elf32_Sword a_type;

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec.h,v 1.12 2002/11/13 14:35:15 jdolecek Exp $ */ /* $NetBSD: linux_exec.h,v 1.13 2002/11/13 15:16:31 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@ -100,16 +100,10 @@
((howmany(LINUX_ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr))) \ ((howmany(LINUX_ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr))) \
+ 16 + LINUX_SP_WRAP) + 16 + LINUX_SP_WRAP)
/* XXX should use ELFNAME2 */ /* we have special powerpc ELF copyargs */
#define LINUX_COPYARGS_FUNCTION linux_elf32_copyargs #define LINUX_MACHDEP_ELF_COPYARGS
/* NetBSD/powerpc doesn't use e_syscall, so use the default. */ /* NetBSD/powerpc doesn't use e_syscall, so use the default. */
#define LINUX_SYSCALL_FUNCTION syscall #define LINUX_SYSCALL_FUNCTION syscall
#ifdef _KERNEL
__BEGIN_DECLS
int linux_elf32_copyargs __P((struct proc *, struct exec_package *,
struct ps_strings *, char **, void *));
__END_DECLS
#endif /* _KERNEL */
#endif /* !_POWERPC_LINUX_EXEC_H */ #endif /* !_POWERPC_LINUX_EXEC_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec.h,v 1.22 2002/08/26 21:06:01 christos Exp $ */ /* $NetBSD: linux_exec.h,v 1.23 2002/11/13 15:16:28 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@ -78,6 +78,10 @@
#define LINUX_N_BSSADDR(x,m) (LINUX_N_DATADDR(x,m) + (x).a_data) #define LINUX_N_BSSADDR(x,m) (LINUX_N_DATADDR(x,m) + (x).a_data)
#ifndef LINUX_MACHDEP_ELF_COPYARGS
#define LINUX_ELF_AUX_ENTRIES 13 /* we push 13 parameters */
#endif
/* /*
* From Linux's include/linux/elf.h * From Linux's include/linux/elf.h
*/ */
@ -127,10 +131,14 @@ void linux_trapsignal __P((struct proc *, int, u_long));
#ifdef EXEC_ELF32 #ifdef EXEC_ELF32
int linux_elf32_probe __P((struct proc *, struct exec_package *, void *, int linux_elf32_probe __P((struct proc *, struct exec_package *, void *,
char *, vaddr_t *)); char *, vaddr_t *));
int linux_elf32_copyargs __P((struct proc *, struct exec_package *,
struct ps_strings *, char **, void *));
#endif #endif
#ifdef EXEC_ELF64 #ifdef EXEC_ELF64
int linux_elf64_probe __P((struct proc *, struct exec_package *, void *, int linux_elf64_probe __P((struct proc *, struct exec_package *, void *,
char *, vaddr_t *)); char *, vaddr_t *));
int linux_elf64_copyargs __P((struct proc *, struct exec_package *,
struct ps_strings *, char **, void *));
#endif #endif
__END_DECLS __END_DECLS
#endif /* !_KERNEL */ #endif /* !_KERNEL */

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec_elf32.c,v 1.58 2002/10/22 23:31:24 christos Exp $ */ /* $NetBSD: linux_exec_elf32.c,v 1.59 2002/11/13 15:16:29 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc. * Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.58 2002/10/22 23:31:24 christos Exp $"); __KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.59 2002/11/13 15:16:29 jdolecek Exp $");
#ifndef ELFSIZE #ifndef ELFSIZE
/* XXX should die */ /* XXX should die */
@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.58 2002/10/22 23:31:24 christ
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/exec.h> #include <sys/exec.h>
#include <sys/exec_elf.h> #include <sys/exec_elf.h>
#include <sys/stat.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/syscallargs.h> #include <sys/syscallargs.h>
@ -341,3 +342,102 @@ ELFNAME2(linux,probe)(p, epp, eh, itp, pos)
return 0; return 0;
} }
#ifndef LINUX_MACHDEP_ELF_COPYARGS
/*
* Copy arguments onto the stack in the normal way, but add some
* extra information in case of dynamic binding.
*/
int
ELFNAME2(linux,copyargs)(struct proc *p, struct exec_package *pack,
struct ps_strings *arginfo, char **stackp, void *argp)
{
size_t len;
AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a;
struct elf_args *ap;
int error;
struct vattr *vap;
if ((error = copyargs(p, pack, arginfo, stackp, argp)) != 0)
return error;
a = ai;
/*
* Push extra arguments used by glibc on the stack.
*/
a->a_type = AT_PAGESZ;
a->a_v = PAGE_SIZE;
a++;
if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
a->a_type = AT_PHDR;
a->a_v = ap->arg_phaddr;
a++;
a->a_type = AT_PHENT;
a->a_v = ap->arg_phentsize;
a++;
a->a_type = AT_PHNUM;
a->a_v = ap->arg_phnum;
a++;
a->a_type = AT_BASE;
a->a_v = ap->arg_interp;
a++;
a->a_type = AT_FLAGS;
a->a_v = 0;
a++;
a->a_type = AT_ENTRY;
a->a_v = ap->arg_entry;
a++;
free(pack->ep_emul_arg, M_TEMP);
pack->ep_emul_arg = NULL;
}
/* Linux-specific items */
a->a_type = LINUX_AT_CLKTCK;
a->a_v = hz;
a++;
vap = pack->ep_vap;
a->a_type = LINUX_AT_UID;
a->a_v = p->p_cred->p_ruid;
a++;
a->a_type = LINUX_AT_EUID;
if (vap->va_mode & S_ISUID)
a->a_v = vap->va_uid;
else
a->a_v = p->p_ucred->cr_uid;
a++;
a->a_type = LINUX_AT_GID;
a->a_v = p->p_cred->p_rgid;
a++;
a->a_type = LINUX_AT_EGID;
if (vap->va_mode & S_ISGID)
a->a_v = vap->va_gid;
else
a->a_v = p->p_ucred->cr_gid;
a++;
a->a_type = AT_NULL;
a->a_v = 0;
a++;
len = (a - ai) * sizeof(AuxInfo);
if ((error = copyout(ai, *stackp, len)) != 0)
return error;
*stackp += len;
return 0;
}
#endif /* !LINUX_MACHDEP_ELF_COPYARGS */

View File

@ -1,4 +1,4 @@
/* $NetBSD: exec_conf.c,v 1.76 2002/11/12 23:40:21 manu Exp $ */ /* $NetBSD: exec_conf.c,v 1.77 2002/11/13 15:16:27 jdolecek Exp $ */
/* /*
* Copyright (c) 1993, 1994 Christopher G. Demetriou * Copyright (c) 1993, 1994 Christopher G. Demetriou
@ -31,7 +31,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exec_conf.c,v 1.76 2002/11/12 23:40:21 manu Exp $"); __KERNEL_RCSID(0, "$NetBSD: exec_conf.c,v 1.77 2002/11/13 15:16:27 jdolecek Exp $");
#include "opt_execfmt.h" #include "opt_execfmt.h"
#include "opt_compat_freebsd.h" #include "opt_compat_freebsd.h"
@ -358,7 +358,7 @@ const struct execsw execsw_builtin[] = {
&emul_linux, &emul_linux,
EXECSW_PRIO_ANY, EXECSW_PRIO_ANY,
LINUX_ELF_AUX_ARGSIZ, LINUX_ELF_AUX_ARGSIZ,
LINUX_COPYARGS_FUNCTION, linux_elf32_copyargs,
NULL, NULL,
coredump_elf32 }, coredump_elf32 },
#endif #endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: lkminit_exec.c,v 1.6 2002/01/04 06:51:01 thorpej Exp $ */ /* $NetBSD: lkminit_exec.c,v 1.7 2002/11/13 15:16:28 jdolecek Exp $ */
/*- /*-
* Copyright (c) 1996 The NetBSD Foundation, Inc. * Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lkminit_exec.c,v 1.6 2002/01/04 06:51:01 thorpej Exp $"); __KERNEL_RCSID(0, "$NetBSD: lkminit_exec.c,v 1.7 2002/11/13 15:16:28 jdolecek Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -63,9 +63,9 @@ static struct execsw exec_linux_elf =
NULL, /* will be set by exec_add() */ NULL, /* will be set by exec_add() */
EXECSW_PRIO_ANY, EXECSW_PRIO_ANY,
LINUX_ELF_AUX_ARGSIZ, LINUX_ELF_AUX_ARGSIZ,
LINUX_COPYARGS_FUNCTION, ELFNAME2(linux,copyargs),
NULL, NULL,
coredump_elf32 }; coredump_elf32 }; /* XXX ELF64? */
/* /*
* declare the exec * declare the exec