From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by sourceware.org (Postfix) with ESMTPS id 645FF385800E for ; Sat, 6 Aug 2022 09:12:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 645FF385800E Received: by mail-pj1-x102c.google.com with SMTP id v16-20020a17090abb9000b001f25244c65dso10260787pjr.2 for ; Sat, 06 Aug 2022 02:12:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=XflIeO/pG4D5VfVUjJM0G/zj7Eo5GQ3Y7lioyr9NTys=; b=DsT2klDLoZn4ze7LDOStnbK+vW8BArlL2xgysOyVdELYnjiADHPkY8Ael5gwSjNlUP YXZb5/ivqnNRpKEFEPNTJ8ZWvSg1VkoioJxkGMg/mu5T5sjP0EkDlqKprfMa0dJmnKtz z0dgRI68BVpQaIXZMpU1RRXnl+qL1oz5GjzhRxH6q6DdlIFgExUMGfJcfumzqwSK5FNQ U4GpApNF36tOaGwit609qEjg01h8oGfKdYkL5WGYL+MGzhWuCK7e1YMkPqoD7fKSoqeM hSzLSu6ZHbuhpoqNGgc8MvYRuDOwu6LVEfjaWCVJ+tGfd7N8xBo14le58Y1WNVpzd1gU W7ow== X-Gm-Message-State: ACgBeo3bfbFqkpV2tNyoO1UfyqM03I1uV8hAwdHOg06b33r31D9fPytZ MY2/1pvdSft83BPnFmMIU8cMEA66g7c= X-Google-Smtp-Source: AA6agR5X167eslzXLNSlBGPm3enpZ8R3kvHdN4NvSRVh2nc6I2gfPk/+UllFIR6XL7h3E41ZSHenRw== X-Received: by 2002:a17:90b:1d90:b0:1f2:5f47:ca6c with SMTP id pf16-20020a17090b1d9000b001f25f47ca6cmr20305057pjb.162.1659777143878; Sat, 06 Aug 2022 02:12:23 -0700 (PDT) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:b433:7963:2f3b:b98]) by smtp.gmail.com with ESMTPSA id a16-20020aa79710000000b0052d40c4c06esm4487976pfg.39.2022.08.06.02.12.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Aug 2022 02:12:23 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 010121142EB7; Sat, 6 Aug 2022 18:42:20 +0930 (ACST) Date: Sat, 6 Aug 2022 18:42:20 +0930 From: Alan Modra To: binutils@sourceware.org Subject: msan: bfd_mach_o_layout_commands use of uninitialised value Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3036.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Aug 2022 09:12:28 -0000 Catches fuzzed input with unterminated strings that later run off the end of their buffers when calling strlen. * 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 --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, const char *segname, { const mach_o_section_name_xlat *xlat; char *res; - unsigned int len; + size_t len; const char *pfx = ""; *name = NULL; @@ -394,7 +394,7 @@ bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname, res = bfd_alloc (abfd, len + 1); if (res == NULL) return; - memcpy (res, xlat->bfd_name, len+1); + memcpy (res, xlat->bfd_name, len + 1); *name = res; *flags = xlat->bfd_flags; return; @@ -440,9 +440,9 @@ bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED, const char *name = 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; 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 = mdata->sections[i]; unsigned int first, last; bfd_vma addr; - bfd_vma entry_size; + unsigned int entry_size; 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. */ static int -bfd_mach_o_pad4 (bfd *abfd, unsigned int len) +bfd_mach_o_pad4 (bfd *abfd, size_t len) { if (len % 4 != 0) { @@ -1221,14 +1221,14 @@ bfd_mach_o_pad4 (bfd *abfd, unsigned int len) /* Likewise, but for a command. */ 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 = bfd_mach_o_wide_p (abfd) ? 8 : 4; + size_t align = bfd_mach_o_wide_p (abfd) ? 8 : 4; if (len % align != 0) { char pad[8] = {0}; - unsigned int padlen = align - (len % align); + size_t padlen = align - (len % align); if (bfd_bwrite (pad, padlen, abfd) != 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; size = 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_command *command) bfd_mach_o_thread_command *cmd = &command->command.thread; unsigned int i; struct mach_o_thread_command_external raw; - unsigned int offset; + size_t offset; BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD) || (command->type == BFD_MACH_O_LC_UNIXTHREAD)); @@ -1281,8 +1281,8 @@ bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command) for (i = 0; i < cmd->nflavours; i++) { BFD_ASSERT ((cmd->flavours[i].size % 4) == 0); - BFD_ASSERT (cmd->flavours[i].offset == - (command->offset + offset + BFD_MACH_O_LC_SIZE)); + BFD_ASSERT (cmd->flavours[i].offset + == command->offset + offset + BFD_MACH_O_LC_SIZE); 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 = &command->command.dylinker; struct mach_o_str_command_external raw; - unsigned int namelen; + size_t namelen; bfd_h_put_32 (abfd, cmd->name_offset, raw.str); @@ -1325,7 +1325,7 @@ bfd_mach_o_write_dylib (bfd *abfd, bfd_mach_o_load_command *command) { bfd_mach_o_dylib_command *cmd = &command->command.dylib; struct mach_o_dylib_command_external raw; - unsigned int namelen; + size_t namelen; 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) } 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) != 0) return NULL; - return _bfd_alloc_and_read (abfd, size, size); + unsigned char *ret = _bfd_alloc_and_read (abfd, size + extra, size); + if (ret && extra != 0) + memset (ret + size, 0, extra); + return ret; } 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 = &command->command.dylinker; struct mach_o_str_command_external raw; unsigned int nameoff; - unsigned int namelen; + size_t namelen; 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 = nameoff; namelen = command->len - nameoff; nameoff += command->offset; - cmd->name_str = (char *) bfd_mach_o_alloc_and_read (abfd, nameoff, namelen); + cmd->name_str = (char *) bfd_mach_o_alloc_and_read (abfd, nameoff, + namelen, 1); return cmd->name_str != NULL; } @@ -4041,7 +4046,7 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command) bfd_mach_o_dylib_command *cmd = &command->command.dylib; struct mach_o_dylib_command_external raw; unsigned int nameoff; - unsigned int namelen; + size_t namelen; file_ptr pos; if (command->len < sizeof (raw) + 8) @@ -4073,7 +4078,7 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command) cmd->name_offset = command->offset + nameoff; namelen = command->len - nameoff; pos = mdata->hdr_offset + cmd->name_offset; - cmd->name_str = (char *) bfd_mach_o_alloc_and_read (abfd, pos, namelen); + cmd->name_str = (char *) bfd_mach_o_alloc_and_read (abfd, pos, namelen, 1); return cmd->name_str != NULL; } @@ -4151,7 +4156,7 @@ bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command) bfd_mach_o_fvmlib_command *fvm = &command->command.fvmlib; struct mach_o_fvmlib_command_external raw; unsigned int nameoff; - unsigned int namelen; + size_t namelen; if (command->len < sizeof (raw) + 8) return false; @@ -4167,7 +4172,7 @@ bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command) fvm->name_offset = command->offset + nameoff; namelen = command->len - nameoff; fvm->name_str = (char *) bfd_mach_o_alloc_and_read (abfd, fvm->name_offset, - namelen); + namelen, 1); return fvm->name_str != NULL; } @@ -4235,7 +4240,7 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command) for (i = 0; i < nflavours; i++) { asection *bfdsec; - unsigned int snamelen; + size_t snamelen; char *sname; const char *flavourstr; const char *prefix = "LC_THREAD"; @@ -4603,7 +4608,7 @@ bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command) cmd->stroff = command->offset + off; cmd->str_len = command->len - off; cmd->str = (char *) bfd_mach_o_alloc_and_read (abfd, cmd->stroff, - cmd->str_len); + cmd->str_len, 1); return cmd->str != NULL; } @@ -4614,7 +4619,8 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd) if (cmd->rebase_content == NULL && cmd->rebase_size != 0) { cmd->rebase_content - = bfd_mach_o_alloc_and_read (abfd, cmd->rebase_off, cmd->rebase_size); + = bfd_mach_o_alloc_and_read (abfd, cmd->rebase_off, + cmd->rebase_size, 0); if (cmd->rebase_content == NULL) return false; } @@ -4623,7 +4629,8 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd) if (cmd->bind_content == NULL && cmd->bind_size != 0) { cmd->bind_content - = bfd_mach_o_alloc_and_read (abfd, cmd->bind_off, cmd->bind_size); + = bfd_mach_o_alloc_and_read (abfd, cmd->bind_off, + cmd->bind_size, 0); if (cmd->bind_content == NULL) return false; } @@ -4631,8 +4638,9 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd) /* Read weak bind content. */ if (cmd->weak_bind_content == NULL && cmd->weak_bind_size != 0) { - cmd->weak_bind_content = bfd_mach_o_alloc_and_read - (abfd, cmd->weak_bind_off, cmd->weak_bind_size); + cmd->weak_bind_content + = bfd_mach_o_alloc_and_read (abfd, cmd->weak_bind_off, + cmd->weak_bind_size, 0); if (cmd->weak_bind_content == NULL) return false; } @@ -4640,8 +4648,9 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd) /* Read lazy bind content. */ if (cmd->lazy_bind_content == NULL && cmd->lazy_bind_size != 0) { - cmd->lazy_bind_content = bfd_mach_o_alloc_and_read - (abfd, cmd->lazy_bind_off, cmd->lazy_bind_size); + cmd->lazy_bind_content + = bfd_mach_o_alloc_and_read (abfd, cmd->lazy_bind_off, + cmd->lazy_bind_size, 0); if (cmd->lazy_bind_content == NULL) return false; } @@ -4649,8 +4658,9 @@ bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd) /* Read export content. */ if (cmd->export_content == NULL && cmd->export_size != 0) { - cmd->export_content = bfd_mach_o_alloc_and_read - (abfd, cmd->export_off, cmd->export_size); + cmd->export_content + = bfd_mach_o_alloc_and_read (abfd, cmd->export_off, + cmd->export_size, 0); if (cmd->export_content == NULL) return false; } -- Alan Modra Australia Development Lab, IBM