From dc95d1588775854fd5f7e617bfcb6f362bf3a923 Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Fri, 26 May 2000 10:23:45 +0000 Subject: Update. 2000-05-26 Andreas Jaeger * elf/ldconfig.h: Update parameter list for process_elf_file. * sysdeps/unix/sysv/linux/sparc/readelflib.c (process_elf_file): Add parameter file_length and pass it ot process_elf*file. * sysdeps/generic/readelflib.c (check_ptr): New. (process_elf_file): Use check_ptr to check all accesses to the mmapped file. Add parameter file_length. * elf/readlib.c (known_libs): Use to specify library names. * sunrpc/xdr_intXX_t.c (xdr_uint8_t): Fix conversion. Closes PR libc/1573, reported by Bradley White . --- sysdeps/generic/readelflib.c | 26 ++++++++++++++++++++++++-- sysdeps/unix/sysv/linux/sparc/readelflib.c | 14 +++++++++----- 2 files changed, 33 insertions(+), 7 deletions(-) (limited to 'sysdeps') diff --git a/sysdeps/generic/readelflib.c b/sysdeps/generic/readelflib.c index 645c9124a9..270c9b00a5 100644 --- a/sysdeps/generic/readelflib.c +++ b/sysdeps/generic/readelflib.c @@ -23,10 +23,24 @@ which need to handle both 32bit and 64bit ELF libraries, this file is included twice for each arch size. */ +/* check_ptr checks that a pointer is in the mmaped file and doesn't + point outside it. */ +#define check_ptr(ptr) \ +do \ + { \ + if ((void *)(ptr) < file_contents \ + || (void *)(ptr) > (file_contents+file_length)) \ + { \ + error (0, 0, _("file %s is truncated\n"), file_name); \ + return 1; \ + } \ + } \ + while (0); + /* Returns 0 if everything is ok, != 0 in case of error. */ int -process_elf_file (const char *file_name, const char *lib, int *flag, char **soname, - void *file_contents) +process_elf_file (const char *file_name, const char *lib, int *flag, + char **soname, void *file_contents, size_t file_length) { int i; unsigned int j; @@ -65,6 +79,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona /* Get information from elf program header. */ elf_pheader = (ElfW(Phdr) *) (elf_header->e_phoff + file_contents); + check_ptr (elf_pheader); /* The library is an elf library, now search for soname and libc5/libc6. */ @@ -77,6 +92,8 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona for (i = 0, segment = elf_pheader; i < elf_header->e_phnum; i++, segment++) { + check_ptr (segment); + switch (segment->p_type) { case PT_LOAD: @@ -94,6 +111,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona break; case PT_INTERP: program_interpreter = (char *) (file_contents + segment->p_offset); + check_ptr (program_interpreter); /* Check if this is enough to classify the binary. */ for (j = 0; j < sizeof (interpreters) / sizeof (interpreters [0]); @@ -120,15 +138,18 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona return 1; dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr); + check_ptr (dynamic_segment); /* Find the string table. */ dynamic_strings = NULL; for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL; ++dyn_entry) { + check_ptr (dyn_entry); if (dyn_entry->d_tag == DT_STRTAB) { dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr); + check_ptr (dynamic_strings); break; } } @@ -143,6 +164,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME) { char *name = dynamic_strings + dyn_entry->d_un.d_val; + check_ptr (name); if (dyn_entry->d_tag == DT_NEEDED) { diff --git a/sysdeps/unix/sysv/linux/sparc/readelflib.c b/sysdeps/unix/sysv/linux/sparc/readelflib.c index d956ad90f6..f5006278bb 100644 --- a/sysdeps/unix/sysv/linux/sparc/readelflib.c +++ b/sysdeps/unix/sysv/linux/sparc/readelflib.c @@ -20,23 +20,27 @@ int process_elf32_file (const char *file_name, const char *lib, int *flag, - char **soname, void *file_contents); + char **soname, void *file_contents, + size_t file_length); int process_elf64_file (const char *file_name, const char *lib, int *flag, - char **soname, void *file_contents); + char **soname, void *file_contents, + size_t file_length); /* Returns 0 if everything is ok, != 0 in case of error. */ int process_elf_file (const char *file_name, const char *lib, int *flag, - char **soname, void *file_contents) + char **soname, void *file_contents, size_t file_length) { ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents; int ret; if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) - return process_elf32_file (file_name, lib, flag, soname, file_contents); + return process_elf32_file (file_name, lib, flag, soname, file_contents, + file_length); else { - ret = process_elf64_file (file_name, lib, flag, soname, file_contents); + ret = process_elf64_file (file_name, lib, flag, soname, file_contents, + file_length); /* Sparc 64bit libraries are always libc.so.6+. */ if (!ret) *flag = FLAG_SPARC_LIB64|FLAG_ELF_LIBC6; -- cgit v1.2.3