diff options
author | kstailey <kstailey@cvs.openbsd.org> | 1999-09-19 16:16:50 +0000 |
---|---|---|
committer | kstailey <kstailey@cvs.openbsd.org> | 1999-09-19 16:16:50 +0000 |
commit | cba8dae6e27ff4b3f26f3cf822bc743016e0552f (patch) | |
tree | f711640f4dfa1b153c25cbbfa3c95ee0ae81ad0e /sys | |
parent | 45752c593238cb159394b4c05caab576dcda8dc5 (diff) |
improved OS brand PT_NOTE detection
Diffstat (limited to 'sys')
-rw-r--r-- | sys/compat/netbsd/netbsd_exec.c | 9 | ||||
-rw-r--r-- | sys/kern/exec_elf64.c | 90 | ||||
-rw-r--r-- | sys/sys/exec_elf.h | 19 |
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 *)); |