2000-05-26  Andreas Jaeger  <aj@suse.de>

	* 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 <gnu/lib-names.h> to specify
	library names.

	* sunrpc/xdr_intXX_t.c (xdr_uint8_t): Fix conversion.
	Closes PR libc/1573, reported by Bradley White
	<bww@laurelnetworks.com>.
This commit is contained in:
Andreas Jaeger 2000-05-26 10:23:45 +00:00
parent 446e763b48
commit dc95d15887
5 changed files with 64 additions and 14 deletions

View File

@ -1,3 +1,21 @@
2000-05-26 Andreas Jaeger <aj@suse.de>
* 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 <gnu/lib-names.h> to specify
library names.
* sunrpc/xdr_intXX_t.c (xdr_uint8_t): Fix conversion.
Closes PR libc/1573, reported by Bradley White
<bww@laurelnetworks.com>.
2000-05-25 Ulrich Drepper <drepper@redhat.com> 2000-05-25 Ulrich Drepper <drepper@redhat.com>
* sysdeps/i386/fpu/bits/mathinline.h: Define expm1 inline only if * sysdeps/i386/fpu/bits/mathinline.h: Define expm1 inline only if

View File

@ -46,7 +46,8 @@ extern int process_file (const char *file_name, const char *lib, int *flag,
/* Declared in readelflib.c. */ /* Declared in readelflib.c. */
extern int process_elf_file (const char *file_name, const char *lib, int *flag, extern 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);
/* Declared in ldconfig.c. */ /* Declared in ldconfig.c. */

View File

@ -35,6 +35,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <gnu/lib-names.h>
#include "ldconfig.h" #include "ldconfig.h"
@ -49,23 +50,26 @@ struct known_names
static struct known_names interpreters [] = static struct known_names interpreters [] =
{ {
{"/lib/ld-linux.so.2", FLAG_ELF_LIBC6}, {"/lib/" LD_LINUX_SO, FLAG_ELF_LIBC6},
{"/lib/ld-linux.so.1", FLAG_ELF_LIBC5} {"/lib/ld-linux.so.1", FLAG_ELF_LIBC5}
}; };
static struct known_names known_libs [] = static struct known_names known_libs [] =
{ {
{"libc.so.6", FLAG_ELF_LIBC6}, /* Old names: */
{"libc.so.5", FLAG_ELF_LIBC5}, {"libc.so.5", FLAG_ELF_LIBC5},
{"libm.so.6", FLAG_ELF_LIBC6}, {"libm.so.5", FLAG_ELF_LIBC5},
{"libm.so.5", FLAG_ELF_LIBC5} /* Current names: */
{LIBC_SO, FLAG_ELF_LIBC6},
{LIBM_SO, FLAG_ELF_LIBC6}
}; };
/* Returns 0 if everything is ok, != 0 in case of error. */ /* Returns 0 if everything is ok, != 0 in case of error. */
int int
process_file (const char *file_name, const char *lib, int *flag, char **soname, int is_link) process_file (const char *file_name, const char *lib, int *flag,
char **soname, int is_link)
{ {
FILE *file; FILE *file;
struct stat statbuf; struct stat statbuf;
@ -156,7 +160,8 @@ process_file (const char *file_name, const char *lib, int *flag, char **soname,
goto done; goto done;
} }
if (process_elf_file (file_name, lib, flag, soname, file_contents)) if (process_elf_file (file_name, lib, flag, soname, file_contents,
statbuf.st_size))
ret = 1; ret = 1;
done: done:

View File

@ -23,10 +23,24 @@
which need to handle both 32bit and 64bit ELF libraries, this file is which need to handle both 32bit and 64bit ELF libraries, this file is
included twice for each arch size. */ 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. */ /* Returns 0 if everything is ok, != 0 in case of error. */
int int
process_elf_file (const char *file_name, const char *lib, int *flag, char **soname, process_elf_file (const char *file_name, const char *lib, int *flag,
void *file_contents) char **soname, void *file_contents, size_t file_length)
{ {
int i; int i;
unsigned int j; 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. */ /* Get information from elf program header. */
elf_pheader = (ElfW(Phdr) *) (elf_header->e_phoff + file_contents); 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 /* The library is an elf library, now search for soname and
libc5/libc6. */ 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; for (i = 0, segment = elf_pheader;
i < elf_header->e_phnum; i++, segment++) i < elf_header->e_phnum; i++, segment++)
{ {
check_ptr (segment);
switch (segment->p_type) switch (segment->p_type)
{ {
case PT_LOAD: case PT_LOAD:
@ -94,6 +111,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona
break; break;
case PT_INTERP: case PT_INTERP:
program_interpreter = (char *) (file_contents + segment->p_offset); program_interpreter = (char *) (file_contents + segment->p_offset);
check_ptr (program_interpreter);
/* Check if this is enough to classify the binary. */ /* Check if this is enough to classify the binary. */
for (j = 0; j < sizeof (interpreters) / sizeof (interpreters [0]); 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; return 1;
dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr); dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr);
check_ptr (dynamic_segment);
/* Find the string table. */ /* Find the string table. */
dynamic_strings = NULL; dynamic_strings = NULL;
for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL; for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++dyn_entry) ++dyn_entry)
{ {
check_ptr (dyn_entry);
if (dyn_entry->d_tag == DT_STRTAB) if (dyn_entry->d_tag == DT_STRTAB)
{ {
dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr); dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
check_ptr (dynamic_strings);
break; 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) if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME)
{ {
char *name = dynamic_strings + dyn_entry->d_un.d_val; char *name = dynamic_strings + dyn_entry->d_un.d_val;
check_ptr (name);
if (dyn_entry->d_tag == DT_NEEDED) if (dyn_entry->d_tag == DT_NEEDED)
{ {

View File

@ -20,23 +20,27 @@
int process_elf32_file (const char *file_name, const char *lib, int *flag, 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, 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. */ /* Returns 0 if everything is ok, != 0 in case of error. */
int int
process_elf_file (const char *file_name, const char *lib, int *flag, 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; ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
int ret; int ret;
if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) 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 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+. */ /* Sparc 64bit libraries are always libc.so.6+. */
if (!ret) if (!ret)
*flag = FLAG_SPARC_LIB64|FLAG_ELF_LIBC6; *flag = FLAG_SPARC_LIB64|FLAG_ELF_LIBC6;