summaryrefslogtreecommitdiff
path: root/sys/compat/linux/common/linux_exec_elf32.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linux/common/linux_exec_elf32.c')
-rw-r--r--sys/compat/linux/common/linux_exec_elf32.c105
1 files changed, 43 insertions, 62 deletions
diff --git a/sys/compat/linux/common/linux_exec_elf32.c b/sys/compat/linux/common/linux_exec_elf32.c
index 014d8174ec3..2755108501b 100644
--- a/sys/compat/linux/common/linux_exec_elf32.c
+++ b/sys/compat/linux/common/linux_exec_elf32.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_exec_elf32.c,v 1.90 2014/02/23 11:09:42 njoly Exp $ */
+/* $NetBSD: linux_exec_elf32.c,v 1.91 2014/04/15 17:29:00 maxv Exp $ */
/*-
* Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.90 2014/02/23 11:09:42 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.91 2014/04/15 17:29:00 maxv Exp $");
#ifndef ELFSIZE
/* XXX should die */
@@ -92,50 +92,43 @@ ELFNAME2(linux,atexit_signature)(
struct exec_package *epp,
Elf_Ehdr *eh)
{
+ Elf_Shdr *sh;
size_t shsize;
- int strndx;
+ u_int shstrndx;
size_t i;
static const char signature[] = "__libc_atexit";
- char *strtable = NULL;
- Elf_Shdr *sh;
-
+ const size_t sigsz = sizeof(signature);
+ char tbuf[sizeof(signature)];
int error;
- /*
- * load the section header table
- */
+ /* Load the section header table. */
shsize = eh->e_shnum * sizeof(Elf_Shdr);
sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize);
if (error)
goto out;
- /*
- * Now let's find the string table. If it does not exists, give up.
- */
- strndx = (int)(eh->e_shstrndx);
- if (strndx == SHN_UNDEF) {
+ /* Now let's find the string table. If it does not exist, give up. */
+ shstrndx = eh->e_shstrndx;
+ if (shstrndx == SHN_UNDEF || shstrndx >= eh->e_shnum) {
error = ENOEXEC;
goto out;
}
- /*
- * strndx is the index in section header table of the string table
- * section get the whole string table in strtable, and then we get access to the names
- * s->sh_name is the offset of the section name in strtable.
- */
- strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK);
- error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable,
- sh[strndx].sh_size);
- if (error)
- goto out;
-
+ /* Check if any section has the name we're looking for. */
+ const off_t stroff = sh[shstrndx].sh_offset;
for (i = 0; i < eh->e_shnum; i++) {
Elf_Shdr *s = &sh[i];
- if (!memcmp((void*)(&(strtable[s->sh_name])), signature,
- sizeof(signature))) {
- DPRINTF(("linux_atexit_sig=%s\n",
- &(strtable[s->sh_name])));
+
+ if (s->sh_name + sigsz > sh[shstrndx].sh_size)
+ continue;
+
+ error = exec_read_from(l, epp->ep_vp, stroff + s->sh_name, tbuf,
+ sigsz);
+ if (error)
+ goto out;
+ if (!memcmp(tbuf, signature, sigsz)) {
+ DPRINTF(("linux_atexit_sig=%s\n", tbuf));
error = 0;
goto out;
}
@@ -144,8 +137,6 @@ ELFNAME2(linux,atexit_signature)(
out:
free(sh, M_TEMP);
- if (strtable)
- free(strtable, M_TEMP);
return (error);
}
#endif
@@ -219,56 +210,48 @@ out:
#ifdef LINUX_DEBUGLINK_SIGNATURE
/*
- * Look for a .gnu_debuglink, specific to x86_64 interpeter
+ * Look for a .gnu_debuglink, specific to x86_64 interpreter
*/
int
ELFNAME2(linux,debuglink_signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh)
{
+ Elf_Shdr *sh;
size_t shsize;
- int strndx;
+ u_int shstrndx;
size_t i;
static const char signature[] = ".gnu_debuglink";
- char *strtable = NULL;
- Elf_Shdr *sh;
-
+ const size_t sigsz = sizeof(signature);
+ char tbuf[sizeof(signature)];
int error;
- /*
- * load the section header table
- */
+ /* Load the section header table. */
shsize = eh->e_shnum * sizeof(Elf_Shdr);
sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize);
if (error)
goto out;
- /*
- * Now let's find the string table. If it does not exists, give up.
- */
- strndx = (int)(eh->e_shstrndx);
- if (strndx == SHN_UNDEF) {
+ /* Now let's find the string table. If it does not exist, give up. */
+ shstrndx = eh->e_shstrndx;
+ if (shstrndx == SHN_UNDEF || shstrndx >= eh->e_shnum) {
error = ENOEXEC;
goto out;
}
- /*
- * strndx is the index in section header table of the string table
- * section get the whole string table in strtable, and then we get access to the names
- * s->sh_name is the offset of the section name in strtable.
- */
- strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK);
- error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable,
- sh[strndx].sh_size);
- if (error)
- goto out;
-
+ /* Check if any section has the name we're looking for. */
+ const off_t stroff = sh[shstrndx].sh_offset;
for (i = 0; i < eh->e_shnum; i++) {
Elf_Shdr *s = &sh[i];
- if (!memcmp((void*)(&(strtable[s->sh_name])), signature,
- sizeof(signature))) {
- DPRINTF(("linux_debuglink_sig=%s\n",
- &(strtable[s->sh_name])));
+ if (s->sh_name + sigsz > sh[shstrndx].sh_size)
+ continue;
+
+ error = exec_read_from(l, epp->ep_vp, stroff + s->sh_name, tbuf,
+ sigsz);
+ if (error)
+ goto out;
+ if (!memcmp(tbuf, signature, sigsz)) {
+ DPRINTF(("linux_debuglink_sig=%s\n", tbuf));
error = 0;
goto out;
}
@@ -277,8 +260,6 @@ ELFNAME2(linux,debuglink_signature)(struct lwp *l, struct exec_package *epp, Elf
out:
free(sh, M_TEMP);
- if (strtable)
- free(strtable, M_TEMP);
return (error);
}
#endif
@@ -340,7 +321,7 @@ ELFNAME2(linux,signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh,
continue;
}
- /* Check for certain intepreter names. */
+ /* Check for certain interpreter names. */
if (itp) {
if (!strncmp(itp, "/lib/ld-linux", 13) ||
#if (ELFSIZE == 64)