Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-3-0]: src/gnu/dist/binutils/bfd Pull up following revision(s) (re...
details: https://anonhg.NetBSD.org/src/rev/712471018236
branches: netbsd-3-0
changeset: 579485:712471018236
user: ghen <ghen%NetBSD.org@localhost>
date: Mon Jun 23 10:39:33 2008 +0000
description:
Pull up following revision(s) (requested by adrianp in ticket #1941):
gnu/dist/binutils/bfd/tekhex.c: revision 1.2 via patch
Fix for PR #33551 (a.k.a CVE-2006-2362)
Back port from the binutils CVS tree
Buffer overflow in getsym in tekhex.c in libbfd in Free Software Foundation
GNU Binutils before 20060423, as used by GNU strings, allows context-dependent
attackers to cause a denial of service (application crash) and possibly
execute arbitrary code via a file with a crafted Tektronix Hex Format (TekHex)
record in which the length character is not a valid hexadecimal character.
diffstat:
gnu/dist/binutils/bfd/tekhex.c | 86 ++++++++++++++++++++++++++++-------------
1 files changed, 58 insertions(+), 28 deletions(-)
diffs (228 lines):
diff -r e8932886bbf0 -r 712471018236 gnu/dist/binutils/bfd/tekhex.c
--- a/gnu/dist/binutils/bfd/tekhex.c Tue May 13 06:27:43 2008 +0000
+++ b/gnu/dist/binutils/bfd/tekhex.c Mon Jun 23 10:39:33 2008 +0000
@@ -99,7 +99,7 @@
#define ISHEX(x) hex_p(x)
static void tekhex_init PARAMS ((void));
-static bfd_vma getvalue PARAMS ((char **));
+static bfd_boolean getvalue PARAMS ((char **, bfd_vma *));
static void tekhex_print_symbol
PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
static void tekhex_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
@@ -121,11 +121,11 @@
static bfd_boolean tekhex_mkobject PARAMS ((bfd *));
static long tekhex_get_symtab_upper_bound PARAMS ((bfd *));
static long tekhex_canonicalize_symtab PARAMS ((bfd *, asymbol **));
-static void pass_over PARAMS ((bfd *, void (*) (bfd*, int, char *)));
-static void first_phase PARAMS ((bfd *, int, char *));
+static bfd_boolean pass_over PARAMS ((bfd *, bfd_boolean (*) (bfd*, int, char *)));
+static bfd_boolean first_phase PARAMS ((bfd *, int, char *));
static void insert_byte PARAMS ((bfd *, int, bfd_vma));
static struct data_struct *find_chunk PARAMS ((bfd *, bfd_vma));
-static unsigned int getsym PARAMS ((char *, char **));
+static bfd_boolean getsym PARAMS ((char *, char **, unsigned int *));
/*
Here's an example
@@ -304,40 +304,53 @@
#define enda(x) (x->vma + x->size)
-static bfd_vma
-getvalue (srcp)
+static bfd_boolean
+getvalue (srcp, valuep)
char **srcp;
+ bfd_vma *valuep;
{
char *src = *srcp;
bfd_vma value = 0;
- unsigned int len = hex_value(*src++);
+ unsigned int len;
+ if (!ISHEX(*src))
+ return FALSE;
+
+ len = hex_value(*src++);
if (len == 0)
len = 16;
while (len--)
{
+ if (!ISHEX(*src))
+ return FALSE;
value = value << 4 | hex_value(*src++);
}
*srcp = src;
- return value;
+ *valuep = value;
+ return TRUE;
}
-static unsigned int
-getsym (dstp, srcp)
+static bfd_boolean
+getsym (dstp, srcp, lenp)
char *dstp;
char **srcp;
+ unsigned int *lenp;
{
char *src = *srcp;
unsigned int i;
- unsigned int len = hex_value(*src++);
+ unsigned int len;
+ if (!ISHEX(*src))
+ return FALSE;
+ len = hex_value(*src++);
if (len == 0)
len = 16;
for (i = 0; i < len; i++)
dstp[i] = src[i];
dstp[i] = 0;
*srcp = src + i;
- return len;
+ *lenp = len;
+ return TRUE;
}
static struct data_struct *
@@ -383,7 +396,7 @@
/* The first pass is to find the names of all the sections, and see
how big the data is */
-static void
+static bfd_boolean
first_phase (abfd, type, src)
bfd *abfd;
int type;
@@ -391,6 +404,7 @@
{
asection *section = bfd_abs_section_ptr;
unsigned int len;
+ bfd_vma val;
char sym[17]; /* A symbol can only be 16chars long */
switch (type)
@@ -398,7 +412,10 @@
case '6':
/* Data record - read it and store it */
{
- bfd_vma addr = getvalue (&src);
+ bfd_vma addr;
+
+ if (!getvalue (&src, &addr))
+ return FALSE;
while (*src)
{
@@ -408,17 +425,18 @@
}
}
- return;
+ return TRUE;
case '3':
/* Symbol record, read the segment */
- len = getsym (sym, &src);
+ if (!getsym (sym, &src, &len))
+ return FALSE;
section = bfd_get_section_by_name (abfd, sym);
if (section == (asection *) NULL)
{
char *n = bfd_alloc (abfd, (bfd_size_type) len + 1);
if (!n)
- abort (); /* FIXME */
+ return FALSE;
memcpy (n, sym, len + 1);
section = bfd_make_section (abfd, n);
}
@@ -428,8 +446,11 @@
{
case '1': /* section range */
src++;
- section->vma = getvalue (&src);
- section->_raw_size = getvalue (&src) - section->vma;
+ if (!getvalue (&src, §ion->vma))
+ return FALSE;
+ if (!getvalue (&src, &val))
+ return FALSE;
+ section->_raw_size = val - section->vma;
section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
break;
case '0':
@@ -447,37 +468,43 @@
char stype = (*src);
if (!new)
- abort (); /* FIXME */
+ return FALSE;
new->symbol.the_bfd = abfd;
src++;
abfd->symcount++;
abfd->flags |= HAS_SYMS;
new->prev = abfd->tdata.tekhex_data->symbols;
abfd->tdata.tekhex_data->symbols = new;
- len = getsym (sym, &src);
+ if (!getsym (sym, &src, &len))
+ return FALSE;
new->symbol.name = bfd_alloc (abfd, (bfd_size_type) len + 1);
if (!new->symbol.name)
- abort (); /* FIXME */
+ return FALSE;
memcpy ((char *) (new->symbol.name), sym, len + 1);
new->symbol.section = section;
if (stype <= '4')
new->symbol.flags = (BSF_GLOBAL | BSF_EXPORT);
else
new->symbol.flags = BSF_LOCAL;
- new->symbol.value = getvalue (&src) - section->vma;
+ if (!getvalue (&src, &val))
+ return FALSE;
+ new->symbol.value = val - section->vma;
}
+ default:
+ return FALSE;
}
}
}
+ return TRUE;
}
/* Pass over a tekhex, calling one of the above functions on each
record. */
-static void
+static bfd_boolean
pass_over (abfd, func)
bfd *abfd;
- void (*func) PARAMS ((bfd *, int, char *));
+ bfd_boolean (*func) PARAMS ((bfd *, int, char *));
{
unsigned int chars_on_line;
bfd_boolean eof = FALSE;
@@ -516,9 +543,10 @@
abort (); /* FIXME */
src[chars_on_line] = 0; /* put a null at the end */
- func (abfd, type, src);
+ if (!func (abfd, type, src))
+ return FALSE;
}
-
+ return TRUE;
}
static long
@@ -585,7 +613,9 @@
tekhex_mkobject (abfd);
- pass_over (abfd, first_phase);
+ if (!pass_over (abfd, first_phase))
+ return NULL;
+
return abfd->xvec;
}
Home |
Main Index |
Thread Index |
Old Index