projects
/
deliverable
/
binutils-gdb.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Memory leaks and ineffective bounds checking in wasm_scan
[deliverable/binutils-gdb.git]
/
bfd
/
wasm-module.c
diff --git
a/bfd/wasm-module.c
b/bfd/wasm-module.c
index 6806e0f81d9c3c6205949b2fe0a527dbcb91800d..e62f842e12c07f7f6f6cfa96f884b02d746a6cc5 100644
(file)
--- a/
bfd/wasm-module.c
+++ b/
bfd/wasm-module.c
@@
-1,5
+1,5
@@
/* BFD back-end for WebAssembly modules.
/* BFD back-end for WebAssembly modules.
- Copyright (C) 2017-20
18
Free Software Foundation, Inc.
+ Copyright (C) 2017-20
20
Free Software Foundation, Inc.
Based on srec.c, mmo.c, and binary.c
Based on srec.c, mmo.c, and binary.c
@@
-28,9
+28,7
@@
#include "sysdep.h"
#include "alloca-conf.h"
#include "bfd.h"
#include "sysdep.h"
#include "alloca-conf.h"
#include "bfd.h"
-#include "sysdep.h"
#include <limits.h>
#include <limits.h>
-#include "bfd_stdint.h"
#include "libiberty.h"
#include "libbfd.h"
#include "wasm-module.h"
#include "libiberty.h"
#include "libbfd.h"
#include "wasm-module.h"
@@
-113,18
+111,28
@@
wasm_read_leb128 (bfd * abfd,
unsigned int num_read = 0;
unsigned int shift = 0;
unsigned char byte = 0;
unsigned int num_read = 0;
unsigned int shift = 0;
unsigned char byte = 0;
-
bfd_boolean success = FALSE
;
+
int status = 1
;
while (bfd_bread (&byte, 1, abfd) == 1)
{
num_read++;
while (bfd_bread (&byte, 1, abfd) == 1)
{
num_read++;
- result |= ((bfd_vma) (byte & 0x7f)) << shift;
+ if (shift < sizeof (result) * 8)
+ {
+ result |= ((bfd_vma) (byte & 0x7f)) << shift;
+ if ((result >> shift) != (byte & 0x7f))
+ /* Overflow. */
+ status |= 2;
+ shift += 7;
+ }
+ else if ((byte & 0x7f) != 0)
+ status |= 2;
- shift += 7;
if ((byte & 0x80) == 0)
{
if ((byte & 0x80) == 0)
{
- success = TRUE;
+ status &= ~1;
+ if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+ result |= -((bfd_vma) 1 << shift);
break;
}
}
break;
}
}
@@
-132,10
+140,7
@@
wasm_read_leb128 (bfd * abfd,
if (length_return != NULL)
*length_return = num_read;
if (error_return != NULL)
if (length_return != NULL)
*length_return = num_read;
if (error_return != NULL)
- *error_return = ! success;
-
- if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
- result |= -((bfd_vma) 1 << shift);
+ *error_return = status != 0;
return result;
}
return result;
}
@@
-241,16
+246,10
@@
wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
asymbol *symbols = NULL;
sec_ptr space_function_index;
asymbol *symbols = NULL;
sec_ptr space_function_index;
- if (! asect)
- return FALSE;
-
- if (strcmp (asect->name, WASM_NAME_SECTION) != 0)
- return FALSE;
-
p = asect->contents;
end = asect->contents + asect->size;
p = asect->contents;
end = asect->contents + asect->size;
- if (!
p)
+ if (!p)
return FALSE;
while (p < end)
return FALSE;
while (p < end)
@@
-267,7
+266,7
@@
wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
READ_LEB128 (payload_size, p, end);
READ_LEB128 (payload_size, p, end);
- if (p
> p + payload_size
)
+ if (p
ayload_size > (size_t) (end - p)
)
return FALSE;
p += payload_size;
return FALSE;
p += payload_size;
@@
-278,10
+277,7
@@
wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
READ_LEB128 (payload_size, p, end);
READ_LEB128 (payload_size, p, end);
- if (p > p + payload_size)
- return FALSE;
-
- if (p + payload_size > end)
+ if (payload_size > (size_t) (end - p))
return FALSE;
end = p + payload_size;
return FALSE;
end = p + payload_size;
@@
-289,22
+285,24
@@
wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
READ_LEB128 (symcount, p, end);
/* Sanity check: each symbol has at least two bytes. */
READ_LEB128 (symcount, p, end);
/* Sanity check: each symbol has at least two bytes. */
- if (symcount > payload_size
/
2)
+ if (symcount > payload_size
/
2)
return FALSE;
tdata->symcount = symcount;
return FALSE;
tdata->symcount = symcount;
- space_function_index = bfd_make_section_with_flags
- (abfd, WASM_SECTION_FUNCTION_INDEX, SEC_READONLY | SEC_CODE);
+ space_function_index
+ = bfd_make_section_with_flags (abfd, WASM_SECTION_FUNCTION_INDEX,
+ SEC_READONLY | SEC_CODE);
- if (! space_function_index)
- space_function_index = bfd_get_section_by_name (abfd, WASM_SECTION_FUNCTION_INDEX);
+ if (!space_function_index)
+ space_function_index
+ = bfd_get_section_by_name (abfd, WASM_SECTION_FUNCTION_INDEX);
- if (!
space_function_index)
+ if (!space_function_index)
return FALSE;
return FALSE;
- symbols = bfd_
zalloc (abfd, tdata->symcount *
sizeof (asymbol));
- if (!
symbols)
+ symbols = bfd_
alloc2 (abfd, tdata->symcount,
sizeof (asymbol));
+ if (!symbols)
return FALSE;
for (symcount = 0; p < end && symcount < tdata->symcount; symcount++)
return FALSE;
for (symcount = 0; p < end && symcount < tdata->symcount; symcount++)
@@
-317,14
+315,15
@@
wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
READ_LEB128 (idx, p, end);
READ_LEB128 (len, p, end);
READ_LEB128 (idx, p, end);
READ_LEB128 (len, p, end);
- if (
p + len < p || p + len > end
)
+ if (
len > (size_t) (end - p)
)
goto error_return;
goto error_return;
- name = bfd_
z
alloc (abfd, len + 1);
- if (!
name)
+ name = bfd_alloc (abfd, len + 1);
+ if (!name)
goto error_return;
memcpy (name, p, len);
goto error_return;
memcpy (name, p, len);
+ name[len] = 0;
p += len;
sym = &symbols[symcount];
p += len;
sym = &symbols[symcount];
@@
-345,8
+344,6
@@
wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
return TRUE;
error_return:
return TRUE;
error_return:
- while (symcount)
- bfd_release (abfd, (void *)symbols[--symcount].name);
bfd_release (abfd, symbols);
return FALSE;
}
bfd_release (abfd, symbols);
return FALSE;
}
@@
-381,13
+378,12
@@
wasm_scan (bfd *abfd)
bfd_vma vma = 0x80000000;
int section_code;
unsigned int bytes_read;
bfd_vma vma = 0x80000000;
int section_code;
unsigned int bytes_read;
- char *name = NULL;
asection *bfdsec;
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
goto error_return;
asection *bfdsec;
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
goto error_return;
- if (!
wasm_read_header (abfd, &error))
+ if (!wasm_read_header (abfd, &error))
goto error_return;
while ((section_code = wasm_read_byte (abfd, &error)) != EOF)
goto error_return;
while ((section_code = wasm_read_byte (abfd, &error)) != EOF)
@@
-396,14
+392,13
@@
wasm_scan (bfd *abfd)
{
const char *sname = wasm_section_code_to_name (section_code);
{
const char *sname = wasm_section_code_to_name (section_code);
- if (!
sname)
+ if (!sname)
goto error_return;
goto error_return;
- name = strdup (sname);
-
bfdsec = bfd_make_section_anyway_with_flags (abfd, name,
SEC_HAS_CONTENTS);
+ bfdsec = bfd_make_section_anyway_with_flags (abfd, sname,
+
SEC_HAS_CONTENTS);
if (bfdsec == NULL)
goto error_return;
if (bfdsec == NULL)
goto error_return;
- name = NULL;
bfdsec->vma = vma;
bfdsec->lma = vma;
bfdsec->vma = vma;
bfdsec->lma = vma;
@@
-418,9
+413,9
@@
wasm_scan (bfd *abfd)
bfd_vma payload_len;
file_ptr section_start;
bfd_vma namelen;
bfd_vma payload_len;
file_ptr section_start;
bfd_vma namelen;
+ char *name;
char *prefix = WASM_SECTION_PREFIX;
char *prefix = WASM_SECTION_PREFIX;
- char *p;
- int ret;
+ size_t prefixlen = strlen (prefix);
payload_len = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
if (error)
payload_len = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
if (error)
@@
-429,21
+424,18
@@
wasm_scan (bfd *abfd)
namelen = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
if (error || namelen > payload_len)
goto error_return;
namelen = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE);
if (error || namelen > payload_len)
goto error_return;
- name = bfd_zmalloc (namelen + strlen (prefix) + 1);
- if (! name)
- goto error_return;
- p = name;
- ret = sprintf (p, "%s", prefix);
- if (ret < 0 || (bfd_vma) ret != strlen (prefix))
+ name = bfd_alloc (abfd, namelen + prefixlen + 1);
+ if (!name)
goto error_return;
goto error_return;
-
p += ret
;
- if (bfd_bread (
p
, namelen, abfd) != namelen)
+
memcpy (name, prefix, prefixlen)
;
+ if (bfd_bread (
name + prefixlen
, namelen, abfd) != namelen)
goto error_return;
goto error_return;
+ name[prefixlen + namelen] = 0;
- bfdsec = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ bfdsec = bfd_make_section_anyway_with_flags (abfd, name,
+ SEC_HAS_CONTENTS);
if (bfdsec == NULL)
goto error_return;
if (bfdsec == NULL)
goto error_return;
- name = NULL;
bfdsec->vma = vma;
bfdsec->lma = vma;
bfdsec->vma = vma;
bfdsec->lma = vma;
@@
-454,8
+446,8
@@
wasm_scan (bfd *abfd)
if (bfdsec->size != 0)
{
if (bfdsec->size != 0)
{
- bfdsec->contents = bfd_
z
alloc (abfd, bfdsec->size);
- if (!
bfdsec->contents)
+ bfdsec->contents = bfd_alloc (abfd, bfdsec->size);
+ if (!bfdsec->contents)
goto error_return;
if (bfd_bread (bfdsec->contents, bfdsec->size, abfd) != bfdsec->size)
goto error_return;
if (bfd_bread (bfdsec->contents, bfdsec->size, abfd) != bfdsec->size)
@@
-473,12
+465,6
@@
wasm_scan (bfd *abfd)
return TRUE;
error_return:
return TRUE;
error_return:
- if (name)
- free (name);
-
- for (bfdsec = abfd->sections; bfdsec; bfdsec = bfdsec->next)
- free ((void *) bfdsec->name);
-
return FALSE;
}
return FALSE;
}
@@
-745,23
+731,30
@@
static const bfd_target *
wasm_object_p (bfd *abfd)
{
bfd_boolean error;
wasm_object_p (bfd *abfd)
{
bfd_boolean error;
+ asection *s;
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
return NULL;
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
return NULL;
- if (!
wasm_read_header (abfd, &error))
+ if (!wasm_read_header (abfd, &error))
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
- if (!
wasm_mkobject (abfd) || ! wasm_scan
(abfd))
+ if (!
wasm_mkobject
(abfd))
return NULL;
return NULL;
- if (! bfd_default_set_arch_mach (abfd, bfd_arch_wasm32, 0))
- return NULL;
+ if (!wasm_scan (abfd)
+ || !bfd_default_set_arch_mach (abfd, bfd_arch_wasm32, 0))
+ {
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ return NULL;
+ }
- if (wasm_scan_name_function_section (abfd, bfd_get_section_by_name (abfd, WASM_NAME_SECTION)))
+ s = bfd_get_section_by_name (abfd, WASM_NAME_SECTION);
+ if (s != NULL && wasm_scan_name_function_section (abfd, s))
abfd->flags |= HAS_SYMS;
return abfd->xvec;
abfd->flags |= HAS_SYMS;
return abfd->xvec;
This page took
0.02878 seconds
and
4
git commands to generate.