summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorkstailey <kstailey@cvs.openbsd.org>1999-09-19 16:16:50 +0000
committerkstailey <kstailey@cvs.openbsd.org>1999-09-19 16:16:50 +0000
commitcba8dae6e27ff4b3f26f3cf822bc743016e0552f (patch)
treef711640f4dfa1b153c25cbbfa3c95ee0ae81ad0e /sys
parent45752c593238cb159394b4c05caab576dcda8dc5 (diff)
improved OS brand PT_NOTE detection
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/netbsd/netbsd_exec.c9
-rw-r--r--sys/kern/exec_elf64.c90
-rw-r--r--sys/sys/exec_elf.h19
3 files changed, 94 insertions, 24 deletions
diff --git a/sys/compat/netbsd/netbsd_exec.c b/sys/compat/netbsd/netbsd_exec.c
index eddf3d4f018..899d3eb57c7 100644
--- a/sys/compat/netbsd/netbsd_exec.c
+++ b/sys/compat/netbsd/netbsd_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netbsd_exec.c,v 1.3 1999/09/19 13:59:22 kstailey Exp $ */
+/* $OpenBSD: netbsd_exec.c,v 1.4 1999/09/19 16:16:49 kstailey Exp $ */
/* $NetBSD: svr4_exec.c,v 1.16 1995/10/14 20:24:20 christos Exp $ */
/*
@@ -98,14 +98,13 @@ netbsd_elf64_probe(p, epp, itp, pos, os)
u_int8_t *os;
{
Elf64_Ehdr *eh = epp->ep_hdr;
- char *bp, *brand;
+ char *bp;
int error;
size_t len;
-
- brand = elf64_check_brand(eh);
- if (brand == NULL || strcmp(brand, "NetBSD"))
+ if (elf64_os_pt_note(p, epp, eh, "NetBSD\0", 7, 4))
return (EINVAL);
+
if (itp[0]) {
if ((error = emul_find(p, NULL, netbsd_emul_path, itp, &bp, 0)))
return (error);
diff --git a/sys/kern/exec_elf64.c b/sys/kern/exec_elf64.c
index 5dfc2093847..9029c111512 100644
--- a/sys/kern/exec_elf64.c
+++ b/sys/kern/exec_elf64.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_elf64.c,v 1.3 1999/09/19 13:59:22 kstailey Exp $ */
+/* $OpenBSD: exec_elf64.c,v 1.4 1999/09/19 16:16:49 kstailey Exp $ */
/*
* Copyright (c) 1996 Per Fogelstrom
@@ -521,16 +521,6 @@ exec_elf64_makecmds(p, epp)
pp->p_filesz)) != 0)
goto bad;
}
- if (pp->p_type == PT_NOTE) {
- int max_brand = (EI_NIDENT - 1) - EI_BRAND;
-
- if ((error = elf64_read_from(p, epp->ep_vp,
- pp->p_offset + 12, (caddr_t)&eh->e_ident[EI_BRAND],
- pp->p_filesz - 12 <= max_brand ?
- pp->p_filesz - 12 : max_brand)) != 0)
- goto bad;
- eh->e_ident[EI_NIDENT - 1] = '\0';
- }
}
/*
@@ -699,6 +689,7 @@ exec_elf64_fixup(p, epp)
struct elf_args *ap;
AuxInfo ai[ELF_AUX_ENTRIES], *a;
u_long pos = epp->ep_interp_pos;
+ size_t len;
if(epp->ep_interp == 0) {
return (0);
@@ -725,12 +716,13 @@ exec_elf64_fixup(p, epp)
}
kill_vmcmds(&epp->ep_vmcmds);
+ a = ai;
+
/*
* Push extra arguments on the stack needed by dynamically
* linked binaries
*/
- if(error == 0) {
- a = ai;
+ if (error == 0) {
a->au_id = AUX_phdr;
a->au_v = ap->arg_phaddr;
@@ -759,13 +751,14 @@ exec_elf64_fixup(p, epp)
a->au_id = AUX_entry;
a->au_v = ap->arg_entry;
a++;
+ }
- a->au_id = AUX_null;
- a->au_v = 0;
- a++;
+ a->au_id = AUX_null;
+ a->au_v = 0;
+ a++;
- error = copyout(ai, epp->ep_emul_argp, sizeof ai);
- }
+ len = (a - ai) * sizeof(AuxInfo);
+ error = copyout(ai, epp->ep_emul_argp, len);
free((char *)ap, M_TEMP);
free((char *)interp, M_TEMP);
return (error);
@@ -780,4 +773,65 @@ elf64_check_brand(eh)
return (&eh->e_ident[EI_BRAND]);
}
+int
+elf64_os_pt_note(p, epp, eh, os_name, name_size, desc_size)
+ struct proc *p;
+ struct exec_package *epp;
+ Elf64_Ehdr *eh;
+ char *os_name;
+ size_t name_size, desc_size;
+{
+ Elf64_Phdr *hph, *ph;
+ Elf64_Note *np = NULL;
+ size_t phsize;
+ int error;
+
+ phsize = eh->e_phnum * sizeof(Elf64_Phdr);
+ hph = (Elf64_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
+ if ((error = elf64_read_from(p, epp->ep_vp, eh->e_phoff,
+ (caddr_t)hph, phsize)) != 0)
+ goto out1;
+
+ for (ph = hph; ph < &hph[eh->e_phnum]; ph++) {
+ if (ph->p_type != PT_NOTE ||
+ ph->p_filesz < sizeof(Elf64_Note) + name_size)
+ continue;
+
+ np = (Elf64_Note *)malloc(ph->p_filesz, M_TEMP, M_WAITOK);
+ if ((error = elf64_read_from(p, epp->ep_vp, ph->p_offset,
+ (caddr_t)np, ph->p_filesz)) != 0)
+ goto out2;
+
+#if 0
+ if (np->type != ELF_NOTE_TYPE_OSVERSION) {
+ free(np, M_TEMP);
+ np = NULL;
+ continue;
+ }
+#endif
+
+ /* Check the name and description sizes. */
+ if (np->namesz != name_size ||
+ np->descsz != desc_size)
+ goto out3;
+
+ if (bcmp((np + 1), os_name, name_size))
+ goto out3;
+
+ /* XXX: We could check for the specific emulation here */
+ /* All checks succeeded. */
+ error = 0;
+ goto out2;
+ }
+
+out3:
+ error = ENOEXEC;
+out2:
+ if (np)
+ free(np, M_TEMP);
+out1:
+ free(hph, M_TEMP);
+ return error;
+}
+
#endif /* _KERN_DO_ELF64 */
diff --git a/sys/sys/exec_elf.h b/sys/sys/exec_elf.h
index a4ec19618c1..68dca58f8fc 100644
--- a/sys/sys/exec_elf.h
+++ b/sys/sys/exec_elf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_elf.h,v 1.19 1999/09/18 15:43:33 kstailey Exp $ */
+/* $OpenBSD: exec_elf.h,v 1.20 1999/09/19 16:16:49 kstailey Exp $ */
/*
* Copyright (c) 1995, 1996 Erik Theisen. All rights reserved.
*
@@ -430,6 +430,21 @@ typedef struct {
unsigned int elf_hash(const unsigned char *name);
/*
+ * Note Definitions
+ */
+typedef struct {
+ Elf32_Word namesz;
+ Elf32_Word descsz;
+ Elf32_Word type;
+} Elf32_Note;
+
+typedef struct {
+ Elf64_Half namesz;
+ Elf64_Half descsz;
+ Elf64_Half type;
+} Elf64_Note;
+
+/*
* XXX - these _KERNEL items aren't part of the ABI!
*/
#if defined(_KERNEL) || defined(_DYN_LOADER)
@@ -485,6 +500,8 @@ void *elf64_copyargs __P((struct exec_package *, struct ps_strings *,
void *, void *));
int exec_elf64_fixup __P((struct proc *, struct exec_package *));
char *elf64_check_brand __P((Elf64_Ehdr *));
+int elf64_os_pt_note __P((struct proc *, struct exec_package *, Elf64_Ehdr *,
+ char *, size_t, size_t));
#endif
#ifdef _KERN_DO_ELF
int exec_elf_makecmds __P((struct proc *, struct exec_package *));