From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1062) id D2D54385B83E; Sat, 6 Aug 2022 09:13:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D2D54385B83E Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Alan Modra To: bfd-cvs@sourceware.org Subject: [binutils-gdb] msan: bfd_mach_o_layout_commands use of uninitialised value X-Act-Checkin: binutils-gdb X-Git-Author: Alan Modra X-Git-Refname: refs/heads/master X-Git-Oldrev: 578a7392c33c7c7cde5559278e519c75047318c9 X-Git-Newrev: f7a559d5e11c5c023554b48b661aabbcc2c87cb8 Message-Id: <20220806091353.D2D54385B83E@sourceware.org> Date: Sat, 6 Aug 2022 09:13:53 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Aug 2022 09:13:53 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Df7a559d5e11c= 5c023554b48b661aabbcc2c87cb8 commit f7a559d5e11c5c023554b48b661aabbcc2c87cb8 Author: Alan Modra Date: Sat Aug 6 17:05:44 2022 +0930 msan: bfd_mach_o_layout_commands use of uninitialised value =20 Catches fuzzed input with unterminated strings that later run off the end of their buffers when calling strlen. =20 * mach-o.c: Use size_t vars where approprite. (bfd_mach_o_alloc_and_read): Add "extra" param. Allocate that much extra and clear. Update all callers, those that set up strings with one extra byte. Diff: --- bfd/mach-o.c | 78 ++++++++++++++++++++++++++++++++++----------------------= ---- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/bfd/mach-o.c b/bfd/mach-o.c index c761544e21e..eb325236454 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -379,7 +379,7 @@ bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, cons= t char *segname, { const mach_o_section_name_xlat *xlat; char *res; - unsigned int len; + size_t len; const char *pfx =3D ""; =20 *name =3D NULL; @@ -394,7 +394,7 @@ bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, cons= t char *segname, res =3D bfd_alloc (abfd, len + 1); if (res =3D=3D NULL) return; - memcpy (res, xlat->bfd_name, len+1); + memcpy (res, xlat->bfd_name, len + 1); *name =3D res; *flags =3D xlat->bfd_flags; return; @@ -440,9 +440,9 @@ bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd AT= TRIBUTE_UNUSED, const char *name =3D bfd_section_name (sect); const char *segname; const char *dot; - unsigned int len; - unsigned int seglen; - unsigned int seclen; + size_t len; + size_t seglen; + size_t seclen; =20 memset (section->segname, 0, BFD_MACH_O_SEGNAME_SIZE + 1); memset (section->sectname, 0, BFD_MACH_O_SECTNAME_SIZE + 1); @@ -983,7 +983,7 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd, bfd_mach_o_section *sec =3D mdata->sections[i]; unsigned int first, last; bfd_vma addr; - bfd_vma entry_size; + unsigned int entry_size; =20 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK) { @@ -1202,7 +1202,7 @@ bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type = mtype, number of bytes written or -1 in case of error. */ =20 static int -bfd_mach_o_pad4 (bfd *abfd, unsigned int len) +bfd_mach_o_pad4 (bfd *abfd, size_t len) { if (len % 4 !=3D 0) { @@ -1221,14 +1221,14 @@ bfd_mach_o_pad4 (bfd *abfd, unsigned int len) /* Likewise, but for a command. */ =20 static int -bfd_mach_o_pad_command (bfd *abfd, unsigned int len) +bfd_mach_o_pad_command (bfd *abfd, size_t len) { - unsigned int align =3D bfd_mach_o_wide_p (abfd) ? 8 : 4; + size_t align =3D bfd_mach_o_wide_p (abfd) ? 8 : 4; =20 if (len % align !=3D 0) { char pad[8] =3D {0}; - unsigned int padlen =3D align - (len % align); + size_t padlen =3D align - (len % align); =20 if (bfd_bwrite (pad, padlen, abfd) !=3D padlen) return -1; @@ -1243,7 +1243,7 @@ static bool bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header) { struct mach_o_header_external raw; - unsigned int size; + size_t size; =20 size =3D mach_o_wide_p (header) ? BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE; @@ -1272,7 +1272,7 @@ bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_c= ommand *command) bfd_mach_o_thread_command *cmd =3D &command->command.thread; unsigned int i; struct mach_o_thread_command_external raw; - unsigned int offset; + size_t offset; =20 BFD_ASSERT ((command->type =3D=3D BFD_MACH_O_LC_THREAD) || (command->type =3D=3D BFD_MACH_O_LC_UNIXTHREAD)); @@ -1281,8 +1281,8 @@ bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_c= ommand *command) for (i =3D 0; i < cmd->nflavours; i++) { BFD_ASSERT ((cmd->flavours[i].size % 4) =3D=3D 0); - BFD_ASSERT (cmd->flavours[i].offset =3D=3D - (command->offset + offset + BFD_MACH_O_LC_SIZE)); + BFD_ASSERT (cmd->flavours[i].offset + =3D=3D command->offset + offset + BFD_MACH_O_LC_SIZE); =20 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour); bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count); @@ -1302,7 +1302,7 @@ bfd_mach_o_write_dylinker (bfd *abfd, bfd_mach_o_load= _command *command) { bfd_mach_o_dylinker_command *cmd =3D &command->command.dylinker; struct mach_o_str_command_external raw; - unsigned int namelen; + size_t namelen; =20 bfd_h_put_32 (abfd, cmd->name_offset, raw.str); =20 @@ -1325,7 +1325,7 @@ bfd_mach_o_write_dylib (bfd *abfd, bfd_mach_o_load_co= mmand *command) { bfd_mach_o_dylib_command *cmd =3D &command->command.dylib; struct mach_o_dylib_command_external raw; - unsigned int namelen; + size_t namelen; =20 bfd_h_put_32 (abfd, cmd->name_offset, raw.name); bfd_h_put_32 (abfd, cmd->timestamp, raw.timestamp); @@ -4003,11 +4003,15 @@ bfd_mach_o_ppc_flavour_string (unsigned int flavour) } =20 static unsigned char * -bfd_mach_o_alloc_and_read (bfd *abfd, file_ptr filepos, size_t size) +bfd_mach_o_alloc_and_read (bfd *abfd, file_ptr filepos, + size_t size, size_t extra) { if (bfd_seek (abfd, filepos, SEEK_SET) !=3D 0) return NULL; - return _bfd_alloc_and_read (abfd, size, size); + unsigned char *ret =3D _bfd_alloc_and_read (abfd, size + extra, size); + if (ret && extra !=3D 0) + memset (ret + size, 0, extra); + return ret; } =20 static bool @@ -4016,7 +4020,7 @@ bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_= command *command) bfd_mach_o_dylinker_command *cmd =3D &command->command.dylinker; struct mach_o_str_command_external raw; unsigned int nameoff; - unsigned int namelen; + size_t namelen; =20 if (command->len < sizeof (raw) + 8) return false; @@ -4030,7 +4034,8 @@ bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_= command *command) cmd->name_offset =3D nameoff; namelen =3D command->len - nameoff; nameoff +=3D command->offset; - cmd->name_str =3D (char *) bfd_mach_o_alloc_and_read (abfd, nameoff, nam= elen); + cmd->name_str =3D (char *) bfd_mach_o_alloc_and_read (abfd, nameoff, + namelen, 1); return cmd->name_str !=3D NULL; } =20 @@ -4041,7 +4046,7 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_com= mand *command) bfd_mach_o_dylib_command *cmd =3D &command->command.dylib; struct mach_o_dylib_command_external raw; unsigned int nameoff; - unsigned int namelen; + size_t namelen; file_ptr pos; =20 if (command->len < sizeof (raw) + 8) @@ -4073,7 +4078,7 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_com= mand *command) cmd->name_offset =3D command->offset + nameoff; namelen =3D command->len - nameoff; pos =3D mdata->hdr_offset + cmd->name_offset; - cmd->name_str =3D (char *) bfd_mach_o_alloc_and_read (abfd, pos, namelen= ); + cmd->name_str =3D (char *) bfd_mach_o_alloc_and_read (abfd, pos, namelen= , 1); return cmd->name_str !=3D NULL; } =20 @@ -4151,7 +4156,7 @@ bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_co= mmand *command) bfd_mach_o_fvmlib_command *fvm =3D &command->command.fvmlib; struct mach_o_fvmlib_command_external raw; unsigned int nameoff; - unsigned int namelen; + size_t namelen; =20 if (command->len < sizeof (raw) + 8) return false; @@ -4167,7 +4172,7 @@ bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_co= mmand *command) fvm->name_offset =3D command->offset + nameoff; namelen =3D command->len - nameoff; fvm->name_str =3D (char *) bfd_mach_o_alloc_and_read (abfd, fvm->name_of= fset, - namelen); + namelen, 1); return fvm->name_str !=3D NULL; } =20 @@ -4235,7 +4240,7 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_co= mmand *command) for (i =3D 0; i < nflavours; i++) { asection *bfdsec; - unsigned int snamelen; + size_t snamelen; char *sname; const char *flavourstr; const char *prefix =3D "LC_THREAD"; @@ -4603,7 +4608,7 @@ bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_comma= nd *command) cmd->stroff =3D command->offset + off; cmd->str_len =3D command->len - off; cmd->str =3D (char *) bfd_mach_o_alloc_and_read (abfd, cmd->stroff, - cmd->str_len); + cmd->str_len, 1); return cmd->str !=3D NULL; } =20 @@ -4614,7 +4619,8 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_d= yld_info_command *cmd) if (cmd->rebase_content =3D=3D NULL && cmd->rebase_size !=3D 0) { cmd->rebase_content - =3D bfd_mach_o_alloc_and_read (abfd, cmd->rebase_off, cmd->rebase_size); + =3D bfd_mach_o_alloc_and_read (abfd, cmd->rebase_off, + cmd->rebase_size, 0); if (cmd->rebase_content =3D=3D NULL) return false; } @@ -4623,7 +4629,8 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_d= yld_info_command *cmd) if (cmd->bind_content =3D=3D NULL && cmd->bind_size !=3D 0) { cmd->bind_content - =3D bfd_mach_o_alloc_and_read (abfd, cmd->bind_off, cmd->bind_size); + =3D bfd_mach_o_alloc_and_read (abfd, cmd->bind_off, + cmd->bind_size, 0); if (cmd->bind_content =3D=3D NULL) return false; } @@ -4631,8 +4638,9 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_d= yld_info_command *cmd) /* Read weak bind content. */ if (cmd->weak_bind_content =3D=3D NULL && cmd->weak_bind_size !=3D 0) { - cmd->weak_bind_content =3D bfd_mach_o_alloc_and_read - (abfd, cmd->weak_bind_off, cmd->weak_bind_size); + cmd->weak_bind_content + =3D bfd_mach_o_alloc_and_read (abfd, cmd->weak_bind_off, + cmd->weak_bind_size, 0); if (cmd->weak_bind_content =3D=3D NULL) return false; } @@ -4640,8 +4648,9 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_d= yld_info_command *cmd) /* Read lazy bind content. */ if (cmd->lazy_bind_content =3D=3D NULL && cmd->lazy_bind_size !=3D 0) { - cmd->lazy_bind_content =3D bfd_mach_o_alloc_and_read - (abfd, cmd->lazy_bind_off, cmd->lazy_bind_size); + cmd->lazy_bind_content + =3D bfd_mach_o_alloc_and_read (abfd, cmd->lazy_bind_off, + cmd->lazy_bind_size, 0); if (cmd->lazy_bind_content =3D=3D NULL) return false; } @@ -4649,8 +4658,9 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_d= yld_info_command *cmd) /* Read export content. */ if (cmd->export_content =3D=3D NULL && cmd->export_size !=3D 0) { - cmd->export_content =3D bfd_mach_o_alloc_and_read - (abfd, cmd->export_off, cmd->export_size); + cmd->export_content + =3D bfd_mach_o_alloc_and_read (abfd, cmd->export_off, + cmd->export_size, 0); if (cmd->export_content =3D=3D NULL) return false; }