Skip to content

Commit 8abac80

Browse files
committed
PR24236, Heap buffer overflow in _bfd_archive_64_bit_slurp_armap
PR 24236 * archive64.c (_bfd_archive_64_bit_slurp_armap): Move code adding sentinel NUL to string buffer nearer to loop where it is used. Don't go past sentinel when scanning strings, and don't write NUL again. * archive.c (do_slurp_coff_armap): Simplify string handling to archive64.c style.
1 parent 7ae39e2 commit 8abac80

File tree

3 files changed

+22
-15
lines changed

3 files changed

+22
-15
lines changed

bfd/ChangeLog

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2019-02-20 Alan Modra <[email protected]>
2+
3+
PR 24236
4+
* archive64.c (_bfd_archive_64_bit_slurp_armap): Move code adding
5+
sentinel NUL to string buffer nearer to loop where it is used.
6+
Don't go past sentinel when scanning strings, and don't write
7+
NUL again.
8+
* archive.c (do_slurp_coff_armap): Simplify string handling to
9+
archive64.c style.
10+
111
2019-02-19 Alan Modra <[email protected]>
212

313
PR 24235

bfd/archive.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,7 @@ do_slurp_coff_armap (bfd *abfd)
10121012
int *raw_armap, *rawptr;
10131013
struct artdata *ardata = bfd_ardata (abfd);
10141014
char *stringbase;
1015+
char *stringend;
10151016
bfd_size_type stringsize;
10161017
bfd_size_type parsed_size;
10171018
carsym *carsyms;
@@ -1071,22 +1072,18 @@ do_slurp_coff_armap (bfd *abfd)
10711072
}
10721073

10731074
/* OK, build the carsyms. */
1074-
for (i = 0; i < nsymz && stringsize > 0; i++)
1075+
stringend = stringbase + stringsize;
1076+
*stringend = 0;
1077+
for (i = 0; i < nsymz; i++)
10751078
{
1076-
bfd_size_type len;
1077-
10781079
rawptr = raw_armap + i;
10791080
carsyms->file_offset = swap ((bfd_byte *) rawptr);
10801081
carsyms->name = stringbase;
1081-
/* PR 17512: file: 4a1d50c1. */
1082-
len = strnlen (stringbase, stringsize);
1083-
if (len < stringsize)
1084-
len ++;
1085-
stringbase += len;
1086-
stringsize -= len;
1082+
stringbase += strlen (stringbase);
1083+
if (stringbase != stringend)
1084+
++stringbase;
10871085
carsyms++;
10881086
}
1089-
*stringbase = 0;
10901087

10911088
ardata->symdef_count = nsymz;
10921089
ardata->first_file_filepos = bfd_tell (abfd);

bfd/archive64.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ _bfd_archive_64_bit_slurp_armap (bfd *abfd)
100100
return FALSE;
101101
carsyms = ardata->symdefs;
102102
stringbase = ((char *) ardata->symdefs) + carsym_size;
103-
stringbase[stringsize] = 0;
104-
stringend = stringbase + stringsize;
105103

106104
raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
107105
if (raw_armap == NULL)
@@ -115,15 +113,17 @@ _bfd_archive_64_bit_slurp_armap (bfd *abfd)
115113
goto release_raw_armap;
116114
}
117115

116+
stringend = stringbase + stringsize;
117+
*stringend = 0;
118118
for (i = 0; i < nsymz; i++)
119119
{
120120
carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
121121
carsyms->name = stringbase;
122-
if (stringbase < stringend)
123-
stringbase += strlen (stringbase) + 1;
122+
stringbase += strlen (stringbase);
123+
if (stringbase != stringend)
124+
++stringbase;
124125
++carsyms;
125126
}
126-
*stringbase = '\0';
127127

128128
ardata->symdef_count = nsymz;
129129
ardata->first_file_filepos = bfd_tell (abfd);

0 commit comments

Comments
 (0)