From patchwork Sat Apr 15 15:26:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 22646 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3C55C77B76 for ; Sat, 15 Apr 2023 15:27:07 +0000 (UTC) Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) by mx.groups.io with SMTP id smtpd.web11.10381.1681572421278908051 for ; Sat, 15 Apr 2023 08:27:01 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@sakoman-com.20221208.gappssmtp.com header.s=20221208 header.b=nNuaRLPL; spf=softfail (domain: sakoman.com, ip: 209.85.210.181, mailfrom: steve@sakoman.com) Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-63b5312bd4fso3331571b3a.0 for ; Sat, 15 Apr 2023 08:27:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20221208.gappssmtp.com; s=20221208; t=1681572420; x=1684164420; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=BOf0pbbhPDrxYCJhk/lrERtRJa7lcZ7epmZnqEu9wH4=; b=nNuaRLPLnEzH1TLYVj65NYZcQ+KE00+ApMc6nkd3a3HzCrrauMVATfEUlGFh9MKER9 29EYdmmLIKnULwbtCd/KSQicQNZMEFEnohypLIrtUAVSAkiiEy4XtOhEowg5M7Piy6yX RXM/pZa8MXkUJuwn4ViNjpQAjedt1AX/3yxA75d24sEjM3KkL+gUCa+vwnE+g3EHcJpA QcpUedKxaxmDuzADPKslSimAkPI58qT6EqwTAgPZyNmvxH2RZAKLoath/PWZCb0vL746 8qSPXUqlRU053oiid/VYpX/CvDNadHAIA2kNasEySL5kY1+P4Nw5CP5tWWWTb6VqmTcX u2Ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681572420; x=1684164420; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BOf0pbbhPDrxYCJhk/lrERtRJa7lcZ7epmZnqEu9wH4=; b=KtyBXXE32akRgy3D2WyTPf1EESKuFlziupfcok6VmyiX0AtoZX5Uy4wEPYctHo2mH/ mUbSI6hLrhs2JcHXNBlyPkCVXywGusPnNMVG7ywjx3ouXCoH1JX+6Do2dAXkiUmEOv4n eR8AQoYFQTq0tLa1DK6qjXlO/o3degrOrQvL1wl2REKhBcqeTKU9uGNK79y+AnNB1ctv GtooDbJO6pGZhSCvd1A2x50TUWEQtt6G3VZZ7WgKja1+v+5gj2+Ho8Ri7PoT11PRZE/Z 02BaJ67JVfrmcPQYgXXBoYAJSTZe0K+1ZFVQ1Cr32Eg7GmurqS3RIIMBzvCsg2vymQgz CWAA== X-Gm-Message-State: AAQBX9eCzahf0qjifrpGjVhpq4QawzwGT8W+DmfNhQtJu+/BR1F+/RGO g224uuJYDQuyBHEoneZ0Gj7lHSS2joVaz0Kr6Zo= X-Google-Smtp-Source: AKy350aAWhsA4rAxFH8aY8dlfcOVGwds+iqgCqhXfaBsdKl6Xro9CtOP5OO8BXIDOTHZVRuYWDahtw== X-Received: by 2002:a05:6a00:240b:b0:634:c34f:e214 with SMTP id z11-20020a056a00240b00b00634c34fe214mr16569722pfh.10.1681572418065; Sat, 15 Apr 2023 08:26:58 -0700 (PDT) Received: from hexa.router0800d9.com (dhcp-72-253-4-112.hawaiiantel.net. [72.253.4.112]) by smtp.gmail.com with ESMTPSA id u22-20020aa78496000000b0063b1e7ffc5fsm4824410pfn.39.2023.04.15.08.26.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Apr 2023 08:26:57 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 1/7] binutils : Fix CVE-2023-1579 Date: Sat, 15 Apr 2023 05:26:38 -1000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 15 Apr 2023 15:27:07 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/180012 From: Yash Shinde Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3e307d538c351aa9327cbad672c884059ecc20dd] Signed-off-by: Yash Shinde Signed-off-by: Steve Sakoman --- .../binutils/binutils-2.38.inc | 4 + .../binutils/0021-CVE-2023-1579-1.patch | 459 ++++ .../binutils/0021-CVE-2023-1579-2.patch | 2127 +++++++++++++++++ .../binutils/0021-CVE-2023-1579-3.patch | 156 ++ .../binutils/0021-CVE-2023-1579-4.patch | 37 + 5 files changed, 2783 insertions(+) create mode 100644 meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-1.patch create mode 100644 meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-2.patch create mode 100644 meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch create mode 100644 meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-4.patch diff --git a/meta/recipes-devtools/binutils/binutils-2.38.inc b/meta/recipes-devtools/binutils/binutils-2.38.inc index 30a34d7ba4..bf44e6c762 100644 --- a/meta/recipes-devtools/binutils/binutils-2.38.inc +++ b/meta/recipes-devtools/binutils/binutils-2.38.inc @@ -46,5 +46,9 @@ SRC_URI = "\ file://0020-CVE-2023-22608-1.patch \ file://0020-CVE-2023-22608-2.patch \ file://0020-CVE-2023-22608-3.patch \ + file://0021-CVE-2023-1579-1.patch \ + file://0021-CVE-2023-1579-2.patch \ + file://0021-CVE-2023-1579-3.patch \ + file://0021-CVE-2023-1579-4.patch \ " S = "${WORKDIR}/git" diff --git a/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-1.patch b/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-1.patch new file mode 100644 index 0000000000..1e9c03e70e --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-1.patch @@ -0,0 +1,459 @@ +From f67741e172bf342291fe3abd2b395899ce6433a0 Mon Sep 17 00:00:00 2001 +From: "Potharla, Rupesh" +Date: Tue, 24 May 2022 00:01:49 +0000 +Subject: [PATCH] bfd: Add Support for DW_FORM_strx* and DW_FORM_addrx* + +Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=f67741e172bf342291fe3abd2b395899ce6433a0] + +CVE: CVE-2023-1579 + +Signed-off-by: Yash Shinde + +--- + bfd/dwarf2.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 268 insertions(+), 14 deletions(-) + +diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c +index f6b0183720b..45e286754e4 100644 +--- a/bfd/dwarf2.c ++++ b/bfd/dwarf2.c +@@ -189,6 +189,18 @@ struct dwarf2_debug_file + /* Length of the loaded .debug_str section. */ + bfd_size_type dwarf_str_size; + ++ /* Pointer to the .debug_str_offsets section loaded into memory. */ ++ bfd_byte *dwarf_str_offsets_buffer; ++ ++ /* Length of the loaded .debug_str_offsets section. */ ++ bfd_size_type dwarf_str_offsets_size; ++ ++ /* Pointer to the .debug_addr section loaded into memory. */ ++ bfd_byte *dwarf_addr_buffer; ++ ++ /* Length of the loaded .debug_addr section. */ ++ bfd_size_type dwarf_addr_size; ++ + /* Pointer to the .debug_line_str section loaded into memory. */ + bfd_byte *dwarf_line_str_buffer; + +@@ -382,6 +394,12 @@ struct comp_unit + /* Used when iterating over trie leaves to know which units we have + already seen in this iteration. */ + bool mark; ++ ++ /* Base address of debug_addr section. */ ++ size_t dwarf_addr_offset; ++ ++ /* Base address of string offset table. */ ++ size_t dwarf_str_offset; + }; + + /* This data structure holds the information of an abbrev. */ +@@ -424,6 +442,8 @@ const struct dwarf_debug_section dwarf_debug_sections[] = + { ".debug_static_vars", ".zdebug_static_vars" }, + { ".debug_str", ".zdebug_str", }, + { ".debug_str", ".zdebug_str", }, ++ { ".debug_str_offsets", ".zdebug_str_offsets", }, ++ { ".debug_addr", ".zdebug_addr", }, + { ".debug_line_str", ".zdebug_line_str", }, + { ".debug_types", ".zdebug_types" }, + /* GNU DWARF 1 extensions */ +@@ -458,6 +478,8 @@ enum dwarf_debug_section_enum + debug_static_vars, + debug_str, + debug_str_alt, ++ debug_str_offsets, ++ debug_addr, + debug_line_str, + debug_types, + debug_sfnames, +@@ -1307,12 +1329,92 @@ is_int_form (const struct attribute *attr) + } + } + ++/* Returns true if the form is strx[1-4]. */ ++ ++static inline bool ++is_strx_form (enum dwarf_form form) ++{ ++ return (form == DW_FORM_strx ++ || form == DW_FORM_strx1 ++ || form == DW_FORM_strx2 ++ || form == DW_FORM_strx3 ++ || form == DW_FORM_strx4); ++} ++ ++/* Return true if the form is addrx[1-4]. */ ++ ++static inline bool ++is_addrx_form (enum dwarf_form form) ++{ ++ return (form == DW_FORM_addrx ++ || form == DW_FORM_addrx1 ++ || form == DW_FORM_addrx2 ++ || form == DW_FORM_addrx3 ++ || form == DW_FORM_addrx4); ++} ++ ++/* Returns the address in .debug_addr section using DW_AT_addr_base. ++ Used to implement DW_FORM_addrx*. */ ++static bfd_vma ++read_indexed_address (bfd_uint64_t idx, ++ struct comp_unit *unit) ++{ ++ struct dwarf2_debug *stash = unit->stash; ++ struct dwarf2_debug_file *file = unit->file; ++ size_t addr_base = unit->dwarf_addr_offset; ++ bfd_byte *info_ptr; ++ ++ if (stash == NULL) ++ return 0; ++ ++ if (!read_section (unit->abfd, &stash->debug_sections[debug_addr], ++ file->syms, 0, ++ &file->dwarf_addr_buffer, &file->dwarf_addr_size)) ++ return 0; ++ ++ info_ptr = file->dwarf_addr_buffer + addr_base + idx * unit->offset_size; ++ ++ if (unit->offset_size == 4) ++ return bfd_get_32 (unit->abfd, info_ptr); ++ else ++ return bfd_get_64 (unit->abfd, info_ptr); ++} ++ ++/* Returns the string using DW_AT_str_offsets_base. ++ Used to implement DW_FORM_strx*. */ + static const char * +-read_indexed_string (bfd_uint64_t idx ATTRIBUTE_UNUSED, +- struct comp_unit * unit ATTRIBUTE_UNUSED) ++read_indexed_string (bfd_uint64_t idx, ++ struct comp_unit *unit) + { +- /* FIXME: Add support for indexed strings. */ +- return ""; ++ struct dwarf2_debug *stash = unit->stash; ++ struct dwarf2_debug_file *file = unit->file; ++ bfd_byte *info_ptr; ++ unsigned long str_offset; ++ ++ if (stash == NULL) ++ return NULL; ++ ++ if (!read_section (unit->abfd, &stash->debug_sections[debug_str], ++ file->syms, 0, ++ &file->dwarf_str_buffer, &file->dwarf_str_size)) ++ return NULL; ++ ++ if (!read_section (unit->abfd, &stash->debug_sections[debug_str_offsets], ++ file->syms, 0, ++ &file->dwarf_str_offsets_buffer, ++ &file->dwarf_str_offsets_size)) ++ return NULL; ++ ++ info_ptr = (file->dwarf_str_offsets_buffer ++ + unit->dwarf_str_offset ++ + idx * unit->offset_size); ++ ++ if (unit->offset_size == 4) ++ str_offset = bfd_get_32 (unit->abfd, info_ptr); ++ else ++ str_offset = bfd_get_64 (unit->abfd, info_ptr); ++ ++ return (const char *) file->dwarf_str_buffer + str_offset; + } + + /* Read and fill in the value of attribute ATTR as described by FORM. +@@ -1381,21 +1483,37 @@ read_attribute_value (struct attribute * attr, + case DW_FORM_ref1: + case DW_FORM_flag: + case DW_FORM_data1: ++ attr->u.val = read_1_byte (abfd, &info_ptr, info_ptr_end); ++ break; + case DW_FORM_addrx1: + attr->u.val = read_1_byte (abfd, &info_ptr, info_ptr_end); ++ /* dwarf_addr_offset value 0 indicates the attribute DW_AT_addr_base ++ is not yet read. */ ++ if (unit->dwarf_addr_offset != 0) ++ attr->u.val = read_indexed_address (attr->u.val, unit); + break; + case DW_FORM_data2: +- case DW_FORM_addrx2: + case DW_FORM_ref2: + attr->u.val = read_2_bytes (abfd, &info_ptr, info_ptr_end); + break; ++ case DW_FORM_addrx2: ++ attr->u.val = read_2_bytes (abfd, &info_ptr, info_ptr_end); ++ if (unit->dwarf_addr_offset != 0) ++ attr->u.val = read_indexed_address (attr->u.val, unit); ++ break; + case DW_FORM_addrx3: + attr->u.val = read_3_bytes (abfd, &info_ptr, info_ptr_end); ++ if (unit->dwarf_addr_offset != 0) ++ attr->u.val = read_indexed_address(attr->u.val, unit); + break; + case DW_FORM_ref4: + case DW_FORM_data4: ++ attr->u.val = read_4_bytes (abfd, &info_ptr, info_ptr_end); ++ break; + case DW_FORM_addrx4: + attr->u.val = read_4_bytes (abfd, &info_ptr, info_ptr_end); ++ if (unit->dwarf_addr_offset != 0) ++ attr->u.val = read_indexed_address (attr->u.val, unit); + break; + case DW_FORM_data8: + case DW_FORM_ref8: +@@ -1416,24 +1534,31 @@ read_attribute_value (struct attribute * attr, + break; + case DW_FORM_strx1: + attr->u.val = read_1_byte (abfd, &info_ptr, info_ptr_end); +- attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ /* dwarf_str_offset value 0 indicates the attribute DW_AT_str_offsets_base ++ is not yet read. */ ++ if (unit->dwarf_str_offset != 0) ++ attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + break; + case DW_FORM_strx2: + attr->u.val = read_2_bytes (abfd, &info_ptr, info_ptr_end); +- attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ if (unit->dwarf_str_offset != 0) ++ attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + break; + case DW_FORM_strx3: + attr->u.val = read_3_bytes (abfd, &info_ptr, info_ptr_end); +- attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ if (unit->dwarf_str_offset != 0) ++ attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + break; + case DW_FORM_strx4: + attr->u.val = read_4_bytes (abfd, &info_ptr, info_ptr_end); +- attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ if (unit->dwarf_str_offset != 0) ++ attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + break; + case DW_FORM_strx: + attr->u.val = _bfd_safe_read_leb128 (abfd, &info_ptr, + false, info_ptr_end); +- attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ if (unit->dwarf_str_offset != 0) ++ attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + break; + case DW_FORM_exprloc: + case DW_FORM_block: +@@ -1455,9 +1580,14 @@ read_attribute_value (struct attribute * attr, + break; + case DW_FORM_ref_udata: + case DW_FORM_udata: ++ attr->u.val = _bfd_safe_read_leb128 (abfd, &info_ptr, ++ false, info_ptr_end); ++ break; + case DW_FORM_addrx: + attr->u.val = _bfd_safe_read_leb128 (abfd, &info_ptr, + false, info_ptr_end); ++ if (unit->dwarf_addr_offset != 0) ++ attr->u.val = read_indexed_address (attr->u.val, unit); + break; + case DW_FORM_indirect: + form = _bfd_safe_read_leb128 (abfd, &info_ptr, +@@ -2396,6 +2526,11 @@ read_formatted_entries (struct comp_unit *unit, bfd_byte **bufp, + { + case DW_FORM_string: + case DW_FORM_line_strp: ++ case DW_FORM_strx: ++ case DW_FORM_strx1: ++ case DW_FORM_strx2: ++ case DW_FORM_strx3: ++ case DW_FORM_strx4: + *stringp = attr.u.str; + break; + +@@ -4031,6 +4166,80 @@ scan_unit_for_symbols (struct comp_unit *unit) + return false; + } + ++/* Read the attributes of the form strx and addrx. */ ++ ++static void ++reread_attribute (struct comp_unit *unit, ++ struct attribute *attr, ++ bfd_vma *low_pc, ++ bfd_vma *high_pc, ++ bool *high_pc_relative, ++ bool compunit) ++{ ++ if (is_strx_form (attr->form)) ++ attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ if (is_addrx_form (attr->form)) ++ attr->u.val = read_indexed_address (attr->u.val, unit); ++ ++ switch (attr->name) ++ { ++ case DW_AT_stmt_list: ++ unit->stmtlist = 1; ++ unit->line_offset = attr->u.val; ++ break; ++ ++ case DW_AT_name: ++ if (is_str_form (attr)) ++ unit->name = attr->u.str; ++ break; ++ ++ case DW_AT_low_pc: ++ *low_pc = attr->u.val; ++ if (compunit) ++ unit->base_address = *low_pc; ++ break; ++ ++ case DW_AT_high_pc: ++ *high_pc = attr->u.val; ++ *high_pc_relative = attr->form != DW_FORM_addr; ++ break; ++ ++ case DW_AT_ranges: ++ if (!read_rangelist (unit, &unit->arange, ++ &unit->file->trie_root, attr->u.val)) ++ return; ++ break; ++ ++ case DW_AT_comp_dir: ++ { ++ char *comp_dir = attr->u.str; ++ ++ if (!is_str_form (attr)) ++ { ++ _bfd_error_handler ++ (_("DWARF error: DW_AT_comp_dir attribute encountered " ++ "with a non-string form")); ++ comp_dir = NULL; ++ } ++ ++ if (comp_dir) ++ { ++ char *cp = strchr (comp_dir, ':'); ++ ++ if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/') ++ comp_dir = cp + 1; ++ } ++ unit->comp_dir = comp_dir; ++ break; ++ } ++ ++ case DW_AT_language: ++ unit->lang = attr->u.val; ++ default: ++ break; ++ } ++} ++ + /* Parse a DWARF2 compilation unit starting at INFO_PTR. UNIT_LENGTH + includes the compilation unit header that proceeds the DIE's, but + does not include the length field that precedes each compilation +@@ -4064,6 +4273,10 @@ parse_comp_unit (struct dwarf2_debug *stash, + bfd *abfd = file->bfd_ptr; + bool high_pc_relative = false; + enum dwarf_unit_type unit_type; ++ struct attribute *str_addrp = NULL; ++ size_t str_count = 0; ++ size_t str_alloc = 0; ++ bool compunit_flag = false; + + version = read_2_bytes (abfd, &info_ptr, end_ptr); + if (version < 2 || version > 5) +@@ -4168,11 +4381,33 @@ parse_comp_unit (struct dwarf2_debug *stash, + unit->file = file; + unit->info_ptr_unit = info_ptr_unit; + ++ if (abbrev->tag == DW_TAG_compile_unit) ++ compunit_flag = true; ++ + for (i = 0; i < abbrev->num_attrs; ++i) + { + info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr, end_ptr); + if (info_ptr == NULL) +- return NULL; ++ goto err_exit; ++ ++ /* Identify attributes of the form strx* and addrx* which come before ++ DW_AT_str_offsets_base and DW_AT_addr_base respectively in the CU. ++ Store the attributes in an array and process them later. */ ++ if ((unit->dwarf_str_offset == 0 && is_strx_form (attr.form)) ++ || (unit->dwarf_addr_offset == 0 && is_addrx_form (attr.form))) ++ { ++ if (str_count <= str_alloc) ++ { ++ str_alloc = 2 * str_alloc + 200; ++ str_addrp = bfd_realloc (str_addrp, ++ str_alloc * sizeof (*str_addrp)); ++ if (str_addrp == NULL) ++ goto err_exit; ++ } ++ str_addrp[str_count] = attr; ++ str_count++; ++ continue; ++ } + + /* Store the data if it is of an attribute we want to keep in a + partial symbol table. */ +@@ -4198,7 +4433,7 @@ parse_comp_unit (struct dwarf2_debug *stash, + /* If the compilation unit DIE has a DW_AT_low_pc attribute, + this is the base address to use when reading location + lists or range lists. */ +- if (abbrev->tag == DW_TAG_compile_unit) ++ if (compunit_flag) + unit->base_address = low_pc; + } + break; +@@ -4215,7 +4450,7 @@ parse_comp_unit (struct dwarf2_debug *stash, + if (is_int_form (&attr) + && !read_rangelist (unit, &unit->arange, + &unit->file->trie_root, attr.u.val)) +- return NULL; ++ goto err_exit; + break; + + case DW_AT_comp_dir: +@@ -4248,21 +4483,40 @@ parse_comp_unit (struct dwarf2_debug *stash, + unit->lang = attr.u.val; + break; + ++ case DW_AT_addr_base: ++ unit->dwarf_addr_offset = attr.u.val; ++ break; ++ ++ case DW_AT_str_offsets_base: ++ unit->dwarf_str_offset = attr.u.val; ++ break; ++ + default: + break; + } + } ++ ++ for (i = 0; i < str_count; ++i) ++ reread_attribute (unit, &str_addrp[i], &low_pc, &high_pc, ++ &high_pc_relative, compunit_flag); ++ + if (high_pc_relative) + high_pc += low_pc; + if (high_pc != 0) + { + if (!arange_add (unit, &unit->arange, &unit->file->trie_root, + low_pc, high_pc)) +- return NULL; ++ goto err_exit; + } + + unit->first_child_die_ptr = info_ptr; ++ ++ free (str_addrp); + return unit; ++ ++ err_exit: ++ free (str_addrp); ++ return NULL; + } + + /* Return TRUE if UNIT may contain the address given by ADDR. When +-- +2.31.1 + diff --git a/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-2.patch b/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-2.patch new file mode 100644 index 0000000000..be698ef5c1 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-2.patch @@ -0,0 +1,2127 @@ +From 0e3c1eebb22e0ade28b619fb41f42d66ed6fb145 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Fri, 27 May 2022 12:37:21 +0930 +Subject: [PATCH] Remove use of bfd_uint64_t and similar + +Requiring C99 means that uses of bfd_uint64_t can be replaced with +uint64_t, and similarly for bfd_int64_t, BFD_HOST_U_64_BIT, and +BFD_HOST_64_BIT. This patch does that, removes #ifdef BFD_HOST_* +and tidies a few places that print 64-bit values. + +Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=0e3c1eebb22e0ade28b619fb41f42d66ed6fb145] + +CVE: CVE-2023-1579 + +Signed-off-by: Yash Shinde + +--- + bfd/aix386-core.c | 6 +-- + bfd/bfd-in.h | 24 ++++++------ + bfd/bfd-in2.h | 36 +++++++++--------- + bfd/coff-rs6000.c | 10 +---- + bfd/coff-x86_64.c | 2 +- + bfd/cpu-ia64-opc.c | 22 +++++------ + bfd/dwarf2.c | 83 ++++++++++++++++++++--------------------- + bfd/elf32-score.c | 16 ++++---- + bfd/elf64-ia64-vms.c | 8 ++-- + bfd/elflink.c | 16 +------- + bfd/elfxx-ia64.c | 6 +-- + bfd/hppabsd-core.c | 6 +-- + bfd/hpux-core.c | 6 +-- + bfd/irix-core.c | 6 +-- + bfd/libbfd.c | 65 +++++++++----------------------- + bfd/mach-o.c | 2 +- + bfd/mach-o.h | 8 ++-- + bfd/netbsd-core.c | 6 +-- + bfd/osf-core.c | 6 +-- + bfd/ptrace-core.c | 6 +-- + bfd/sco5-core.c | 6 +-- + bfd/targets.c | 12 +++--- + bfd/trad-core.c | 6 +-- + bfd/vms-alpha.c | 2 +- + binutils/nm.c | 49 +++--------------------- + binutils/od-macho.c | 50 ++++++++----------------- + binutils/prdbg.c | 39 +++---------------- + binutils/readelf.c | 21 +++++------ + gas/config/tc-arm.c | 28 ++++---------- + gas/config/tc-csky.c | 10 ++--- + gas/config/tc-sparc.c | 35 +++++++++-------- + gas/config/tc-tilegx.c | 20 +++++----- + gas/config/tc-tilepro.c | 20 +++++----- + gas/config/tc-z80.c | 8 ++-- + gas/config/te-vms.c | 2 +- + gas/config/te-vms.h | 2 +- + gdb/findcmd.c | 2 +- + gdb/tilegx-tdep.c | 2 +- + gprof/gmon_io.c | 44 ++++++---------------- + include/elf/nfp.h | 2 +- + include/opcode/csky.h | 62 +++++++++++++++--------------- + include/opcode/ia64.h | 2 +- + opcodes/csky-dis.c | 2 +- + opcodes/csky-opc.h | 4 +- + opcodes/ia64-dis.c | 2 +- + 45 files changed, 297 insertions(+), 475 deletions(-) + +diff --git a/bfd/aix386-core.c b/bfd/aix386-core.c +index 3443e49ed46..977a6bd1fb4 100644 +--- a/bfd/aix386-core.c ++++ b/bfd/aix386-core.c +@@ -220,9 +220,9 @@ swap_abort (void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_aix386_vec = + { +diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h +index a1c4bf139fc..09c5728e944 100644 +--- a/bfd/bfd-in.h ++++ b/bfd/bfd-in.h +@@ -116,10 +116,10 @@ typedef struct bfd bfd; + #error No 64 bit integer type available + #endif /* ! defined (BFD_HOST_64_BIT) */ + +-typedef BFD_HOST_U_64_BIT bfd_vma; +-typedef BFD_HOST_64_BIT bfd_signed_vma; +-typedef BFD_HOST_U_64_BIT bfd_size_type; +-typedef BFD_HOST_U_64_BIT symvalue; ++typedef uint64_t bfd_vma; ++typedef int64_t bfd_signed_vma; ++typedef uint64_t bfd_size_type; ++typedef uint64_t symvalue; + + #if BFD_HOST_64BIT_LONG + #define BFD_VMA_FMT "l" +@@ -447,10 +447,10 @@ extern bool bfd_record_phdr + + /* Byte swapping routines. */ + +-bfd_uint64_t bfd_getb64 (const void *); +-bfd_uint64_t bfd_getl64 (const void *); +-bfd_int64_t bfd_getb_signed_64 (const void *); +-bfd_int64_t bfd_getl_signed_64 (const void *); ++uint64_t bfd_getb64 (const void *); ++uint64_t bfd_getl64 (const void *); ++int64_t bfd_getb_signed_64 (const void *); ++int64_t bfd_getl_signed_64 (const void *); + bfd_vma bfd_getb32 (const void *); + bfd_vma bfd_getl32 (const void *); + bfd_signed_vma bfd_getb_signed_32 (const void *); +@@ -459,8 +459,8 @@ bfd_vma bfd_getb16 (const void *); + bfd_vma bfd_getl16 (const void *); + bfd_signed_vma bfd_getb_signed_16 (const void *); + bfd_signed_vma bfd_getl_signed_16 (const void *); +-void bfd_putb64 (bfd_uint64_t, void *); +-void bfd_putl64 (bfd_uint64_t, void *); ++void bfd_putb64 (uint64_t, void *); ++void bfd_putl64 (uint64_t, void *); + void bfd_putb32 (bfd_vma, void *); + void bfd_putl32 (bfd_vma, void *); + void bfd_putb24 (bfd_vma, void *); +@@ -470,8 +470,8 @@ void bfd_putl16 (bfd_vma, void *); + + /* Byte swapping routines which take size and endiannes as arguments. */ + +-bfd_uint64_t bfd_get_bits (const void *, int, bool); +-void bfd_put_bits (bfd_uint64_t, void *, int, bool); ++uint64_t bfd_get_bits (const void *, int, bool); ++void bfd_put_bits (uint64_t, void *, int, bool); + + + /* mmap hacks */ +diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h +index 50e26fc691d..d50885e76cf 100644 +--- a/bfd/bfd-in2.h ++++ b/bfd/bfd-in2.h +@@ -123,10 +123,10 @@ typedef struct bfd bfd; + #error No 64 bit integer type available + #endif /* ! defined (BFD_HOST_64_BIT) */ + +-typedef BFD_HOST_U_64_BIT bfd_vma; +-typedef BFD_HOST_64_BIT bfd_signed_vma; +-typedef BFD_HOST_U_64_BIT bfd_size_type; +-typedef BFD_HOST_U_64_BIT symvalue; ++typedef uint64_t bfd_vma; ++typedef int64_t bfd_signed_vma; ++typedef uint64_t bfd_size_type; ++typedef uint64_t symvalue; + + #if BFD_HOST_64BIT_LONG + #define BFD_VMA_FMT "l" +@@ -454,10 +454,10 @@ extern bool bfd_record_phdr + + /* Byte swapping routines. */ + +-bfd_uint64_t bfd_getb64 (const void *); +-bfd_uint64_t bfd_getl64 (const void *); +-bfd_int64_t bfd_getb_signed_64 (const void *); +-bfd_int64_t bfd_getl_signed_64 (const void *); ++uint64_t bfd_getb64 (const void *); ++uint64_t bfd_getl64 (const void *); ++int64_t bfd_getb_signed_64 (const void *); ++int64_t bfd_getl_signed_64 (const void *); + bfd_vma bfd_getb32 (const void *); + bfd_vma bfd_getl32 (const void *); + bfd_signed_vma bfd_getb_signed_32 (const void *); +@@ -466,8 +466,8 @@ bfd_vma bfd_getb16 (const void *); + bfd_vma bfd_getl16 (const void *); + bfd_signed_vma bfd_getb_signed_16 (const void *); + bfd_signed_vma bfd_getl_signed_16 (const void *); +-void bfd_putb64 (bfd_uint64_t, void *); +-void bfd_putl64 (bfd_uint64_t, void *); ++void bfd_putb64 (uint64_t, void *); ++void bfd_putl64 (uint64_t, void *); + void bfd_putb32 (bfd_vma, void *); + void bfd_putl32 (bfd_vma, void *); + void bfd_putb24 (bfd_vma, void *); +@@ -477,8 +477,8 @@ void bfd_putl16 (bfd_vma, void *); + + /* Byte swapping routines which take size and endiannes as arguments. */ + +-bfd_uint64_t bfd_get_bits (const void *, int, bool); +-void bfd_put_bits (bfd_uint64_t, void *, int, bool); ++uint64_t bfd_get_bits (const void *, int, bool); ++void bfd_put_bits (uint64_t, void *, int, bool); + + + /* mmap hacks */ +@@ -7416,9 +7416,9 @@ typedef struct bfd_target + /* Entries for byte swapping for data. These are different from the + other entry points, since they don't take a BFD as the first argument. + Certain other handlers could do the same. */ +- bfd_uint64_t (*bfd_getx64) (const void *); +- bfd_int64_t (*bfd_getx_signed_64) (const void *); +- void (*bfd_putx64) (bfd_uint64_t, void *); ++ uint64_t (*bfd_getx64) (const void *); ++ int64_t (*bfd_getx_signed_64) (const void *); ++ void (*bfd_putx64) (uint64_t, void *); + bfd_vma (*bfd_getx32) (const void *); + bfd_signed_vma (*bfd_getx_signed_32) (const void *); + void (*bfd_putx32) (bfd_vma, void *); +@@ -7427,9 +7427,9 @@ typedef struct bfd_target + void (*bfd_putx16) (bfd_vma, void *); + + /* Byte swapping for the headers. */ +- bfd_uint64_t (*bfd_h_getx64) (const void *); +- bfd_int64_t (*bfd_h_getx_signed_64) (const void *); +- void (*bfd_h_putx64) (bfd_uint64_t, void *); ++ uint64_t (*bfd_h_getx64) (const void *); ++ int64_t (*bfd_h_getx_signed_64) (const void *); ++ void (*bfd_h_putx64) (uint64_t, void *); + bfd_vma (*bfd_h_getx32) (const void *); + bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); + void (*bfd_h_putx32) (bfd_vma, void *); +diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c +index 8819187ab42..48ce5c0516b 100644 +--- a/bfd/coff-rs6000.c ++++ b/bfd/coff-rs6000.c +@@ -1890,18 +1890,12 @@ xcoff_write_armap_old (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED, + } + + static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1]; +-#if BFD_HOST_64BIT_LONG +-#define FMT20 "%-20ld" +-#elif defined (__MSVCRT__) +-#define FMT20 "%-20I64d" +-#else +-#define FMT20 "%-20lld" +-#endif ++#define FMT20 "%-20" PRId64 + #define FMT12 "%-12d" + #define FMT12_OCTAL "%-12o" + #define FMT4 "%-4d" + #define PRINT20(d, v) \ +- sprintf (buff20, FMT20, (bfd_uint64_t)(v)), \ ++ sprintf (buff20, FMT20, (uint64_t) (v)), \ + memcpy ((void *) (d), buff20, 20) + + #define PRINT12(d, v) \ +diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c +index e8e16d3ce4b..cf339c93215 100644 +--- a/bfd/coff-x86_64.c ++++ b/bfd/coff-x86_64.c +@@ -201,7 +201,7 @@ coff_amd64_reloc (bfd *abfd, + + case 4: + { +- bfd_uint64_t x = bfd_get_64 (abfd, addr); ++ uint64_t x = bfd_get_64 (abfd, addr); + DOIT (x); + bfd_put_64 (abfd, x, addr); + } +diff --git a/bfd/cpu-ia64-opc.c b/bfd/cpu-ia64-opc.c +index e2b5c2694b6..01e3c3f476a 100644 +--- a/bfd/cpu-ia64-opc.c ++++ b/bfd/cpu-ia64-opc.c +@@ -99,14 +99,14 @@ ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) + static const char* + ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) + { +- BFD_HOST_U_64_BIT value = 0; ++ uint64_t value = 0; + int i, bits = 0, total = 0; + + for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) + { + bits = self->field[i].bits; + value |= ((code >> self->field[i].shift) +- & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total; ++ & (((uint64_t) 1 << bits) - 1)) << total; + total += bits; + } + *valuep = value; +@@ -161,7 +161,7 @@ static const char* + ins_imms_scaled (const struct ia64_operand *self, ia64_insn value, + ia64_insn *code, int scale) + { +- BFD_HOST_64_BIT svalue = value, sign_bit = 0; ++ int64_t svalue = value, sign_bit = 0; + ia64_insn new_insn = 0; + int i; + +@@ -186,17 +186,17 @@ ext_imms_scaled (const struct ia64_operand *self, ia64_insn code, + ia64_insn *valuep, int scale) + { + int i, bits = 0, total = 0; +- BFD_HOST_U_64_BIT val = 0, sign; ++ uint64_t val = 0, sign; + + for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) + { + bits = self->field[i].bits; + val |= ((code >> self->field[i].shift) +- & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total; ++ & (((uint64_t) 1 << bits) - 1)) << total; + total += bits; + } + /* sign extend: */ +- sign = (BFD_HOST_U_64_BIT) 1 << (total - 1); ++ sign = (uint64_t) 1 << (total - 1); + val = (val ^ sign) - sign; + + *valuep = val << scale; +@@ -312,7 +312,7 @@ static const char* + ins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) + { + --value; +- if (value >= ((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) ++ if (value >= (uint64_t) 1 << self->field[0].bits) + return "count out of range"; + + *code |= value << self->field[0].shift; +@@ -323,7 +323,7 @@ static const char* + ext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) + { + *valuep = ((code >> self->field[0].shift) +- & ((((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) - 1)) + 1; ++ & (((uint64_t) 1 << self->field[0].bits) - 1)) + 1; + return 0; + } + +@@ -421,8 +421,8 @@ ext_strd5b (const struct ia64_operand *self, ia64_insn code, + static const char* + ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) + { +- BFD_HOST_64_BIT val = value; +- BFD_HOST_U_64_BIT sign = 0; ++ int64_t val = value; ++ uint64_t sign = 0; + + if (val < 0) + { +@@ -444,7 +444,7 @@ ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) + static const char* + ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) + { +- BFD_HOST_64_BIT val; ++ int64_t val; + int negate; + + val = (code >> self->field[0].shift) & 0x7; +diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c +index 45e286754e4..6a728fc38b0 100644 +--- a/bfd/dwarf2.c ++++ b/bfd/dwarf2.c +@@ -63,8 +63,8 @@ struct attribute + { + char *str; + struct dwarf_block *blk; +- bfd_uint64_t val; +- bfd_int64_t sval; ++ uint64_t val; ++ int64_t sval; + } + u; + }; +@@ -632,12 +632,12 @@ lookup_info_hash_table (struct info_hash_table *hash_table, const char *key) + the located section does not contain at least OFFSET bytes. */ + + static bool +-read_section (bfd * abfd, ++read_section (bfd *abfd, + const struct dwarf_debug_section *sec, +- asymbol ** syms, +- bfd_uint64_t offset, +- bfd_byte ** section_buffer, +- bfd_size_type * section_size) ++ asymbol **syms, ++ uint64_t offset, ++ bfd_byte **section_buffer, ++ bfd_size_type *section_size) + { + const char *section_name = sec->uncompressed_name; + bfd_byte *contents = *section_buffer; +@@ -848,7 +848,7 @@ read_indirect_string (struct comp_unit *unit, + bfd_byte **ptr, + bfd_byte *buf_end) + { +- bfd_uint64_t offset; ++ uint64_t offset; + struct dwarf2_debug *stash = unit->stash; + struct dwarf2_debug_file *file = unit->file; + char *str; +@@ -882,7 +882,7 @@ read_indirect_line_string (struct comp_unit *unit, + bfd_byte **ptr, + bfd_byte *buf_end) + { +- bfd_uint64_t offset; ++ uint64_t offset; + struct dwarf2_debug *stash = unit->stash; + struct dwarf2_debug_file *file = unit->file; + char *str; +@@ -919,7 +919,7 @@ read_alt_indirect_string (struct comp_unit *unit, + bfd_byte **ptr, + bfd_byte *buf_end) + { +- bfd_uint64_t offset; ++ uint64_t offset; + struct dwarf2_debug *stash = unit->stash; + char *str; + +@@ -975,8 +975,7 @@ read_alt_indirect_string (struct comp_unit *unit, + or NULL upon failure. */ + + static bfd_byte * +-read_alt_indirect_ref (struct comp_unit * unit, +- bfd_uint64_t offset) ++read_alt_indirect_ref (struct comp_unit *unit, uint64_t offset) + { + struct dwarf2_debug *stash = unit->stash; + +@@ -1012,7 +1011,7 @@ read_alt_indirect_ref (struct comp_unit * unit, + return stash->alt.dwarf_info_buffer + offset; + } + +-static bfd_uint64_t ++static uint64_t + read_address (struct comp_unit *unit, bfd_byte **ptr, bfd_byte *buf_end) + { + bfd_byte *buf = *ptr; +@@ -1131,7 +1130,7 @@ del_abbrev (void *p) + in a hash table. */ + + static struct abbrev_info** +-read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash, ++read_abbrevs (bfd *abfd, uint64_t offset, struct dwarf2_debug *stash, + struct dwarf2_debug_file *file) + { + struct abbrev_info **abbrevs; +@@ -1356,8 +1355,7 @@ is_addrx_form (enum dwarf_form form) + /* Returns the address in .debug_addr section using DW_AT_addr_base. + Used to implement DW_FORM_addrx*. */ + static bfd_vma +-read_indexed_address (bfd_uint64_t idx, +- struct comp_unit *unit) ++read_indexed_address (uint64_t idx, struct comp_unit *unit) + { + struct dwarf2_debug *stash = unit->stash; + struct dwarf2_debug_file *file = unit->file; +@@ -1383,8 +1381,7 @@ read_indexed_address (bfd_uint64_t idx, + /* Returns the string using DW_AT_str_offsets_base. + Used to implement DW_FORM_strx*. */ + static const char * +-read_indexed_string (bfd_uint64_t idx, +- struct comp_unit *unit) ++read_indexed_string (uint64_t idx, struct comp_unit *unit) + { + struct dwarf2_debug *stash = unit->stash; + struct dwarf2_debug_file *file = unit->file; +@@ -1717,39 +1714,39 @@ struct line_info_table + struct funcinfo + { + /* Pointer to previous function in list of all functions. */ +- struct funcinfo * prev_func; ++ struct funcinfo *prev_func; + /* Pointer to function one scope higher. */ +- struct funcinfo * caller_func; ++ struct funcinfo *caller_func; + /* Source location file name where caller_func inlines this func. */ +- char * caller_file; ++ char *caller_file; + /* Source location file name. */ +- char * file; ++ char *file; + /* Source location line number where caller_func inlines this func. */ +- int caller_line; ++ int caller_line; + /* Source location line number. */ +- int line; +- int tag; +- bool is_linkage; +- const char * name; +- struct arange arange; ++ int line; ++ int tag; ++ bool is_linkage; ++ const char *name; ++ struct arange arange; + /* Where the symbol is defined. */ +- asection * sec; ++ asection *sec; + /* The offset of the funcinfo from the start of the unit. */ +- bfd_uint64_t unit_offset; ++ uint64_t unit_offset; + }; + + struct lookup_funcinfo + { + /* Function information corresponding to this lookup table entry. */ +- struct funcinfo * funcinfo; ++ struct funcinfo *funcinfo; + + /* The lowest address for this specific function. */ +- bfd_vma low_addr; ++ bfd_vma low_addr; + + /* The highest address of this function before the lookup table is sorted. + The highest address of all prior functions after the lookup table is + sorted, which is used for binary search. */ +- bfd_vma high_addr; ++ bfd_vma high_addr; + /* Index of this function, used to ensure qsort is stable. */ + unsigned int idx; + }; +@@ -1759,7 +1756,7 @@ struct varinfo + /* Pointer to previous variable in list of all variables. */ + struct varinfo *prev_var; + /* The offset of the varinfo from the start of the unit. */ +- bfd_uint64_t unit_offset; ++ uint64_t unit_offset; + /* Source location file name. */ + char *file; + /* Source location line number. */ +@@ -3335,7 +3332,7 @@ find_abstract_instance (struct comp_unit *unit, + bfd_byte *info_ptr_end; + unsigned int abbrev_number, i; + struct abbrev_info *abbrev; +- bfd_uint64_t die_ref = attr_ptr->u.val; ++ uint64_t die_ref = attr_ptr->u.val; + struct attribute attr; + const char *name = NULL; + +@@ -3549,7 +3546,7 @@ find_abstract_instance (struct comp_unit *unit, + + static bool + read_ranges (struct comp_unit *unit, struct arange *arange, +- struct trie_node **trie_root, bfd_uint64_t offset) ++ struct trie_node **trie_root, uint64_t offset) + { + bfd_byte *ranges_ptr; + bfd_byte *ranges_end; +@@ -3594,7 +3591,7 @@ read_ranges (struct comp_unit *unit, struct arange *arange, + + static bool + read_rnglists (struct comp_unit *unit, struct arange *arange, +- struct trie_node **trie_root, bfd_uint64_t offset) ++ struct trie_node **trie_root, uint64_t offset) + { + bfd_byte *rngs_ptr; + bfd_byte *rngs_end; +@@ -3675,7 +3672,7 @@ read_rnglists (struct comp_unit *unit, struct arange *arange, + + static bool + read_rangelist (struct comp_unit *unit, struct arange *arange, +- struct trie_node **trie_root, bfd_uint64_t offset) ++ struct trie_node **trie_root, uint64_t offset) + { + if (unit->version <= 4) + return read_ranges (unit, arange, trie_root, offset); +@@ -3684,7 +3681,7 @@ read_rangelist (struct comp_unit *unit, struct arange *arange, + } + + static struct funcinfo * +-lookup_func_by_offset (bfd_uint64_t offset, struct funcinfo * table) ++lookup_func_by_offset (uint64_t offset, struct funcinfo * table) + { + for (; table != NULL; table = table->prev_func) + if (table->unit_offset == offset) +@@ -3693,7 +3690,7 @@ lookup_func_by_offset (bfd_uint64_t offset, struct funcinfo * table) + } + + static struct varinfo * +-lookup_var_by_offset (bfd_uint64_t offset, struct varinfo * table) ++lookup_var_by_offset (uint64_t offset, struct varinfo * table) + { + while (table) + { +@@ -3775,7 +3772,7 @@ scan_unit_for_symbols (struct comp_unit *unit) + struct abbrev_info *abbrev; + struct funcinfo *func; + struct varinfo *var; +- bfd_uint64_t current_offset; ++ uint64_t current_offset; + + /* PR 17512: file: 9f405d9d. */ + if (info_ptr >= info_ptr_end) +@@ -3909,7 +3906,7 @@ scan_unit_for_symbols (struct comp_unit *unit) + bfd_vma low_pc = 0; + bfd_vma high_pc = 0; + bool high_pc_relative = false; +- bfd_uint64_t current_offset; ++ uint64_t current_offset; + + /* PR 17512: file: 9f405d9d. */ + if (info_ptr >= info_ptr_end) +@@ -4259,7 +4256,7 @@ parse_comp_unit (struct dwarf2_debug *stash, + { + struct comp_unit* unit; + unsigned int version; +- bfd_uint64_t abbrev_offset = 0; ++ uint64_t abbrev_offset = 0; + /* Initialize it just to avoid a GCC false warning. */ + unsigned int addr_size = -1; + struct abbrev_info** abbrevs; +diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c +index c868707347c..5bc78d523ea 100644 +--- a/bfd/elf32-score.c ++++ b/bfd/elf32-score.c +@@ -230,14 +230,14 @@ static bfd_vma + score3_bfd_getl48 (const void *p) + { + const bfd_byte *addr = p; +- bfd_uint64_t v; +- +- v = (bfd_uint64_t) addr[4]; +- v |= (bfd_uint64_t) addr[5] << 8; +- v |= (bfd_uint64_t) addr[2] << 16; +- v |= (bfd_uint64_t) addr[3] << 24; +- v |= (bfd_uint64_t) addr[0] << 32; +- v |= (bfd_uint64_t) addr[1] << 40; ++ uint64_t v; ++ ++ v = (uint64_t) addr[4]; ++ v |= (uint64_t) addr[5] << 8; ++ v |= (uint64_t) addr[2] << 16; ++ v |= (uint64_t) addr[3] << 24; ++ v |= (uint64_t) addr[0] << 32; ++ v |= (uint64_t) addr[1] << 40; + return v; + } + +diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c +index 59cc6b6fe85..4d8f98550a3 100644 +--- a/bfd/elf64-ia64-vms.c ++++ b/bfd/elf64-ia64-vms.c +@@ -179,7 +179,7 @@ struct elf64_ia64_vms_obj_tdata + struct elf_obj_tdata root; + + /* Ident for shared library. */ +- bfd_uint64_t ident; ++ uint64_t ident; + + /* Used only during link: offset in the .fixups section for this bfd. */ + bfd_vma fixups_off; +@@ -2791,7 +2791,7 @@ elf64_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_IDENT, 0)) + return false; + if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_LINKTIME, +- (((bfd_uint64_t)time_hi) << 32) ++ ((uint64_t) time_hi << 32) + + time_lo)) + return false; + +@@ -4720,7 +4720,7 @@ elf64_vms_close_and_cleanup (bfd *abfd) + if ((isize & 7) != 0) + { + int ishort = 8 - (isize & 7); +- bfd_uint64_t pad = 0; ++ uint64_t pad = 0; + + bfd_seek (abfd, isize, SEEK_SET); + bfd_bwrite (&pad, ishort, abfd); +@@ -4853,7 +4853,7 @@ elf64_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) + bed->s->swap_dyn_in (abfd, extdyn, &dyn); + if (dyn.d_tag == DT_IA_64_VMS_IDENT) + { +- bfd_uint64_t tagv = dyn.d_un.d_val; ++ uint64_t tagv = dyn.d_un.d_val; + elf_ia64_vms_ident (abfd) = tagv; + break; + } +diff --git a/bfd/elflink.c b/bfd/elflink.c +index 96eb36aa5bf..fc3a335c72d 100644 +--- a/bfd/elflink.c ++++ b/bfd/elflink.c +@@ -6354,15 +6354,11 @@ compute_bucket_count (struct bfd_link_info *info ATTRIBUTE_UNUSED, + size_t best_size = 0; + unsigned long int i; + +- /* We have a problem here. The following code to optimize the table +- size requires an integer type with more the 32 bits. If +- BFD_HOST_U_64_BIT is set we know about such a type. */ +-#ifdef BFD_HOST_U_64_BIT + if (info->optimize) + { + size_t minsize; + size_t maxsize; +- BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0); ++ uint64_t best_chlen = ~((uint64_t) 0); + bfd *dynobj = elf_hash_table (info)->dynobj; + size_t dynsymcount = elf_hash_table (info)->dynsymcount; + const struct elf_backend_data *bed = get_elf_backend_data (dynobj); +@@ -6399,7 +6395,7 @@ compute_bucket_count (struct bfd_link_info *info ATTRIBUTE_UNUSED, + for (i = minsize; i < maxsize; ++i) + { + /* Walk through the array of hashcodes and count the collisions. */ +- BFD_HOST_U_64_BIT max; ++ uint64_t max; + unsigned long int j; + unsigned long int fact; + +@@ -6464,11 +6460,7 @@ compute_bucket_count (struct bfd_link_info *info ATTRIBUTE_UNUSED, + free (counts); + } + else +-#endif /* defined (BFD_HOST_U_64_BIT) */ + { +- /* This is the fallback solution if no 64bit type is available or if we +- are not supposed to spend much time on optimizations. We select the +- bucket count using a fixed set of numbers. */ + for (i = 0; elf_buckets[i] != 0; i++) + { + best_size = elf_buckets[i]; +@@ -9354,7 +9346,6 @@ ext32b_r_offset (const void *p) + return aval; + } + +-#ifdef BFD_HOST_64_BIT + static bfd_vma + ext64l_r_offset (const void *p) + { +@@ -9398,7 +9389,6 @@ ext64b_r_offset (const void *p) + | (uint64_t) a->c[7]); + return aval; + } +-#endif + + /* When performing a relocatable link, the input relocations are + preserved. But, if they reference global symbols, the indices +@@ -9502,13 +9492,11 @@ elf_link_adjust_relocs (bfd *abfd, + } + else + { +-#ifdef BFD_HOST_64_BIT + if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE) + ext_r_off = ext64l_r_offset; + else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG) + ext_r_off = ext64b_r_offset; + else +-#endif + abort (); + } + +diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c +index c126adf6890..a108324ca39 100644 +--- a/bfd/elfxx-ia64.c ++++ b/bfd/elfxx-ia64.c +@@ -555,11 +555,7 @@ ia64_elf_install_value (bfd_byte *hit_addr, bfd_vma v, unsigned int r_type) + enum ia64_opnd opnd; + const char *err; + size_t size = 8; +-#ifdef BFD_HOST_U_64_BIT +- BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v; +-#else +- bfd_vma val = v; +-#endif ++ uint64_t val = v; + + opnd = IA64_OPND_NIL; + switch (r_type) +diff --git a/bfd/hppabsd-core.c b/bfd/hppabsd-core.c +index acfa5f69a95..d87af955838 100644 +--- a/bfd/hppabsd-core.c ++++ b/bfd/hppabsd-core.c +@@ -213,9 +213,9 @@ swap_abort (void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_hppabsd_vec = + { +diff --git a/bfd/hpux-core.c b/bfd/hpux-core.c +index 4f03b84909a..654532c6bb9 100644 +--- a/bfd/hpux-core.c ++++ b/bfd/hpux-core.c +@@ -362,9 +362,9 @@ swap_abort (void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_hpux_vec = + { +diff --git a/bfd/irix-core.c b/bfd/irix-core.c +index 694fe2e2e07..b12aef9ce8b 100644 +--- a/bfd/irix-core.c ++++ b/bfd/irix-core.c +@@ -275,9 +275,9 @@ swap_abort(void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_irix_vec = + { +diff --git a/bfd/libbfd.c b/bfd/libbfd.c +index 2781671ddba..d33f3416206 100644 +--- a/bfd/libbfd.c ++++ b/bfd/libbfd.c +@@ -617,7 +617,7 @@ DESCRIPTION + #define COERCE16(x) (((bfd_vma) (x) ^ 0x8000) - 0x8000) + #define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000) + #define COERCE64(x) \ +- (((bfd_uint64_t) (x) ^ ((bfd_uint64_t) 1 << 63)) - ((bfd_uint64_t) 1 << 63)) ++ (((uint64_t) (x) ^ ((uint64_t) 1 << 63)) - ((uint64_t) 1 << 63)) + + bfd_vma + bfd_getb16 (const void *p) +@@ -757,12 +757,11 @@ bfd_getl_signed_32 (const void *p) + return COERCE32 (v); + } + +-bfd_uint64_t +-bfd_getb64 (const void *p ATTRIBUTE_UNUSED) ++uint64_t ++bfd_getb64 (const void *p) + { +-#ifdef BFD_HOST_64_BIT + const bfd_byte *addr = (const bfd_byte *) p; +- bfd_uint64_t v; ++ uint64_t v; + + v = addr[0]; v <<= 8; + v |= addr[1]; v <<= 8; +@@ -774,18 +773,13 @@ bfd_getb64 (const void *p ATTRIBUTE_UNUSED) + v |= addr[7]; + + return v; +-#else +- BFD_FAIL(); +- return 0; +-#endif + } + +-bfd_uint64_t +-bfd_getl64 (const void *p ATTRIBUTE_UNUSED) ++uint64_t ++bfd_getl64 (const void *p) + { +-#ifdef BFD_HOST_64_BIT + const bfd_byte *addr = (const bfd_byte *) p; +- bfd_uint64_t v; ++ uint64_t v; + + v = addr[7]; v <<= 8; + v |= addr[6]; v <<= 8; +@@ -797,19 +791,13 @@ bfd_getl64 (const void *p ATTRIBUTE_UNUSED) + v |= addr[0]; + + return v; +-#else +- BFD_FAIL(); +- return 0; +-#endif +- + } + +-bfd_int64_t +-bfd_getb_signed_64 (const void *p ATTRIBUTE_UNUSED) ++int64_t ++bfd_getb_signed_64 (const void *p) + { +-#ifdef BFD_HOST_64_BIT + const bfd_byte *addr = (const bfd_byte *) p; +- bfd_uint64_t v; ++ uint64_t v; + + v = addr[0]; v <<= 8; + v |= addr[1]; v <<= 8; +@@ -821,18 +809,13 @@ bfd_getb_signed_64 (const void *p ATTRIBUTE_UNUSED) + v |= addr[7]; + + return COERCE64 (v); +-#else +- BFD_FAIL(); +- return 0; +-#endif + } + +-bfd_int64_t +-bfd_getl_signed_64 (const void *p ATTRIBUTE_UNUSED) ++int64_t ++bfd_getl_signed_64 (const void *p) + { +-#ifdef BFD_HOST_64_BIT + const bfd_byte *addr = (const bfd_byte *) p; +- bfd_uint64_t v; ++ uint64_t v; + + v = addr[7]; v <<= 8; + v |= addr[6]; v <<= 8; +@@ -844,10 +827,6 @@ bfd_getl_signed_64 (const void *p ATTRIBUTE_UNUSED) + v |= addr[0]; + + return COERCE64 (v); +-#else +- BFD_FAIL(); +- return 0; +-#endif + } + + void +@@ -871,9 +850,8 @@ bfd_putl32 (bfd_vma data, void *p) + } + + void +-bfd_putb64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED) ++bfd_putb64 (uint64_t data, void *p) + { +-#ifdef BFD_HOST_64_BIT + bfd_byte *addr = (bfd_byte *) p; + addr[0] = (data >> (7*8)) & 0xff; + addr[1] = (data >> (6*8)) & 0xff; +@@ -883,15 +861,11 @@ bfd_putb64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED) + addr[5] = (data >> (2*8)) & 0xff; + addr[6] = (data >> (1*8)) & 0xff; + addr[7] = (data >> (0*8)) & 0xff; +-#else +- BFD_FAIL(); +-#endif + } + + void +-bfd_putl64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED) ++bfd_putl64 (uint64_t data, void *p) + { +-#ifdef BFD_HOST_64_BIT + bfd_byte *addr = (bfd_byte *) p; + addr[7] = (data >> (7*8)) & 0xff; + addr[6] = (data >> (6*8)) & 0xff; +@@ -901,13 +875,10 @@ bfd_putl64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED) + addr[2] = (data >> (2*8)) & 0xff; + addr[1] = (data >> (1*8)) & 0xff; + addr[0] = (data >> (0*8)) & 0xff; +-#else +- BFD_FAIL(); +-#endif + } + + void +-bfd_put_bits (bfd_uint64_t data, void *p, int bits, bool big_p) ++bfd_put_bits (uint64_t data, void *p, int bits, bool big_p) + { + bfd_byte *addr = (bfd_byte *) p; + int i; +@@ -926,11 +897,11 @@ bfd_put_bits (bfd_uint64_t data, void *p, int bits, bool big_p) + } + } + +-bfd_uint64_t ++uint64_t + bfd_get_bits (const void *p, int bits, bool big_p) + { + const bfd_byte *addr = (const bfd_byte *) p; +- bfd_uint64_t data; ++ uint64_t data; + int i; + int bytes; + +diff --git a/bfd/mach-o.c b/bfd/mach-o.c +index e32b7873cef..9f3f1f13e4e 100644 +--- a/bfd/mach-o.c ++++ b/bfd/mach-o.c +@@ -4773,7 +4773,7 @@ bfd_mach_o_read_source_version (bfd *abfd, bfd_mach_o_load_command *command) + { + bfd_mach_o_source_version_command *cmd = &command->command.source_version; + struct mach_o_source_version_command_external raw; +- bfd_uint64_t ver; ++ uint64_t ver; + + if (command->len < sizeof (raw) + 8) + return false; +diff --git a/bfd/mach-o.h b/bfd/mach-o.h +index 5a068d8d970..f7418ad8d40 100644 +--- a/bfd/mach-o.h ++++ b/bfd/mach-o.h +@@ -545,8 +545,8 @@ bfd_mach_o_encryption_info_command; + + typedef struct bfd_mach_o_main_command + { +- bfd_uint64_t entryoff; +- bfd_uint64_t stacksize; ++ uint64_t entryoff; ++ uint64_t stacksize; + } + bfd_mach_o_main_command; + +@@ -563,8 +563,8 @@ bfd_mach_o_source_version_command; + typedef struct bfd_mach_o_note_command + { + char data_owner[16]; +- bfd_uint64_t offset; +- bfd_uint64_t size; ++ uint64_t offset; ++ uint64_t size; + } + bfd_mach_o_note_command; + +diff --git a/bfd/netbsd-core.c b/bfd/netbsd-core.c +index cb215937da6..ffc8e50842c 100644 +--- a/bfd/netbsd-core.c ++++ b/bfd/netbsd-core.c +@@ -257,9 +257,9 @@ swap_abort (void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_netbsd_vec = + { +diff --git a/bfd/osf-core.c b/bfd/osf-core.c +index 09a04a07624..04434b2045c 100644 +--- a/bfd/osf-core.c ++++ b/bfd/osf-core.c +@@ -169,9 +169,9 @@ swap_abort (void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_osf_vec = + { +diff --git a/bfd/ptrace-core.c b/bfd/ptrace-core.c +index 3d077d21200..c4afffbfb95 100644 +--- a/bfd/ptrace-core.c ++++ b/bfd/ptrace-core.c +@@ -160,9 +160,9 @@ swap_abort (void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_ptrace_vec = + { +diff --git a/bfd/sco5-core.c b/bfd/sco5-core.c +index d1f80c9079f..7807ac86a65 100644 +--- a/bfd/sco5-core.c ++++ b/bfd/sco5-core.c +@@ -340,9 +340,9 @@ swap_abort (void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_sco5_vec = + { +diff --git a/bfd/targets.c b/bfd/targets.c +index 05dd8236d91..f44b5c67724 100644 +--- a/bfd/targets.c ++++ b/bfd/targets.c +@@ -226,9 +226,9 @@ DESCRIPTION + . {* Entries for byte swapping for data. These are different from the + . other entry points, since they don't take a BFD as the first argument. + . Certain other handlers could do the same. *} +-. bfd_uint64_t (*bfd_getx64) (const void *); +-. bfd_int64_t (*bfd_getx_signed_64) (const void *); +-. void (*bfd_putx64) (bfd_uint64_t, void *); ++. uint64_t (*bfd_getx64) (const void *); ++. int64_t (*bfd_getx_signed_64) (const void *); ++. void (*bfd_putx64) (uint64_t, void *); + . bfd_vma (*bfd_getx32) (const void *); + . bfd_signed_vma (*bfd_getx_signed_32) (const void *); + . void (*bfd_putx32) (bfd_vma, void *); +@@ -237,9 +237,9 @@ DESCRIPTION + . void (*bfd_putx16) (bfd_vma, void *); + . + . {* Byte swapping for the headers. *} +-. bfd_uint64_t (*bfd_h_getx64) (const void *); +-. bfd_int64_t (*bfd_h_getx_signed_64) (const void *); +-. void (*bfd_h_putx64) (bfd_uint64_t, void *); ++. uint64_t (*bfd_h_getx64) (const void *); ++. int64_t (*bfd_h_getx_signed_64) (const void *); ++. void (*bfd_h_putx64) (uint64_t, void *); + . bfd_vma (*bfd_h_getx32) (const void *); + . bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); + . void (*bfd_h_putx32) (bfd_vma, void *); +diff --git a/bfd/trad-core.c b/bfd/trad-core.c +index 92a279b6a72..8e9ee0d6667 100644 +--- a/bfd/trad-core.c ++++ b/bfd/trad-core.c +@@ -249,9 +249,9 @@ swap_abort (void) + #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) + #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) + #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) +-#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) +-#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) +-#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) ++#define NO_GET64 ((uint64_t (*) (const void *)) swap_abort) ++#define NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort) ++#define NO_GETS64 ((int64_t (*) (const void *)) swap_abort) + + const bfd_target core_trad_vec = + { +diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c +index 1129c98f0e2..fd0762811df 100644 +--- a/bfd/vms-alpha.c ++++ b/bfd/vms-alpha.c +@@ -522,7 +522,7 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) + struct vms_eisd *eisd; + unsigned int rec_size; + unsigned int size; +- bfd_uint64_t vaddr; ++ uint64_t vaddr; + unsigned int flags; + unsigned int vbn; + char *name = NULL; +diff --git a/binutils/nm.c b/binutils/nm.c +index 60e4d850885..539c5688425 100644 +--- a/binutils/nm.c ++++ b/binutils/nm.c +@@ -1557,29 +1557,15 @@ get_print_format (void) + padding = "016"; + } + +- const char * length = "l"; +- if (print_width == 64) +- { +-#if BFD_HOST_64BIT_LONG +- ; +-#elif BFD_HOST_64BIT_LONG_LONG +-#ifndef __MSVCRT__ +- length = "ll"; +-#else +- length = "I64"; +-#endif +-#endif +- } +- + const char * radix = NULL; + switch (print_radix) + { +- case 8: radix = "o"; break; +- case 10: radix = "d"; break; +- case 16: radix = "x"; break; ++ case 8: radix = PRIo64; break; ++ case 10: radix = PRId64; break; ++ case 16: radix = PRIx64; break; + } + +- return concat ("%", padding, length, radix, NULL); ++ return concat ("%", padding, radix, NULL); + } + + static void +@@ -1874,33 +1860,8 @@ print_value (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma val) + switch (print_width) + { + case 32: +- printf (print_format_string, (unsigned long) val); +- break; +- + case 64: +-#if BFD_HOST_64BIT_LONG || BFD_HOST_64BIT_LONG_LONG +- printf (print_format_string, val); +-#else +- /* We have a 64 bit value to print, but the host is only 32 bit. */ +- if (print_radix == 16) +- bfd_fprintf_vma (abfd, stdout, val); +- else +- { +- char buf[30]; +- char *s; +- +- s = buf + sizeof buf; +- *--s = '\0'; +- while (val > 0) +- { +- *--s = (val % print_radix) + '0'; +- val /= print_radix; +- } +- while ((buf + sizeof buf - 1) - s < 16) +- *--s = '0'; +- printf ("%s", s); +- } +-#endif ++ printf (print_format_string, (uint64_t) val); + break; + + default: +diff --git a/binutils/od-macho.c b/binutils/od-macho.c +index 56d448ac3bd..e91c87d2acf 100644 +--- a/binutils/od-macho.c ++++ b/binutils/od-macho.c +@@ -283,15 +283,6 @@ bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table, + printf ("-"); + } + +-/* Print a bfd_uint64_t, using a platform independent style. */ +- +-static void +-printf_uint64 (bfd_uint64_t v) +-{ +- printf ("0x%08lx%08lx", +- (unsigned long)((v >> 16) >> 16), (unsigned long)(v & 0xffffffffUL)); +-} +- + static const char * + bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table, + unsigned long val) +@@ -1729,26 +1720,20 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd, + } + case BFD_MACH_O_LC_MAIN: + { +- bfd_mach_o_main_command *entry = &cmd->command.main; +- printf (" entry offset: "); +- printf_uint64 (entry->entryoff); +- printf ("\n" +- " stack size: "); +- printf_uint64 (entry->stacksize); +- printf ("\n"); +- break; ++ bfd_mach_o_main_command *entry = &cmd->command.main; ++ printf (" entry offset: %#016" PRIx64 "\n" ++ " stack size: %#016" PRIx64 "\n", ++ entry->entryoff, entry->stacksize); ++ break; + } + case BFD_MACH_O_LC_NOTE: + { +- bfd_mach_o_note_command *note = &cmd->command.note; +- printf (" data owner: %.16s\n", note->data_owner); +- printf (" offset: "); +- printf_uint64 (note->offset); +- printf ("\n" +- " size: "); +- printf_uint64 (note->size); +- printf ("\n"); +- break; ++ bfd_mach_o_note_command *note = &cmd->command.note; ++ printf (" data owner: %.16s\n" ++ " offset: %#016" PRIx64 "\n" ++ " size: %#016" PRIx64 "\n", ++ note->data_owner, note->offset, note->size); ++ break; + } + case BFD_MACH_O_LC_BUILD_VERSION: + dump_build_version (abfd, cmd); +@@ -2013,14 +1998,11 @@ dump_obj_compact_unwind (bfd *abfd, + { + e = (struct mach_o_compact_unwind_64 *) p; + +- putchar (' '); +- printf_uint64 (bfd_get_64 (abfd, e->start)); +- printf (" %08lx", (unsigned long)bfd_get_32 (abfd, e->length)); +- putchar (' '); +- printf_uint64 (bfd_get_64 (abfd, e->personality)); +- putchar (' '); +- printf_uint64 (bfd_get_64 (abfd, e->lsda)); +- putchar ('\n'); ++ printf (" %#016" PRIx64 " %#08x %#016" PRIx64 " %#016" PRIx64 "\n", ++ (uint64_t) bfd_get_64 (abfd, e->start), ++ (unsigned int) bfd_get_32 (abfd, e->length), ++ (uint64_t) bfd_get_64 (abfd, e->personality), ++ (uint64_t) bfd_get_64 (abfd, e->lsda)); + + printf (" encoding: "); + dump_unwind_encoding (mdata, bfd_get_32 (abfd, e->encoding)); +diff --git a/binutils/prdbg.c b/binutils/prdbg.c +index d6cbab8578b..c1e41628d26 100644 +--- a/binutils/prdbg.c ++++ b/binutils/prdbg.c +@@ -485,41 +485,12 @@ pop_type (struct pr_handle *info) + static void + print_vma (bfd_vma vma, char *buf, bool unsignedp, bool hexp) + { +- if (sizeof (vma) <= sizeof (unsigned long)) +- { +- if (hexp) +- sprintf (buf, "0x%lx", (unsigned long) vma); +- else if (unsignedp) +- sprintf (buf, "%lu", (unsigned long) vma); +- else +- sprintf (buf, "%ld", (long) vma); +- } +-#if BFD_HOST_64BIT_LONG_LONG +- else if (sizeof (vma) <= sizeof (unsigned long long)) +- { +-#ifndef __MSVCRT__ +- if (hexp) +- sprintf (buf, "0x%llx", (unsigned long long) vma); +- else if (unsignedp) +- sprintf (buf, "%llu", (unsigned long long) vma); +- else +- sprintf (buf, "%lld", (long long) vma); +-#else +- if (hexp) +- sprintf (buf, "0x%I64x", (unsigned long long) vma); +- else if (unsignedp) +- sprintf (buf, "%I64u", (unsigned long long) vma); +- else +- sprintf (buf, "%I64d", (long long) vma); +-#endif +- } +-#endif ++ if (hexp) ++ sprintf (buf, "%#" PRIx64, (uint64_t) vma); ++ else if (unsignedp) ++ sprintf (buf, "%" PRIu64, (uint64_t) vma); + else +- { +- buf[0] = '0'; +- buf[1] = 'x'; +- sprintf_vma (buf + 2, vma); +- } ++ sprintf (buf, "%" PRId64, (int64_t) vma); + } + + /* Start a new compilation unit. */ +diff --git a/binutils/readelf.c b/binutils/readelf.c +index c35bfc12366..4c0a2a34767 100644 +--- a/binutils/readelf.c ++++ b/binutils/readelf.c +@@ -10729,7 +10729,7 @@ dynamic_section_parisc_val (Elf_Internal_Dyn * entry) + /* Display a VMS time in a human readable format. */ + + static void +-print_vms_time (bfd_int64_t vmstime) ++print_vms_time (int64_t vmstime) + { + struct tm *tm = NULL; + time_t unxtime; +@@ -20764,7 +20764,7 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) + /* FIXME: Generate an error if descsz > 8 ? */ + + printf ("0x%016" BFD_VMA_FMT "x\n", +- (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8)); ++ (bfd_vma) byte_get ((unsigned char *) pnote->descdata, 8)); + break; + + case NT_VMS_LINKTIME: +@@ -20773,8 +20773,7 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) + goto desc_size_fail; + /* FIXME: Generate an error if descsz > 8 ? */ + +- print_vms_time +- ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8)); ++ print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8)); + printf ("\n"); + break; + +@@ -20784,8 +20783,7 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) + goto desc_size_fail; + /* FIXME: Generate an error if descsz > 8 ? */ + +- print_vms_time +- ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8)); ++ print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8)); + printf ("\n"); + break; + +@@ -20794,16 +20792,15 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) + goto desc_size_fail; + + printf (_(" Major id: %u, minor id: %u\n"), +- (unsigned) byte_get ((unsigned char *)pnote->descdata, 4), +- (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4)); ++ (unsigned) byte_get ((unsigned char *) pnote->descdata, 4), ++ (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4)); + printf (_(" Last modified : ")); +- print_vms_time +- ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8)); ++ print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8)); + printf (_("\n Link flags : ")); + printf ("0x%016" BFD_VMA_FMT "x\n", +- (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8)); ++ (bfd_vma) byte_get ((unsigned char *) pnote->descdata + 16, 8)); + printf (_(" Header flags: 0x%08x\n"), +- (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4)); ++ (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4)); + printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32); + break; + #endif +diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c +index 1721097cfca..2e6d175482e 100644 +--- a/gas/config/tc-arm.c ++++ b/gas/config/tc-arm.c +@@ -3565,7 +3565,7 @@ add_to_lit_pool (unsigned int nbytes) + imm1 = inst.operands[1].imm; + imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg + : inst.relocs[0].exp.X_unsigned ? 0 +- : ((bfd_int64_t) inst.operands[1].imm) >> 32); ++ : (int64_t) inst.operands[1].imm >> 32); + if (target_big_endian) + { + imm1 = imm2; +@@ -8819,15 +8819,14 @@ neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p, + return FAIL; + } + +-#if defined BFD_HOST_64_BIT + /* Returns TRUE if double precision value V may be cast + to single precision without loss of accuracy. */ + + static bool +-is_double_a_single (bfd_uint64_t v) ++is_double_a_single (uint64_t v) + { + int exp = (v >> 52) & 0x7FF; +- bfd_uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL; ++ uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL; + + return ((exp == 0 || exp == 0x7FF + || (exp >= 1023 - 126 && exp <= 1023 + 127)) +@@ -8838,11 +8837,11 @@ is_double_a_single (bfd_uint64_t v) + (ignoring the least significant bits in exponent and mantissa). */ + + static int +-double_to_single (bfd_uint64_t v) ++double_to_single (uint64_t v) + { + unsigned int sign = (v >> 63) & 1; + int exp = (v >> 52) & 0x7FF; +- bfd_uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL; ++ uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL; + + if (exp == 0x7FF) + exp = 0xFF; +@@ -8865,7 +8864,6 @@ double_to_single (bfd_uint64_t v) + mantissa >>= 29; + return (sign << 31) | (exp << 23) | mantissa; + } +-#endif /* BFD_HOST_64_BIT */ + + enum lit_type + { +@@ -8914,11 +8912,7 @@ move_or_literal_pool (int i, enum lit_type t, bool mode_3) + if (inst.relocs[0].exp.X_op == O_constant + || inst.relocs[0].exp.X_op == O_big) + { +-#if defined BFD_HOST_64_BIT +- bfd_uint64_t v; +-#else +- valueT v; +-#endif ++ uint64_t v; + if (inst.relocs[0].exp.X_op == O_big) + { + LITTLENUM_TYPE w[X_PRECISION]; +@@ -8933,7 +8927,6 @@ move_or_literal_pool (int i, enum lit_type t, bool mode_3) + else + l = generic_bignum; + +-#if defined BFD_HOST_64_BIT + v = l[3] & LITTLENUM_MASK; + v <<= LITTLENUM_NUMBER_OF_BITS; + v |= l[2] & LITTLENUM_MASK; +@@ -8941,11 +8934,6 @@ move_or_literal_pool (int i, enum lit_type t, bool mode_3) + v |= l[1] & LITTLENUM_MASK; + v <<= LITTLENUM_NUMBER_OF_BITS; + v |= l[0] & LITTLENUM_MASK; +-#else +- v = l[1] & LITTLENUM_MASK; +- v <<= LITTLENUM_NUMBER_OF_BITS; +- v |= l[0] & LITTLENUM_MASK; +-#endif + } + else + v = inst.relocs[0].exp.X_add_number; +@@ -9041,7 +9029,7 @@ move_or_literal_pool (int i, enum lit_type t, bool mode_3) + ? inst.operands[1].reg + : inst.relocs[0].exp.X_unsigned + ? 0 +- : ((bfd_int64_t)((int) immlo)) >> 32; ++ : (int64_t) (int) immlo >> 32; + int cmode = neon_cmode_for_move_imm (immlo, immhi, false, &immbits, + &op, 64, NT_invtype); + +@@ -9090,7 +9078,6 @@ move_or_literal_pool (int i, enum lit_type t, bool mode_3) + discrepancy between the output produced by an assembler built for + a 32-bit-only host and the output produced from a 64-bit host, but + this cannot be helped. */ +-#if defined BFD_HOST_64_BIT + else if (!inst.operands[1].issingle + && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3)) + { +@@ -9103,7 +9090,6 @@ move_or_literal_pool (int i, enum lit_type t, bool mode_3) + return true; + } + } +-#endif + } + } + +diff --git a/gas/config/tc-csky.c b/gas/config/tc-csky.c +index 2371eeb747e..5b824d89af0 100644 +--- a/gas/config/tc-csky.c ++++ b/gas/config/tc-csky.c +@@ -215,7 +215,7 @@ enum + unsigned int mach_flag = 0; + unsigned int arch_flag = 0; + unsigned int other_flag = 0; +-BFD_HOST_U_64_BIT isa_flag = 0; ++uint64_t isa_flag = 0; + unsigned int dsp_flag = 0; + + typedef struct stack_size_entry +@@ -245,7 +245,7 @@ struct csky_macro_info + const char *name; + /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */ + long oprnd_num; +- BFD_HOST_U_64_BIT isa_flag; ++ uint64_t isa_flag; + /* Do the work. */ + void (*handle_func)(void); + }; +@@ -591,14 +591,14 @@ struct csky_cpu_feature + { + const char unique; + unsigned int arch_flag; +- bfd_uint64_t isa_flag; ++ uint64_t isa_flag; + }; + + struct csky_cpu_version + { + int r; + int p; +- bfd_uint64_t isa_flag; ++ uint64_t isa_flag; + }; + + #define CSKY_FEATURE_MAX 10 +@@ -608,7 +608,7 @@ struct csky_cpu_info + { + const char *name; + unsigned int arch_flag; +- bfd_uint64_t isa_flag; ++ uint64_t isa_flag; + struct csky_cpu_feature features[CSKY_FEATURE_MAX]; + struct csky_cpu_version ver[CSKY_CPU_REVERISON_MAX]; + }; +diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c +index 222223f3549..4e443b1d28d 100644 +--- a/gas/config/tc-sparc.c ++++ b/gas/config/tc-sparc.c +@@ -75,10 +75,10 @@ static enum { MM_TSO, MM_PSO, MM_RMO } sparc_memory_model = MM_RMO; + #ifndef TE_SOLARIS + /* Bitmask of instruction types seen so far, used to populate the + GNU attributes section with hwcap information. */ +-static bfd_uint64_t hwcap_seen; ++static uint64_t hwcap_seen; + #endif + +-static bfd_uint64_t hwcap_allowed; ++static uint64_t hwcap_allowed; + + static int architecture_requested; + static int warn_on_bump; +@@ -498,15 +498,15 @@ md_parse_option (int c, const char *arg) + || opcode_arch > max_architecture) + max_architecture = opcode_arch; + +- /* The allowed hardware capabilities are the implied by the +- opcodes arch plus any extra capabilities defined in the GAS +- arch. */ +- hwcap_allowed +- = (hwcap_allowed +- | (((bfd_uint64_t) sparc_opcode_archs[opcode_arch].hwcaps2) << 32) +- | (((bfd_uint64_t) sa->hwcap2_allowed) << 32) +- | sparc_opcode_archs[opcode_arch].hwcaps +- | sa->hwcap_allowed); ++ /* The allowed hardware capabilities are the implied by the ++ opcodes arch plus any extra capabilities defined in the GAS ++ arch. */ ++ hwcap_allowed ++ = (hwcap_allowed ++ | ((uint64_t) sparc_opcode_archs[opcode_arch].hwcaps2 << 32) ++ | ((uint64_t) sa->hwcap2_allowed << 32) ++ | sparc_opcode_archs[opcode_arch].hwcaps ++ | sa->hwcap_allowed); + architecture_requested = 1; + } + break; +@@ -1607,7 +1607,7 @@ md_assemble (char *str) + } + + static const char * +-get_hwcap_name (bfd_uint64_t mask) ++get_hwcap_name (uint64_t mask) + { + if (mask & HWCAP_MUL32) + return "mul32"; +@@ -3171,8 +3171,7 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn) + msg_str = sasi->name; + } + +- bfd_uint64_t hwcaps +- = (((bfd_uint64_t) insn->hwcaps2) << 32) | insn->hwcaps; ++ uint64_t hwcaps = ((uint64_t) insn->hwcaps2 << 32) | insn->hwcaps; + + #ifndef TE_SOLARIS + if (hwcaps) +@@ -3211,10 +3210,10 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn) + } + current_architecture = needed_architecture; + hwcap_allowed +- = (hwcap_allowed +- | hwcaps +- | (((bfd_uint64_t) sparc_opcode_archs[current_architecture].hwcaps2) << 32) +- | sparc_opcode_archs[current_architecture].hwcaps); ++ = (hwcap_allowed ++ | hwcaps ++ | ((uint64_t) sparc_opcode_archs[current_architecture].hwcaps2 << 32) ++ | sparc_opcode_archs[current_architecture].hwcaps); + } + /* Conflict. */ + /* ??? This seems to be a bit fragile. What if the next entry in +diff --git a/gas/config/tc-tilegx.c b/gas/config/tc-tilegx.c +index b627b7080e5..4fcc38c9034 100644 +--- a/gas/config/tc-tilegx.c ++++ b/gas/config/tc-tilegx.c +@@ -789,16 +789,16 @@ emit_tilegx_instruction (tilegx_bundle_bits bits, + static void + check_illegal_reg_writes (void) + { +- BFD_HOST_U_64_BIT all_regs_written = 0; ++ uint64_t all_regs_written = 0; + int j; + + for (j = 0; j < current_bundle_index; j++) + { + const struct tilegx_instruction *instr = ¤t_bundle[j]; + int k; +- BFD_HOST_U_64_BIT regs = +- ((BFD_HOST_U_64_BIT)1) << instr->opcode->implicitly_written_register; +- BFD_HOST_U_64_BIT conflict; ++ uint64_t regs = ++ (uint64_t) 1 << instr->opcode->implicitly_written_register; ++ uint64_t conflict; + + for (k = 0; k < instr->opcode->num_operands; k++) + { +@@ -808,12 +808,12 @@ check_illegal_reg_writes (void) + if (operand->is_dest_reg) + { + int regno = instr->operand_values[k].X_add_number; +- BFD_HOST_U_64_BIT mask = ((BFD_HOST_U_64_BIT)1) << regno; ++ uint64_t mask = (uint64_t) 1 << regno; + +- if ((mask & ( (((BFD_HOST_U_64_BIT)1) << TREG_IDN1) +- | (((BFD_HOST_U_64_BIT)1) << TREG_UDN1) +- | (((BFD_HOST_U_64_BIT)1) << TREG_UDN2) +- | (((BFD_HOST_U_64_BIT)1) << TREG_UDN3))) != 0 ++ if ((mask & ( ((uint64_t) 1 << TREG_IDN1) ++ | ((uint64_t) 1 << TREG_UDN1) ++ | ((uint64_t) 1 << TREG_UDN2) ++ | ((uint64_t) 1 << TREG_UDN3))) != 0 + && !allow_suspicious_bundles) + { + as_bad (_("Writes to register '%s' are not allowed."), +@@ -825,7 +825,7 @@ check_illegal_reg_writes (void) + } + + /* Writing to the zero register doesn't count. */ +- regs &= ~(((BFD_HOST_U_64_BIT)1) << TREG_ZERO); ++ regs &= ~((uint64_t) 1 << TREG_ZERO); + + conflict = all_regs_written & regs; + if (conflict != 0 && !allow_suspicious_bundles) +diff --git a/gas/config/tc-tilepro.c b/gas/config/tc-tilepro.c +index af0be422f98..ca092d77a4b 100644 +--- a/gas/config/tc-tilepro.c ++++ b/gas/config/tc-tilepro.c +@@ -677,16 +677,16 @@ emit_tilepro_instruction (tilepro_bundle_bits bits, + static void + check_illegal_reg_writes (void) + { +- BFD_HOST_U_64_BIT all_regs_written = 0; ++ uint64_t all_regs_written = 0; + int j; + + for (j = 0; j < current_bundle_index; j++) + { + const struct tilepro_instruction *instr = ¤t_bundle[j]; + int k; +- BFD_HOST_U_64_BIT regs = +- ((BFD_HOST_U_64_BIT)1) << instr->opcode->implicitly_written_register; +- BFD_HOST_U_64_BIT conflict; ++ uint64_t regs = ++ (uint64_t) 1 << instr->opcode->implicitly_written_register; ++ uint64_t conflict; + + for (k = 0; k < instr->opcode->num_operands; k++) + { +@@ -696,12 +696,12 @@ check_illegal_reg_writes (void) + if (operand->is_dest_reg) + { + int regno = instr->operand_values[k].X_add_number; +- BFD_HOST_U_64_BIT mask = ((BFD_HOST_U_64_BIT)1) << regno; ++ uint64_t mask = (uint64_t) 1 << regno; + +- if ((mask & ( (((BFD_HOST_U_64_BIT)1) << TREG_IDN1) +- | (((BFD_HOST_U_64_BIT)1) << TREG_UDN1) +- | (((BFD_HOST_U_64_BIT)1) << TREG_UDN2) +- | (((BFD_HOST_U_64_BIT)1) << TREG_UDN3))) != 0 ++ if ((mask & ( ((uint64_t) 1 << TREG_IDN1) ++ | ((uint64_t) 1 << TREG_UDN1) ++ | ((uint64_t) 1 << TREG_UDN2) ++ | ((uint64_t) 1 << TREG_UDN3))) != 0 + && !allow_suspicious_bundles) + { + as_bad (_("Writes to register '%s' are not allowed."), +@@ -713,7 +713,7 @@ check_illegal_reg_writes (void) + } + + /* Writing to the zero register doesn't count. */ +- regs &= ~(((BFD_HOST_U_64_BIT)1) << TREG_ZERO); ++ regs &= ~((uint64_t) 1 << TREG_ZERO); + + conflict = all_regs_written & regs; + if (conflict != 0 && !allow_suspicious_bundles) +diff --git a/gas/config/tc-z80.c b/gas/config/tc-z80.c +index 81fbfe3b0ae..714e704e24a 100644 +--- a/gas/config/tc-z80.c ++++ b/gas/config/tc-z80.c +@@ -3910,11 +3910,11 @@ z80_tc_label_is_local (const char *name) + #define EXP_MIN -0x10000 + #define EXP_MAX 0x10000 + static int +-str_to_broken_float (bool *signP, bfd_uint64_t *mantissaP, int *expP) ++str_to_broken_float (bool *signP, uint64_t *mantissaP, int *expP) + { + char *p; + bool sign; +- bfd_uint64_t mantissa = 0; ++ uint64_t mantissa = 0; + int exponent = 0; + int i; + +@@ -4029,7 +4029,7 @@ str_to_broken_float (bool *signP, bfd_uint64_t *mantissaP, int *expP) + static const char * + str_to_zeda32(char *litP, int *sizeP) + { +- bfd_uint64_t mantissa; ++ uint64_t mantissa; + bool sign; + int exponent; + unsigned i; +@@ -4088,7 +4088,7 @@ str_to_zeda32(char *litP, int *sizeP) + static const char * + str_to_float48(char *litP, int *sizeP) + { +- bfd_uint64_t mantissa; ++ uint64_t mantissa; + bool sign; + int exponent; + unsigned i; +diff --git a/gas/config/te-vms.c b/gas/config/te-vms.c +index 015c95867f0..6661a3b6a72 100644 +--- a/gas/config/te-vms.c ++++ b/gas/config/te-vms.c +@@ -339,7 +339,7 @@ vms_file_stats_name (const char *dirname, + return 0; + } + +-bfd_uint64_t ++uint64_t + vms_dwarf2_file_time_name (const char *filename, const char *dirname) + { + long long cdt; +diff --git a/gas/config/te-vms.h b/gas/config/te-vms.h +index ffe7f5e8f37..08f218502de 100644 +--- a/gas/config/te-vms.h ++++ b/gas/config/te-vms.h +@@ -20,7 +20,7 @@ + #define TE_VMS + #include "obj-format.h" + +-extern bfd_uint64_t vms_dwarf2_file_time_name (const char *, const char *); ++extern uint64_t vms_dwarf2_file_time_name (const char *, const char *); + extern long vms_dwarf2_file_size_name (const char *, const char *); + extern char *vms_dwarf2_file_name (const char *, const char *); + +diff --git a/gdb/findcmd.c b/gdb/findcmd.c +index ff13f22e970..ed2cea7b74d 100644 +--- a/gdb/findcmd.c ++++ b/gdb/findcmd.c +@@ -30,7 +30,7 @@ + /* Copied from bfd_put_bits. */ + + static void +-put_bits (bfd_uint64_t data, gdb::byte_vector &buf, int bits, bfd_boolean big_p) ++put_bits (uint64_t data, gdb::byte_vector &buf, int bits, bfd_boolean big_p) + { + int i; + int bytes; +diff --git a/gdb/tilegx-tdep.c b/gdb/tilegx-tdep.c +index 7930db72779..9668aa80b53 100644 +--- a/gdb/tilegx-tdep.c ++++ b/gdb/tilegx-tdep.c +@@ -375,7 +375,7 @@ tilegx_analyze_prologue (struct gdbarch* gdbarch, + CORE_ADDR instbuf_start; + unsigned int instbuf_size; + int status; +- bfd_uint64_t bundle; ++ uint64_t bundle; + struct tilegx_decoded_instruction + decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; + int num_insns; +diff --git a/gprof/gmon_io.c b/gprof/gmon_io.c +index c613809d396..2b4dd26375b 100644 +--- a/gprof/gmon_io.c ++++ b/gprof/gmon_io.c +@@ -48,10 +48,8 @@ enum gmon_ptr_signedness { + static enum gmon_ptr_size gmon_get_ptr_size (void); + static enum gmon_ptr_signedness gmon_get_ptr_signedness (void); + +-#ifdef BFD_HOST_U_64_BIT +-static int gmon_io_read_64 (FILE *, BFD_HOST_U_64_BIT *); +-static int gmon_io_write_64 (FILE *, BFD_HOST_U_64_BIT); +-#endif ++static int gmon_io_read_64 (FILE *, uint64_t *); ++static int gmon_io_write_64 (FILE *, uint64_t); + static int gmon_read_raw_arc + (FILE *, bfd_vma *, bfd_vma *, unsigned long *); + static int gmon_write_raw_arc +@@ -109,9 +107,8 @@ gmon_io_read_32 (FILE *ifp, unsigned int *valp) + return 0; + } + +-#ifdef BFD_HOST_U_64_BIT + static int +-gmon_io_read_64 (FILE *ifp, BFD_HOST_U_64_BIT *valp) ++gmon_io_read_64 (FILE *ifp, uint64_t *valp) + { + char buf[8]; + +@@ -120,15 +117,12 @@ gmon_io_read_64 (FILE *ifp, BFD_HOST_U_64_BIT *valp) + *valp = bfd_get_64 (core_bfd, buf); + return 0; + } +-#endif + + int + gmon_io_read_vma (FILE *ifp, bfd_vma *valp) + { + unsigned int val32; +-#ifdef BFD_HOST_U_64_BIT +- BFD_HOST_U_64_BIT val64; +-#endif ++ uint64_t val64; + + switch (gmon_get_ptr_size ()) + { +@@ -136,23 +130,19 @@ gmon_io_read_vma (FILE *ifp, bfd_vma *valp) + if (gmon_io_read_32 (ifp, &val32)) + return 1; + if (gmon_get_ptr_signedness () == ptr_signed) +- *valp = (int) val32; ++ *valp = (int) val32; + else +- *valp = val32; ++ *valp = val32; + break; + +-#ifdef BFD_HOST_U_64_BIT + case ptr_64bit: + if (gmon_io_read_64 (ifp, &val64)) + return 1; +-#ifdef BFD_HOST_64_BIT + if (gmon_get_ptr_signedness () == ptr_signed) +- *valp = (BFD_HOST_64_BIT) val64; ++ *valp = (int64_t) val64; + else +-#endif +- *valp = val64; ++ *valp = val64; + break; +-#endif + } + return 0; + } +@@ -176,9 +166,8 @@ gmon_io_write_32 (FILE *ofp, unsigned int val) + return 0; + } + +-#ifdef BFD_HOST_U_64_BIT + static int +-gmon_io_write_64 (FILE *ofp, BFD_HOST_U_64_BIT val) ++gmon_io_write_64 (FILE *ofp, uint64_t val) + { + char buf[8]; + +@@ -187,7 +176,6 @@ gmon_io_write_64 (FILE *ofp, BFD_HOST_U_64_BIT val) + return 1; + return 0; + } +-#endif + + int + gmon_io_write_vma (FILE *ofp, bfd_vma val) +@@ -200,12 +188,10 @@ gmon_io_write_vma (FILE *ofp, bfd_vma val) + return 1; + break; + +-#ifdef BFD_HOST_U_64_BIT + case ptr_64bit: +- if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) val)) ++ if (gmon_io_write_64 (ofp, (uint64_t) val)) + return 1; + break; +-#endif + } + return 0; + } +@@ -232,9 +218,7 @@ gmon_io_write (FILE *ofp, char *buf, size_t n) + static int + gmon_read_raw_arc (FILE *ifp, bfd_vma *fpc, bfd_vma *spc, unsigned long *cnt) + { +-#ifdef BFD_HOST_U_64_BIT +- BFD_HOST_U_64_BIT cnt64; +-#endif ++ uint64_t cnt64; + unsigned int cnt32; + + if (gmon_io_read_vma (ifp, fpc) +@@ -249,13 +233,11 @@ gmon_read_raw_arc (FILE *ifp, bfd_vma *fpc, bfd_vma *spc, unsigned long *cnt) + *cnt = cnt32; + break; + +-#ifdef BFD_HOST_U_64_BIT + case ptr_64bit: + if (gmon_io_read_64 (ifp, &cnt64)) + return 1; + *cnt = cnt64; + break; +-#endif + + default: + return 1; +@@ -278,12 +260,10 @@ gmon_write_raw_arc (FILE *ofp, bfd_vma fpc, bfd_vma spc, unsigned long cnt) + return 1; + break; + +-#ifdef BFD_HOST_U_64_BIT + case ptr_64bit: +- if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) cnt)) ++ if (gmon_io_write_64 (ofp, (uint64_t) cnt)) + return 1; + break; +-#endif + } + return 0; + } +diff --git a/include/elf/nfp.h b/include/elf/nfp.h +index 5a06051196c..c89cefff27b 100644 +--- a/include/elf/nfp.h ++++ b/include/elf/nfp.h +@@ -102,7 +102,7 @@ extern "C" + #define SHF_NFP_INIT 0x80000000 + #define SHF_NFP_INIT2 0x40000000 + #define SHF_NFP_SCS(shf) (((shf) >> 32) & 0xFF) +-#define SHF_NFP_SET_SCS(v) (((BFD_HOST_U_64_BIT)((v) & 0xFF)) << 32) ++#define SHF_NFP_SET_SCS(v) ((uint64_t) ((v) & 0xFF) << 32) + + /* NFP Section Info + For PROGBITS and NOBITS sections: +diff --git a/include/opcode/csky.h b/include/opcode/csky.h +index ed00bfd7cd6..faecba11611 100644 +--- a/include/opcode/csky.h ++++ b/include/opcode/csky.h +@@ -22,46 +22,46 @@ + #include "dis-asm.h" + + /* The following bitmasks control instruction set architecture. */ +-#define CSKYV1_ISA_E1 ((bfd_uint64_t)1 << 0) +-#define CSKYV2_ISA_E1 ((bfd_uint64_t)1 << 1) +-#define CSKYV2_ISA_1E2 ((bfd_uint64_t)1 << 2) +-#define CSKYV2_ISA_2E3 ((bfd_uint64_t)1 << 3) +-#define CSKYV2_ISA_3E7 ((bfd_uint64_t)1 << 4) +-#define CSKYV2_ISA_7E10 ((bfd_uint64_t)1 << 5) +-#define CSKYV2_ISA_3E3R1 ((bfd_uint64_t)1 << 6) +-#define CSKYV2_ISA_3E3R2 ((bfd_uint64_t)1 << 7) +-#define CSKYV2_ISA_10E60 ((bfd_uint64_t)1 << 8) +-#define CSKYV2_ISA_3E3R3 ((bfd_uint64_t)1 << 9) +- +-#define CSKY_ISA_TRUST ((bfd_uint64_t)1 << 11) +-#define CSKY_ISA_CACHE ((bfd_uint64_t)1 << 12) +-#define CSKY_ISA_NVIC ((bfd_uint64_t)1 << 13) +-#define CSKY_ISA_CP ((bfd_uint64_t)1 << 14) +-#define CSKY_ISA_MP ((bfd_uint64_t)1 << 15) +-#define CSKY_ISA_MP_1E2 ((bfd_uint64_t)1 << 16) +-#define CSKY_ISA_JAVA ((bfd_uint64_t)1 << 17) +-#define CSKY_ISA_MAC ((bfd_uint64_t)1 << 18) +-#define CSKY_ISA_MAC_DSP ((bfd_uint64_t)1 << 19) ++#define CSKYV1_ISA_E1 ((uint64_t) 1 << 0) ++#define CSKYV2_ISA_E1 ((uint64_t) 1 << 1) ++#define CSKYV2_ISA_1E2 ((uint64_t) 1 << 2) ++#define CSKYV2_ISA_2E3 ((uint64_t) 1 << 3) ++#define CSKYV2_ISA_3E7 ((uint64_t) 1 << 4) ++#define CSKYV2_ISA_7E10 ((uint64_t) 1 << 5) ++#define CSKYV2_ISA_3E3R1 ((uint64_t) 1 << 6) ++#define CSKYV2_ISA_3E3R2 ((uint64_t) 1 << 7) ++#define CSKYV2_ISA_10E60 ((uint64_t) 1 << 8) ++#define CSKYV2_ISA_3E3R3 ((uint64_t) 1 << 9) ++ ++#define CSKY_ISA_TRUST ((uint64_t) 1 << 11) ++#define CSKY_ISA_CACHE ((uint64_t) 1 << 12) ++#define CSKY_ISA_NVIC ((uint64_t) 1 << 13) ++#define CSKY_ISA_CP ((uint64_t) 1 << 14) ++#define CSKY_ISA_MP ((uint64_t) 1 << 15) ++#define CSKY_ISA_MP_1E2 ((uint64_t) 1 << 16) ++#define CSKY_ISA_JAVA ((uint64_t) 1 << 17) ++#define CSKY_ISA_MAC ((uint64_t) 1 << 18) ++#define CSKY_ISA_MAC_DSP ((uint64_t) 1 << 19) + + /* Base ISA for csky v1 and v2. */ +-#define CSKY_ISA_DSP ((bfd_uint64_t)1 << 20) +-#define CSKY_ISA_DSP_1E2 ((bfd_uint64_t)1 << 21) +-#define CSKY_ISA_DSP_ENHANCE ((bfd_uint64_t)1 << 22) +-#define CSKY_ISA_DSPE60 ((bfd_uint64_t)1 << 23) ++#define CSKY_ISA_DSP ((uint64_t) 1 << 20) ++#define CSKY_ISA_DSP_1E2 ((uint64_t) 1 << 21) ++#define CSKY_ISA_DSP_ENHANCE ((uint64_t) 1 << 22) ++#define CSKY_ISA_DSPE60 ((uint64_t) 1 << 23) + + /* Base float instruction (803f & 810f). */ +-#define CSKY_ISA_FLOAT_E1 ((bfd_uint64_t)1 << 25) ++#define CSKY_ISA_FLOAT_E1 ((uint64_t) 1 << 25) + /* M_FLOAT support (810f). */ +-#define CSKY_ISA_FLOAT_1E2 ((bfd_uint64_t)1 << 26) ++#define CSKY_ISA_FLOAT_1E2 ((uint64_t) 1 << 26) + /* 803 support (803f). */ +-#define CSKY_ISA_FLOAT_1E3 ((bfd_uint64_t)1 << 27) ++#define CSKY_ISA_FLOAT_1E3 ((uint64_t) 1 << 27) + /* 807 support (803f & 807f). */ +-#define CSKY_ISA_FLOAT_3E4 ((bfd_uint64_t)1 << 28) ++#define CSKY_ISA_FLOAT_3E4 ((uint64_t) 1 << 28) + /* 860 support. */ +-#define CSKY_ISA_FLOAT_7E60 ((bfd_uint64_t)1 << 36) ++#define CSKY_ISA_FLOAT_7E60 ((uint64_t) 1 << 36) + /* Vector DSP support. */ +-#define CSKY_ISA_VDSP ((bfd_uint64_t)1 << 29) +-#define CSKY_ISA_VDSP_2 ((bfd_uint64_t)1 << 30) ++#define CSKY_ISA_VDSP ((uint64_t) 1 << 29) ++#define CSKY_ISA_VDSP_2 ((uint64_t) 1 << 30) + + /* The following bitmasks control cpu architecture for CSKY. */ + #define CSKY_ABI_V1 (1 << 28) +diff --git a/include/opcode/ia64.h b/include/opcode/ia64.h +index fbdd8f14e65..42a6812c3f8 100644 +--- a/include/opcode/ia64.h ++++ b/include/opcode/ia64.h +@@ -29,7 +29,7 @@ + extern "C" { + #endif + +-typedef BFD_HOST_U_64_BIT ia64_insn; ++typedef uint64_t ia64_insn; + + enum ia64_insn_type + { +diff --git a/opcodes/csky-dis.c b/opcodes/csky-dis.c +index b7c833623e5..99103ff57b5 100644 +--- a/opcodes/csky-dis.c ++++ b/opcodes/csky-dis.c +@@ -49,7 +49,7 @@ struct csky_dis_info + disassemble_info *info; + /* Opcode information. */ + struct csky_opcode_info const *opinfo; +- BFD_HOST_U_64_BIT isa; ++ uint64_t isa; + /* The value of operand to show. */ + int value; + /* Whether to look up/print a symbol name. */ +diff --git a/opcodes/csky-opc.h b/opcodes/csky-opc.h +index b65efe19d9f..d2db90ede95 100644 +--- a/opcodes/csky-opc.h ++++ b/opcodes/csky-opc.h +@@ -271,8 +271,8 @@ struct csky_opcode + /* Encodings for 32-bit opcodes. */ + struct csky_opcode_info op32[OP_TABLE_NUM]; + /* Instruction set flag. */ +- BFD_HOST_U_64_BIT isa_flag16; +- BFD_HOST_U_64_BIT isa_flag32; ++ uint64_t isa_flag16; ++ uint64_t isa_flag32; + /* Whether this insn needs relocation, 0: no, !=0: yes. */ + signed int reloc16; + signed int reloc32; +diff --git a/opcodes/ia64-dis.c b/opcodes/ia64-dis.c +index 5eb37277a5d..e76f40393c6 100644 +--- a/opcodes/ia64-dis.c ++++ b/opcodes/ia64-dis.c +@@ -73,7 +73,7 @@ print_insn_ia64 (bfd_vma memaddr, struct disassemble_info *info) + const struct ia64_operand *odesc; + const struct ia64_opcode *idesc; + const char *err, *str, *tname; +- BFD_HOST_U_64_BIT value; ++ uint64_t value; + bfd_byte bundle[16]; + enum ia64_unit unit; + char regname[16]; +-- +2.31.1 + diff --git a/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch b/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch new file mode 100644 index 0000000000..6a838ea3ea --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch @@ -0,0 +1,156 @@ +From 31d6c13defeba7716ebc9d5c8f81f2f35fe39980 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Tue, 14 Jun 2022 12:46:42 +0930 +Subject: [PATCH] PR29230, segv in lookup_symbol_in_variable_table + +The PR23230 testcase uses indexed strings without specifying +SW_AT_str_offsets_base. In this case we left u.str with garbage (from +u.val) which then led to a segfault when attempting to access the +string. Fix that by clearing u.str. The patch also adds missing +sanity checks in the recently committed read_indexed_address and +read_indexed_string functions. + + PR 29230 + * dwarf2.c (read_indexed_address): Return uint64_t. Sanity check idx. + (read_indexed_string): Use uint64_t for str_offset. Sanity check idx. + (read_attribute_value): Clear u.str for indexed string forms when + DW_AT_str_offsets_base is not yet read or missing. + +Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=31d6c13defeba7716ebc9d5c8f81f2f35fe39980] + +CVE: CVE-2023-1579 + +Signed-off-by: Yash Shinde + +--- + bfd/dwarf2.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 42 insertions(+), 9 deletions(-) + +diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c +index 51018e1ab45..aaa2d84887f 100644 +--- a/bfd/dwarf2.c ++++ b/bfd/dwarf2.c +@@ -1353,13 +1353,13 @@ is_addrx_form (enum dwarf_form form) + + /* Returns the address in .debug_addr section using DW_AT_addr_base. + Used to implement DW_FORM_addrx*. */ +-static bfd_vma ++static uint64_t + read_indexed_address (uint64_t idx, struct comp_unit *unit) + { + struct dwarf2_debug *stash = unit->stash; + struct dwarf2_debug_file *file = unit->file; +- size_t addr_base = unit->dwarf_addr_offset; + bfd_byte *info_ptr; ++ size_t offset; + + if (stash == NULL) + return 0; +@@ -1369,12 +1369,23 @@ read_indexed_address (uint64_t idx, struct comp_unit *unit) + &file->dwarf_addr_buffer, &file->dwarf_addr_size)) + return 0; + +- info_ptr = file->dwarf_addr_buffer + addr_base + idx * unit->offset_size; ++ if (_bfd_mul_overflow (idx, unit->offset_size, &offset)) ++ return 0; ++ ++ offset += unit->dwarf_addr_offset; ++ if (offset < unit->dwarf_addr_offset ++ || offset > file->dwarf_addr_size ++ || file->dwarf_addr_size - offset < unit->offset_size) ++ return 0; ++ ++ info_ptr = file->dwarf_addr_buffer + offset; + + if (unit->offset_size == 4) + return bfd_get_32 (unit->abfd, info_ptr); +- else ++ else if (unit->offset_size == 8) + return bfd_get_64 (unit->abfd, info_ptr); ++ else ++ return 0; + } + + /* Returns the string using DW_AT_str_offsets_base. +@@ -1385,7 +1396,8 @@ read_indexed_string (uint64_t idx, struct comp_unit *unit) + struct dwarf2_debug *stash = unit->stash; + struct dwarf2_debug_file *file = unit->file; + bfd_byte *info_ptr; +- unsigned long str_offset; ++ uint64_t str_offset; ++ size_t offset; + + if (stash == NULL) + return NULL; +@@ -1401,15 +1413,26 @@ read_indexed_string (uint64_t idx, struct comp_unit *unit) + &file->dwarf_str_offsets_size)) + return NULL; + +- info_ptr = (file->dwarf_str_offsets_buffer +- + unit->dwarf_str_offset +- + idx * unit->offset_size); ++ if (_bfd_mul_overflow (idx, unit->offset_size, &offset)) ++ return NULL; ++ ++ offset += unit->dwarf_str_offset; ++ if (offset < unit->dwarf_str_offset ++ || offset > file->dwarf_str_offsets_size ++ || file->dwarf_str_offsets_size - offset < unit->offset_size) ++ return NULL; ++ ++ info_ptr = file->dwarf_str_offsets_buffer + offset; + + if (unit->offset_size == 4) + str_offset = bfd_get_32 (unit->abfd, info_ptr); +- else ++ else if (unit->offset_size == 8) + str_offset = bfd_get_64 (unit->abfd, info_ptr); ++ else ++ return NULL; + ++ if (str_offset >= file->dwarf_str_size) ++ return NULL; + return (const char *) file->dwarf_str_buffer + str_offset; + } + +@@ -1534,27 +1557,37 @@ read_attribute_value (struct attribute * attr, + is not yet read. */ + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_strx2: + attr->u.val = read_2_bytes (abfd, &info_ptr, info_ptr_end); + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_strx3: + attr->u.val = read_3_bytes (abfd, &info_ptr, info_ptr_end); + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_strx4: + attr->u.val = read_4_bytes (abfd, &info_ptr, info_ptr_end); + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_strx: + attr->u.val = _bfd_safe_read_leb128 (abfd, &info_ptr, + false, info_ptr_end); + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_exprloc: + case DW_FORM_block: +-- +2.31.1 + diff --git a/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-4.patch b/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-4.patch new file mode 100644 index 0000000000..c5a869ca9d --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-4.patch @@ -0,0 +1,37 @@ +From 3e307d538c351aa9327cbad672c884059ecc20dd Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Wed, 11 Jan 2023 12:13:46 +0000 +Subject: [PATCH] Fix a potential illegal memory access in the BFD library when + parsing a corrupt DWARF file. + + PR 29988 + * dwarf2.c (read_indexed_address): Fix check for an out of range + offset. + +Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3e307d538c351aa9327cbad672c884059ecc20dd] + +CVE: CVE-2023-1579 + +Signed-off-by: Yash Shinde + +--- + bfd/ChangeLog | 6 ++++++ + bfd/dwarf2.c | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c +index 6eb6e04e6e5..4ec0053a111 100644 +--- a/bfd/dwarf2.c ++++ b/bfd/dwarf2.c +@@ -1412,7 +1412,7 @@ read_indexed_address (uint64_t idx, struct comp_unit *unit) + offset += unit->dwarf_addr_offset; + if (offset < unit->dwarf_addr_offset + || offset > file->dwarf_addr_size +- || file->dwarf_addr_size - offset < unit->offset_size) ++ || file->dwarf_addr_size - offset < unit->addr_size) + return 0; + + info_ptr = file->dwarf_addr_buffer + offset; +-- +2.31.1 + From patchwork Sat Apr 15 15:26:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 22645 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1969C77B70 for ; Sat, 15 Apr 2023 15:27:07 +0000 (UTC) Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) by mx.groups.io with SMTP id smtpd.web11.10380.1681572421110775565 for ; Sat, 15 Apr 2023 08:27:01 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@sakoman-com.20221208.gappssmtp.com header.s=20221208 header.b=FautJfH2; spf=softfail (domain: sakoman.com, ip: 209.85.214.179, mailfrom: steve@sakoman.com) Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-1a6bc48aec8so191965ad.2 for ; Sat, 15 Apr 2023 08:27:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20221208.gappssmtp.com; s=20221208; t=1681572420; x=1684164420; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=1I7IaIQ1QK/8WL5IUT/2Z6G1mO1dOZImXXRAkdgXu4E=; b=FautJfH2X76ZzCT4cXPUe9L4YqnSG3PPbtEgkeaz04wcIllx5T2jjGCB3LS7BFMX24 efJAWnqXazxOgux6WwtSCzawrdo353VDgHNLm1b1VgmIVUykbyH9D7UQKPNR36zAq9Ok IFel3B2r2esBcdmpqBuznMSwy7PJfaXvPQNE/qdE6dtvs9Mi9ysOqtOcMM3f6nf1bqbV JBZo4pKMEQgIZS6CiST6Sm1v4TbGJUqhj/N8CErZgMzCSj0EYY8C6/HkgAgqUtoSpg9O HsdSYECCjfRn9GQxz8euNsfvPaHmT59BtbNvqq7N5Ui8ljU5PitBjln/PqOMu3sX71B0 9eIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681572420; x=1684164420; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1I7IaIQ1QK/8WL5IUT/2Z6G1mO1dOZImXXRAkdgXu4E=; b=Cn58IVkaH5ceUDD7RVQXBeE7i/Nnd/W4BoicuNRiEJN9jMApk9DmvAjKzc8A9vYznA A/pigBqGFTM0B8gTZnCDBFWa8+6HGrLJApdmmZbk74bywnOKTY5gcdazC/d5I5+I4e2L 2RfsvgNibTx6ItpgFBZ4GbSXyvr+tk1tWorKd7HPrqulzsvytsh1BrKEVf5pyeeZOxYq RLasmp4E8Zm7Yp+98EfWjn43Tbp6wEjeC0CvqswLHxmB0n2Ha68vmJRk75OMDHUbQT/x 3xIAPGg1f9payADXMhHAbl26/kVSxc0oDRU7pznOYWBve0K9qtclLvWg/wd2CTC3Xol9 DUhw== X-Gm-Message-State: AAQBX9dH1Gqa8LguXoDl2vaF4Ot11MmVljlLHqmnt4KpC2OngdxuHq+g mSddLc9K1plnqakAVEkPmrsx7tUMLPxishLdFkk= X-Google-Smtp-Source: AKy350abT79qz4/Smm4iIxBEfrubAkRMoQE/TT0U3UTonOR/sSJclfUQKhmBjYFXLTQBzR8Ausz1AQ== X-Received: by 2002:a05:6a00:1401:b0:637:1177:73f3 with SMTP id l1-20020a056a00140100b00637117773f3mr14114053pfu.14.1681572420035; Sat, 15 Apr 2023 08:27:00 -0700 (PDT) Received: from hexa.router0800d9.com (dhcp-72-253-4-112.hawaiiantel.net. [72.253.4.112]) by smtp.gmail.com with ESMTPSA id u22-20020aa78496000000b0063b1e7ffc5fsm4824410pfn.39.2023.04.15.08.26.59 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Apr 2023 08:26:59 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 2/7] curl: CVE-2023-27533 TELNET option IAC injection Date: Sat, 15 Apr 2023 05:26:39 -1000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 15 Apr 2023 15:27:07 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/180011 From: Hitendra Prajapati Upstream-Status: Backport from https://github.com/curl/curl/commit/0c28ba2faae2d7da780a66d2446045a560192cdc && https://github.com/curl/curl/commit/538b1e79a6e7b0bb829ab4cecc828d32105d0684 Signed-off-by: Hitendra Prajapati Signed-off-by: Steve Sakoman --- .../curl/curl/CVE-2023-27533.patch | 208 ++++++++++++++++++ meta/recipes-support/curl/curl_7.82.0.bb | 1 + 2 files changed, 209 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2023-27533.patch diff --git a/meta/recipes-support/curl/curl/CVE-2023-27533.patch b/meta/recipes-support/curl/curl/CVE-2023-27533.patch new file mode 100644 index 0000000000..b69b20c85a --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2023-27533.patch @@ -0,0 +1,208 @@ +From 538b1e79a6e7b0bb829ab4cecc828d32105d0684 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 6 Mar 2023 12:07:33 +0100 +Subject: [PATCH] telnet: parse telnet options without sscanf & only accept option arguments in ascii + +To avoid embedded telnet negotiation commands etc. + +Reported-by: Harry Sintonen +Closes #10728 + +CVE: CVE-2023-27533 +Upstream-Status: Backport [https://github.com/curl/curl/commit/0c28ba2faae2d7da780a66d2446045a560192cdc && https://github.com/curl/curl/commit/538b1e79a6e7b0bb829ab4cecc828d32105d0684] + +Signed-off-by: Hitendra Prajapati +--- + lib/telnet.c | 149 +++++++++++++++++++++++++++++++-------------------- + 1 file changed, 91 insertions(+), 58 deletions(-) + +diff --git a/lib/telnet.c b/lib/telnet.c +index e709973..3ecd680 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -768,22 +768,32 @@ static void printsub(struct Curl_easy *data, + } + } + ++static bool str_is_nonascii(const char *str) ++{ ++ size_t len = strlen(str); ++ while(len--) { ++ if(*str & 0x80) ++ return TRUE; ++ str++; ++ } ++ return FALSE; ++} ++ + static CURLcode check_telnet_options(struct Curl_easy *data) + { + struct curl_slist *head; + struct curl_slist *beg; +- char option_keyword[128] = ""; +- char option_arg[256] = ""; + struct TELNET *tn = data->req.p.telnet; +- struct connectdata *conn = data->conn; + CURLcode result = CURLE_OK; +- int binary_option; + + /* Add the user name as an environment variable if it + was given on the command line */ + if(data->state.aptr.user) { +- msnprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user); +- beg = curl_slist_append(tn->telnet_vars, option_arg); ++ char buffer[256]; ++ if(str_is_nonascii(data->conn->user)) ++ return CURLE_BAD_FUNCTION_ARGUMENT; ++ msnprintf(buffer, sizeof(buffer), "USER,%s", data->conn->user); ++ beg = curl_slist_append(tn->telnet_vars, buffer); + if(!beg) { + curl_slist_free_all(tn->telnet_vars); + tn->telnet_vars = NULL; +@@ -793,68 +803,91 @@ static CURLcode check_telnet_options(struct Curl_easy *data) + tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; + } + +- for(head = data->set.telnet_options; head; head = head->next) { +- if(sscanf(head->data, "%127[^= ]%*[ =]%255s", +- option_keyword, option_arg) == 2) { +- +- /* Terminal type */ +- if(strcasecompare(option_keyword, "TTYPE")) { +- strncpy(tn->subopt_ttype, option_arg, 31); +- tn->subopt_ttype[31] = 0; /* String termination */ +- tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES; ++ for(head = data->set.telnet_options; head && !result; head = head->next) { ++ size_t olen; ++ char *option = head->data; ++ char *arg; ++ char *sep = strchr(option, '='); ++ if(sep) { ++ olen = sep - option; ++ arg = ++sep; ++ if(str_is_nonascii(arg)) + continue; +- } ++ switch(olen) { ++ case 5: ++ /* Terminal type */ ++ if(strncasecompare(option, "TTYPE", 5)) { ++ strncpy(tn->subopt_ttype, arg, 31); ++ tn->subopt_ttype[31] = 0; /* String termination */ ++ tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES; ++ } ++ else ++ result = CURLE_UNKNOWN_OPTION; ++ break; + +- /* Display variable */ +- if(strcasecompare(option_keyword, "XDISPLOC")) { +- strncpy(tn->subopt_xdisploc, option_arg, 127); +- tn->subopt_xdisploc[127] = 0; /* String termination */ +- tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES; +- continue; +- } ++ case 8: ++ /* Display variable */ ++ if(strncasecompare(option, "XDISPLOC", 8)) { ++ strncpy(tn->subopt_xdisploc, arg, 127); ++ tn->subopt_xdisploc[127] = 0; /* String termination */ ++ tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES; ++ } ++ else ++ result = CURLE_UNKNOWN_OPTION; ++ break; + +- /* Environment variable */ +- if(strcasecompare(option_keyword, "NEW_ENV")) { +- beg = curl_slist_append(tn->telnet_vars, option_arg); +- if(!beg) { +- result = CURLE_OUT_OF_MEMORY; +- break; ++ case 7: ++ /* Environment variable */ ++ if(strncasecompare(option, "NEW_ENV", 7)) { ++ beg = curl_slist_append(tn->telnet_vars, arg); ++ if(!beg) { ++ result = CURLE_OUT_OF_MEMORY; ++ break; ++ } ++ tn->telnet_vars = beg; ++ tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; + } +- tn->telnet_vars = beg; +- tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; +- continue; +- } ++ else ++ result = CURLE_UNKNOWN_OPTION; ++ break; + +- /* Window Size */ +- if(strcasecompare(option_keyword, "WS")) { +- if(sscanf(option_arg, "%hu%*[xX]%hu", +- &tn->subopt_wsx, &tn->subopt_wsy) == 2) +- tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES; +- else { +- failf(data, "Syntax error in telnet option: %s", head->data); +- result = CURLE_SETOPT_OPTION_SYNTAX; +- break; ++ case 2: ++ /* Window Size */ ++ if(strncasecompare(option, "WS", 2)) { ++ if(sscanf(arg, "%hu%*[xX]%hu", ++ &tn->subopt_wsx, &tn->subopt_wsy) == 2) ++ tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES; ++ else { ++ failf(data, "Syntax error in telnet option: %s", head->data); ++ result = CURLE_SETOPT_OPTION_SYNTAX; ++ } + } +- continue; +- } ++ else ++ result = CURLE_UNKNOWN_OPTION; ++ break; + +- /* To take care or not of the 8th bit in data exchange */ +- if(strcasecompare(option_keyword, "BINARY")) { +- binary_option = atoi(option_arg); +- if(binary_option != 1) { +- tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO; +- tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO; ++ case 6: ++ /* To take care or not of the 8th bit in data exchange */ ++ if(strncasecompare(option, "BINARY", 6)) { ++ int binary_option = atoi(arg); ++ if(binary_option != 1) { ++ tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO; ++ tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO; ++ } + } +- continue; ++ else ++ result = CURLE_UNKNOWN_OPTION; ++ break; ++ default: ++ failf(data, "Unknown telnet option %s", head->data); ++ result = CURLE_UNKNOWN_OPTION; ++ break; + } +- +- failf(data, "Unknown telnet option %s", head->data); +- result = CURLE_UNKNOWN_OPTION; +- break; + } +- failf(data, "Syntax error in telnet option: %s", head->data); +- result = CURLE_SETOPT_OPTION_SYNTAX; +- break; ++ else { ++ failf(data, "Syntax error in telnet option: %s", head->data); ++ result = CURLE_SETOPT_OPTION_SYNTAX; ++ } + } + + if(result) { +-- +2.25.1 + diff --git a/meta/recipes-support/curl/curl_7.82.0.bb b/meta/recipes-support/curl/curl_7.82.0.bb index 945745cdde..7efec07e61 100644 --- a/meta/recipes-support/curl/curl_7.82.0.bb +++ b/meta/recipes-support/curl/curl_7.82.0.bb @@ -40,6 +40,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2023-23914_5-4.patch \ file://CVE-2023-23914_5-5.patch \ file://CVE-2023-23916.patch \ + file://CVE-2023-27533.patch \ " SRC_URI[sha256sum] = "0aaa12d7bd04b0966254f2703ce80dd5c38dbbd76af0297d3d690cdce58a583c" From patchwork Sat Apr 15 15:26:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 22644 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2BF4C77B71 for ; Sat, 15 Apr 2023 15:27:07 +0000 (UTC) Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.174]) by mx.groups.io with SMTP id smtpd.web11.10384.1681572422695253552 for ; Sat, 15 Apr 2023 08:27:02 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@sakoman-com.20221208.gappssmtp.com header.s=20221208 header.b=EDw0XLG9; spf=softfail (domain: sakoman.com, ip: 209.85.210.174, mailfrom: steve@sakoman.com) Received: by mail-pf1-f174.google.com with SMTP id d2e1a72fcca58-63b73203e0aso1586685b3a.1 for ; Sat, 15 Apr 2023 08:27:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20221208.gappssmtp.com; s=20221208; t=1681572422; x=1684164422; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=+uSTSMhcm3PFahTrMnZjL1WM2qc4NsbVKol3WuVfXEQ=; b=EDw0XLG9ZXR+DplkE1OH717Upj1XZldyDAcxtnMW5tqFrl6i/J/GhKBp7LiAU2C+cW kX1F659d4PZrlFRyvQpGqoiAvv4F7tbWf61yxOBpUIf5jLsHOTlV8OYarn6P8ysfQx28 5yOC5tl9L8DjPBltK2u2C324c3qiORHHLUp+YZ1aO36AwfM7bNVg/XbD66pRfki+B10S DG22PRpcjTsSaWrJiMyiS2YpO2lKDOjVdhnPgYAUXyz7mKWoG7GzbyNbGxzFcZeK3Adx CHjS8+NFbnekYReGI5cHFJ1T+OOZNoV0tIbaW6a983wNuOsqT95XIFiDZ6JLXegfWEOF mjvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681572422; x=1684164422; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+uSTSMhcm3PFahTrMnZjL1WM2qc4NsbVKol3WuVfXEQ=; b=WrrYVyo1ao3L3qGolpiNcscErRGFsRrVURx1lVDxmH4Zf/FfUPcsANcr5U3AM7nvd3 fBzhhhQ3rsBjLDSsMogt3cEmWaVn2U8vIYZYMrnMV7qiAy5fiCF2+FYvoLSjB3TtB1+Y ikAsx7tkIjxvBZgZiFou+cdl3B7xxQbDFofIcw4TWSHPKpnFWd0Xx44UVED7kb5jeQNx LcuHHxFsCx3cAOzXyXq0ftmVjMhrG77cGDH2zbisAJAiXIqAsaREuQhJAqOmhvXFPpjh stliVVavhP9Q3fRcHDxGSiNVAe5P9pL52bIgCEC+IzD97/Yl3u2qEIGrK3Vwu+qiNma4 2sMA== X-Gm-Message-State: AAQBX9dX93KMm8JI6qB1eOS3EL7CTXGD2TVzRj8fUvd9SkxgYQFCcSAv d/o7QkkGeNWA3uGEqM1j9PWr71cXh2ahg4KcMnM= X-Google-Smtp-Source: AKy350ZDjdbkeS4QHBxSD1y9ZGcaBUW3/t81tOceUZ9JHbpzPHNRwjqEJsP976wwCdvn/Xo7CkjSCQ== X-Received: by 2002:a05:6a00:1343:b0:634:4f6:86df with SMTP id k3-20020a056a00134300b0063404f686dfmr11002365pfu.1.1681572421772; Sat, 15 Apr 2023 08:27:01 -0700 (PDT) Received: from hexa.router0800d9.com (dhcp-72-253-4-112.hawaiiantel.net. [72.253.4.112]) by smtp.gmail.com with ESMTPSA id u22-20020aa78496000000b0063b1e7ffc5fsm4824410pfn.39.2023.04.15.08.27.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Apr 2023 08:27:01 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 3/7] curl: CVE-2023-27534 SFTP path resolving discrepancy Date: Sat, 15 Apr 2023 05:26:40 -1000 Message-Id: <7919a5a5eaa2689db9f0e8110b923bbfe0a610ab.1681572283.git.steve@sakoman.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 15 Apr 2023 15:27:07 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/180013 From: Hitendra Prajapati Upstream-Status: Backport from https://github.com/curl/curl/commit/4e2b52b5f7a3bf50a0f1494155717b02cc1df6d6 Signed-off-by: Hitendra Prajapati Signed-off-by: Steve Sakoman --- .../curl/curl/CVE-2023-27534.patch | 122 ++++++++++++++++++ meta/recipes-support/curl/curl_7.82.0.bb | 1 + 2 files changed, 123 insertions(+) create mode 100644 meta/recipes-support/curl/curl/CVE-2023-27534.patch diff --git a/meta/recipes-support/curl/curl/CVE-2023-27534.patch b/meta/recipes-support/curl/curl/CVE-2023-27534.patch new file mode 100644 index 0000000000..9109faaf88 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2023-27534.patch @@ -0,0 +1,122 @@ +From 4e2b52b5f7a3bf50a0f1494155717b02cc1df6d6 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 9 Mar 2023 16:22:11 +0100 +Subject: [PATCH] curl_path: create the new path with dynbuf + +CVE: CVE-2023-27534 +Upstream-Status: Backport [https://github.com/curl/curl/commit/4e2b52b5f7a3bf50a0f1494155717b02cc1df6d6] + +Signed-off-by: Hitendra Prajapati +--- + lib/curl_path.c | 71 ++++++++++++++++++++++++------------------------- + 1 file changed, 35 insertions(+), 36 deletions(-) + +diff --git a/lib/curl_path.c b/lib/curl_path.c +index a1669d1..b9c470f 100644 +--- a/lib/curl_path.c ++++ b/lib/curl_path.c +@@ -30,66 +30,65 @@ + #include "escape.h" + #include "memdebug.h" + ++#define MAX_SSHPATH_LEN 100000 /* arbitrary */ ++ + /* figure out the path to work with in this particular request */ + CURLcode Curl_getworkingpath(struct Curl_easy *data, + char *homedir, /* when SFTP is used */ + char **path) /* returns the allocated + real path to work with */ + { +- char *real_path = NULL; + char *working_path; + size_t working_path_len; ++ struct dynbuf npath; + CURLcode result = + Curl_urldecode(data->state.up.path, 0, &working_path, + &working_path_len, REJECT_ZERO); + if(result) + return result; + ++ /* new path to switch to in case we need to */ ++ Curl_dyn_init(&npath, MAX_SSHPATH_LEN); ++ + /* Check for /~/, indicating relative to the user's home directory */ +- if(data->conn->handler->protocol & CURLPROTO_SCP) { +- real_path = malloc(working_path_len + 1); +- if(!real_path) { ++ if((data->conn->handler->protocol & CURLPROTO_SCP) && ++ (working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) { ++ /* It is referenced to the home directory, so strip the leading '/~/' */ ++ if(Curl_dyn_addn(&npath, &working_path[3], working_path_len - 3)) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } +- if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) +- /* It is referenced to the home directory, so strip the leading '/~/' */ +- memcpy(real_path, working_path + 3, working_path_len - 2); +- else +- memcpy(real_path, working_path, 1 + working_path_len); + } +- else if(data->conn->handler->protocol & CURLPROTO_SFTP) { +- if((working_path_len > 1) && (working_path[1] == '~')) { +- size_t homelen = strlen(homedir); +- real_path = malloc(homelen + working_path_len + 1); +- if(!real_path) { +- free(working_path); +- return CURLE_OUT_OF_MEMORY; +- } +- /* It is referenced to the home directory, so strip the +- leading '/' */ +- memcpy(real_path, homedir, homelen); +- real_path[homelen] = '/'; +- real_path[homelen + 1] = '\0'; +- if(working_path_len > 3) { +- memcpy(real_path + homelen + 1, working_path + 3, +- 1 + working_path_len -3); +- } ++ else if((data->conn->handler->protocol & CURLPROTO_SFTP) && ++ (working_path_len > 2) && !memcmp(working_path, "/~/", 3)) { ++ size_t len; ++ const char *p; ++ int copyfrom = 3; ++ if(Curl_dyn_add(&npath, homedir)) { ++ free(working_path); ++ return CURLE_OUT_OF_MEMORY; + } +- else { +- real_path = malloc(working_path_len + 1); +- if(!real_path) { +- free(working_path); +- return CURLE_OUT_OF_MEMORY; +- } +- memcpy(real_path, working_path, 1 + working_path_len); ++ /* Copy a separating '/' if homedir does not end with one */ ++ len = Curl_dyn_len(&npath); ++ p = Curl_dyn_ptr(&npath); ++ if(len && (p[len-1] != '/')) ++ copyfrom = 2; ++ ++ if(Curl_dyn_addn(&npath, ++ &working_path[copyfrom], working_path_len - copyfrom)) { ++ free(working_path); ++ return CURLE_OUT_OF_MEMORY; + } + } + +- free(working_path); ++ if(Curl_dyn_len(&npath)) { ++ free(working_path); + +- /* store the pointer for the caller to receive */ +- *path = real_path; ++ /* store the pointer for the caller to receive */ ++ *path = Curl_dyn_ptr(&npath); ++ } ++ else ++ *path = working_path; + + return CURLE_OK; + } +-- +2.25.1 + diff --git a/meta/recipes-support/curl/curl_7.82.0.bb b/meta/recipes-support/curl/curl_7.82.0.bb index 7efec07e61..4c18afe293 100644 --- a/meta/recipes-support/curl/curl_7.82.0.bb +++ b/meta/recipes-support/curl/curl_7.82.0.bb @@ -41,6 +41,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \ file://CVE-2023-23914_5-5.patch \ file://CVE-2023-23916.patch \ file://CVE-2023-27533.patch \ + file://CVE-2023-27534.patch \ " SRC_URI[sha256sum] = "0aaa12d7bd04b0966254f2703ce80dd5c38dbbd76af0297d3d690cdce58a583c" From patchwork Sat Apr 15 15:26:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 22647 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3240C77B79 for ; Sat, 15 Apr 2023 15:27:07 +0000 (UTC) Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) by mx.groups.io with SMTP id smtpd.web10.10502.1681572424358936387 for ; Sat, 15 Apr 2023 08:27:04 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@sakoman-com.20221208.gappssmtp.com header.s=20221208 header.b=EkHEMe6+; spf=softfail (domain: sakoman.com, ip: 209.85.214.178, mailfrom: steve@sakoman.com) Received: by mail-pl1-f178.google.com with SMTP id d15so4017840pll.12 for ; Sat, 15 Apr 2023 08:27:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20221208.gappssmtp.com; s=20221208; t=1681572423; x=1684164423; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=h9xAJm7ZWkbYRCZ0+V5WkNnbB1jIfjxUB/0WEj2sqd8=; b=EkHEMe6+uNguyvIO8H8cEBx2eBkfSgPxj0HJHW46CUBUOksD7wBbWlpTvJc2ruxrfu 1bbnTTsivNO03vGB9quyUwmedG/DoZSFYBVXqtj3Jnp3DdeX9v9ecrx5oF9u3sKGSMdo f/2nynLvShdksHZS16RmGgS/0ZqevpeH5uimN2/6IE0eD60rm3F6fBs3XbaSkEErxjrB XKHxkvJmuJqIv9KSj6VnjgkAfrkKBRyuFWGoRa49y/iSUlCr6dIMFgPWqi2zVUVIWZ+C PjDDGoxcM1H07dxoVTU5WqsOr5rsxl0JkcmGiOYGU5aSmCsfRD0FnHJB+zXhVw3HPi/f Oy0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681572423; x=1684164423; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=h9xAJm7ZWkbYRCZ0+V5WkNnbB1jIfjxUB/0WEj2sqd8=; b=BfNpJ8xOhFp7DLNLsf5Qz8M38pri0We885gHrH69aU0czSJ/vs4yD6g3sKV+889Qs6 XzvQQpzcgr3XJ62/ICI+WRLM8qkV2pM3E+lyXgoJ5d4yQJeHOF1jEJrJBduk0qiAdD5T 1X7rFkI8JHjSdKTfTN/HsqMRQEUlQQw9GjuG3WJDNwCXCp6E3EDPF9z5oT8xZF9KaFiO cQjVGZlg8Q2KIhS/3zK99gJ+UUAmRFO/SUi/5uNOckUWhswwjGuNzsIgVJRnrks4RaeD 3KirrbEdA+UeqmUpuK490c/AVH3zMEA/d9ZkGnircrQy+APN/vpKtZRBR96Eeg5dQKKW v61g== X-Gm-Message-State: AAQBX9devodFp7vI8R8xHmEEYRDfJUfDnYz5ZdLkNQu0/IHTu0ivPIW0 rrGyT9PD0OSGR+a9mnYBazFd9qrJ4SOkcPD3NAM= X-Google-Smtp-Source: AKy350afI88EHEr7UiRu7f4dljRh2Uv8JwAalBA/SzzxVy+38UtBAz0IEZzFqwObpXzmjtrmiYr3qQ== X-Received: by 2002:a05:6a20:a10f:b0:ec:a118:6471 with SMTP id q15-20020a056a20a10f00b000eca1186471mr9689077pzk.50.1681572423447; Sat, 15 Apr 2023 08:27:03 -0700 (PDT) Received: from hexa.router0800d9.com (dhcp-72-253-4-112.hawaiiantel.net. [72.253.4.112]) by smtp.gmail.com with ESMTPSA id u22-20020aa78496000000b0063b1e7ffc5fsm4824410pfn.39.2023.04.15.08.27.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Apr 2023 08:27:03 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 4/7] tiff: Add fix for CVE-2022-4645 Date: Sat, 15 Apr 2023 05:26:41 -1000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 15 Apr 2023 15:27:07 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/180014 From: Pawan Badganchi Below patch fixes the CVE-2022-4645 as well. 0001-Revised-handling-of-TIFFTAG_INKNAMES-and-related-TIF.patch Link: https://nvd.nist.gov/vuln/detail/CVE-2022-4645 Signed-off-by: Pawan Badganchi Signed-off-by: Steve Sakoman --- ...evised-handling-of-TIFFTAG_INKNAMES-and-related-TIF.patch | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/meta/recipes-multimedia/libtiff/tiff/0001-Revised-handling-of-TIFFTAG_INKNAMES-and-related-TIF.patch b/meta/recipes-multimedia/libtiff/tiff/0001-Revised-handling-of-TIFFTAG_INKNAMES-and-related-TIF.patch index 37859c9192..17b37be041 100644 --- a/meta/recipes-multimedia/libtiff/tiff/0001-Revised-handling-of-TIFFTAG_INKNAMES-and-related-TIF.patch +++ b/meta/recipes-multimedia/libtiff/tiff/0001-Revised-handling-of-TIFFTAG_INKNAMES-and-related-TIF.patch @@ -23,9 +23,10 @@ This MR will close the following issues: #149, #150, #152, #168 (to be checked) It also fixes the old bug at http://bugzilla.maptools.org/show_bug.cgi?id=2599, for which the limitation of `NumberOfInks = SPP` was introduced, which is in my opinion not necessary and does not solve the general issue. -CVE: CVE-2022-3599 -Upstream-Status: Backport +CVE: CVE-2022-3599 CVE-2022-4645 +Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/e813112545942107551433d61afd16ac094ff246.patch] Signed-off-by: Ross Burton +Signed-off-by: Pawan Badganchi --- libtiff/tif_dir.c | 119 ++++++++++++++++++++++++----------------- libtiff/tif_dir.h | 2 + From patchwork Sat Apr 15 15:26:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 22650 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id DEFD7C77B76 for ; Sat, 15 Apr 2023 15:27:17 +0000 (UTC) Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) by mx.groups.io with SMTP id smtpd.web10.10506.1681572428262007252 for ; Sat, 15 Apr 2023 08:27:08 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@sakoman-com.20221208.gappssmtp.com header.s=20221208 header.b=zi0YHYX7; spf=softfail (domain: sakoman.com, ip: 209.85.210.176, mailfrom: steve@sakoman.com) Received: by mail-pf1-f176.google.com with SMTP id d2e1a72fcca58-63b62d2f729so433808b3a.1 for ; Sat, 15 Apr 2023 08:27:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20221208.gappssmtp.com; s=20221208; t=1681572427; x=1684164427; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=n5PoxMyYabpa1/AYhSZ73f/ei8z2lTveppDFc8LW6Cc=; b=zi0YHYX7GfdWwYzSztO6UV7QQ8QPjaMaVwdOnF8hgANAd7fbXrEsgeCNTkm2JTAIvk 5uODfjf4DzAxbyljwk9Edz3titEfs3nWeyCwt2466B9d4FFfqrUncsG96EeULzZiATGY majnfm0hEEx4hln+3QZ/DbD7DiiuNs8Ma8W5UhK7XB11Mt1vxDZpzlGJkl+Flbf2CsbX 61RdE5XefJV7JZ0LU5AqQ6+7rcVVbS9maUB+GknkUVRnuUbTFZpHiilCNWhkyqq9qgNZ /PTOTes72oy291s34ybY5E39aEN+tQay+I4lkTAe877+QUdSfEdPw1Q5dlX/+WmdRXc1 8JLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681572427; x=1684164427; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=n5PoxMyYabpa1/AYhSZ73f/ei8z2lTveppDFc8LW6Cc=; b=P7O5F8ogDZ/KgShooJdnwBf6kKo+QwBosOCHoJrNKmHRSrVydSbsCdvPNcWncTs95w RNDaxLth2KzIvJJvc3/KqnC9VXOzXW6AqzSQRqFFyofpwb9rPGmIwIdOwGYHLElOwXGE WQglJxSBCsONEiHEQDVMeCam4O/+3XHPbjZ15+qmdRwlo/15CwfrgNiljJ2q8K1FsOD+ eAzW3Pa5Jy/BXGBvawPTWrF1VCoYsddTQrJ5ifg3goK3cy2iadY5MBrc1Z9thU4Rf/h7 AKeK/Az52PxjnrGBNAiA8pv2saXNsOP8VAZR3JfDmawNYg4YPJk6Mvi8QBgpJZ7jtWvR MQbQ== X-Gm-Message-State: AAQBX9exeJYvnEbBrrdrIWAqxyysXNzJ6FKPqsdsdUzZUyla5FMtgbt5 yxpbSgk5ecafn6rmPQFrOBd69PM/h4Tp5c/vyac= X-Google-Smtp-Source: AKy350b25doOjh7dzv5ZGaK5ZhUb/POnmtgY6X4l1PkR9lETF+ypxJBfCUjsfHmmHKz+KuuEEhgTQw== X-Received: by 2002:a05:6a00:2d15:b0:63b:1e80:3850 with SMTP id fa21-20020a056a002d1500b0063b1e803850mr15668077pfb.19.1681572425553; Sat, 15 Apr 2023 08:27:05 -0700 (PDT) Received: from hexa.router0800d9.com (dhcp-72-253-4-112.hawaiiantel.net. [72.253.4.112]) by smtp.gmail.com with ESMTPSA id u22-20020aa78496000000b0063b1e7ffc5fsm4824410pfn.39.2023.04.15.08.27.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Apr 2023 08:27:05 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 5/7] go: fix CVE-2022-41724, 41725 Date: Sat, 15 Apr 2023 05:26:42 -1000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 15 Apr 2023 15:27:17 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/180015 From: Joe Slater Backport from go-1.19. The godebug package is needed by the fix to CVE-2022-41725. Mostly a cherry-pick but exceptions are noted in comments marked "backport". Signed-off-by: Joe Slater Signed-off-by: Steve Sakoman --- meta/recipes-devtools/go/go-1.17.13.inc | 5 +- .../go/go-1.19/add_godebug.patch | 84 + .../go/go-1.19/cve-2022-41724.patch | 2391 +++++++++++++++++ .../go/go-1.19/cve-2022-41725.patch | 652 +++++ 4 files changed, 3131 insertions(+), 1 deletion(-) create mode 100644 meta/recipes-devtools/go/go-1.19/add_godebug.patch create mode 100644 meta/recipes-devtools/go/go-1.19/cve-2022-41724.patch create mode 100644 meta/recipes-devtools/go/go-1.19/cve-2022-41725.patch diff --git a/meta/recipes-devtools/go/go-1.17.13.inc b/meta/recipes-devtools/go/go-1.17.13.inc index 14d58932dc..23380f04c3 100644 --- a/meta/recipes-devtools/go/go-1.17.13.inc +++ b/meta/recipes-devtools/go/go-1.17.13.inc @@ -1,6 +1,6 @@ require go-common.inc -FILESEXTRAPATHS:prepend := "${FILE_DIRNAME}/go-1.18:" +FILESEXTRAPATHS:prepend := "${FILE_DIRNAME}/go-1.19:${FILE_DIRNAME}/go-1.18:" LIC_FILES_CHKSUM = "file://LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707" @@ -23,6 +23,9 @@ SRC_URI += "\ file://CVE-2022-2879.patch \ file://CVE-2022-41720.patch \ file://CVE-2022-41723.patch \ + file://cve-2022-41724.patch \ + file://add_godebug.patch \ + file://cve-2022-41725.patch \ " SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd" diff --git a/meta/recipes-devtools/go/go-1.19/add_godebug.patch b/meta/recipes-devtools/go/go-1.19/add_godebug.patch new file mode 100644 index 0000000000..0c3d2d2855 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.19/add_godebug.patch @@ -0,0 +1,84 @@ + +Upstream-Status: Backport [see text] + +https://github.com/golong/go.git as of commit 22c1d18a27... +Copy src/internal/godebug from go 1.19 since it does not +exist in 1.17. + +Signed-off-by: Joe Slater +--- + +--- /dev/null ++++ go/src/internal/godebug/godebug.go +@@ -0,0 +1,34 @@ ++// Copyright 2021 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++// Package godebug parses the GODEBUG environment variable. ++package godebug ++ ++import "os" ++ ++// Get returns the value for the provided GODEBUG key. ++func Get(key string) string { ++ return get(os.Getenv("GODEBUG"), key) ++} ++ ++// get returns the value part of key=value in s (a GODEBUG value). ++func get(s, key string) string { ++ for i := 0; i < len(s)-len(key)-1; i++ { ++ if i > 0 && s[i-1] != ',' { ++ continue ++ } ++ afterKey := s[i+len(key):] ++ if afterKey[0] != '=' || s[i:i+len(key)] != key { ++ continue ++ } ++ val := afterKey[1:] ++ for i, b := range val { ++ if b == ',' { ++ return val[:i] ++ } ++ } ++ return val ++ } ++ return "" ++} +--- /dev/null ++++ go/src/internal/godebug/godebug_test.go +@@ -0,0 +1,34 @@ ++// Copyright 2021 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package godebug ++ ++import "testing" ++ ++func TestGet(t *testing.T) { ++ tests := []struct { ++ godebug string ++ key string ++ want string ++ }{ ++ {"", "", ""}, ++ {"", "foo", ""}, ++ {"foo=bar", "foo", "bar"}, ++ {"foo=bar,after=x", "foo", "bar"}, ++ {"before=x,foo=bar,after=x", "foo", "bar"}, ++ {"before=x,foo=bar", "foo", "bar"}, ++ {",,,foo=bar,,,", "foo", "bar"}, ++ {"foodecoy=wrong,foo=bar", "foo", "bar"}, ++ {"foo=", "foo", ""}, ++ {"foo", "foo", ""}, ++ {",foo", "foo", ""}, ++ {"foo=bar,baz", "loooooooong", ""}, ++ } ++ for _, tt := range tests { ++ got := get(tt.godebug, tt.key) ++ if got != tt.want { ++ t.Errorf("get(%q, %q) = %q; want %q", tt.godebug, tt.key, got, tt.want) ++ } ++ } ++} diff --git a/meta/recipes-devtools/go/go-1.19/cve-2022-41724.patch b/meta/recipes-devtools/go/go-1.19/cve-2022-41724.patch new file mode 100644 index 0000000000..aacffbffcd --- /dev/null +++ b/meta/recipes-devtools/go/go-1.19/cve-2022-41724.patch @@ -0,0 +1,2391 @@ +From 00b256e9e3c0fa02a278ec9dfc3e191e02ceaf80 Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Wed, 14 Dec 2022 09:43:16 -0800 +Subject: [PATCH] [release-branch.go1.19] crypto/tls: replace all usages of + BytesOrPanic + +Message marshalling makes use of BytesOrPanic a lot, under the +assumption that it will never panic. This assumption was incorrect, and +specifically crafted handshakes could trigger panics. Rather than just +surgically replacing the usages of BytesOrPanic in paths that could +panic, replace all usages of it with proper error returns in case there +are other ways of triggering panics which we didn't find. + +In one specific case, the tree routed by expandLabel, we replace the +usage of BytesOrPanic, but retain a panic. This function already +explicitly panicked elsewhere, and returning an error from it becomes +rather painful because it requires changing a large number of APIs. +The marshalling is unlikely to ever panic, as the inputs are all either +fixed length, or already limited to the sizes required. If it were to +panic, it'd likely only be during development. A close inspection shows +no paths for a user to cause a panic currently. + +This patches ends up being rather large, since it requires routing +errors back through functions which previously had no error returns. +Where possible I've tried to use helpers that reduce the verbosity +of frequently repeated stanzas, and to make the diffs as minimal as +possible. + +Thanks to Marten Seemann for reporting this issue. + +Updates #58001 +Fixes #58358 +Fixes CVE-2022-41724 + +Change-Id: Ieb55867ef0a3e1e867b33f09421932510cb58851 +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1679436 +Reviewed-by: Julie Qiu +TryBot-Result: Security TryBots +Run-TryBot: Roland Shoemaker +Reviewed-by: Damien Neil +(cherry picked from commit 0f3a44ad7b41cc89efdfad25278953e17d9c1e04) +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1728204 +Reviewed-by: Tatiana Bradley +Reviewed-on: https://go-review.googlesource.com/c/go/+/468117 +Auto-Submit: Michael Pratt +Run-TryBot: Michael Pratt +TryBot-Result: Gopher Robot +Reviewed-by: Than McIntosh +--- + +CVE: CVE-2022-41724 + +Upstream-Status: Backport [see text] + +https://github.com/golong/go.git commit 00b256e9e3c0fa... +boring_test.go does not exist +modified for conn.go and handshake_messages.go + +Signed-off-by: Joe Slater + +--- + src/crypto/tls/boring_test.go | 2 +- + src/crypto/tls/common.go | 2 +- + src/crypto/tls/conn.go | 46 +- + src/crypto/tls/handshake_client.go | 95 +-- + src/crypto/tls/handshake_client_test.go | 4 +- + src/crypto/tls/handshake_client_tls13.go | 74 ++- + src/crypto/tls/handshake_messages.go | 716 +++++++++++----------- + src/crypto/tls/handshake_messages_test.go | 19 +- + src/crypto/tls/handshake_server.go | 73 ++- + src/crypto/tls/handshake_server_test.go | 31 +- + src/crypto/tls/handshake_server_tls13.go | 71 ++- + src/crypto/tls/key_schedule.go | 19 +- + src/crypto/tls/ticket.go | 8 +- + 13 files changed, 657 insertions(+), 503 deletions(-) + +--- go.orig/src/crypto/tls/common.go ++++ go/src/crypto/tls/common.go +@@ -1357,7 +1357,7 @@ func (c *Certificate) leaf() (*x509.Cert + } + + type handshakeMessage interface { +- marshal() []byte ++ marshal() ([]byte, error) + unmarshal([]byte) bool + } + +--- go.orig/src/crypto/tls/conn.go ++++ go/src/crypto/tls/conn.go +@@ -994,18 +994,46 @@ func (c *Conn) writeRecordLocked(typ rec + return n, nil + } + +-// writeRecord writes a TLS record with the given type and payload to the +-// connection and updates the record layer state. +-func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) { ++// writeHandshakeRecord writes a handshake message to the connection and updates ++// the record layer state. If transcript is non-nil the marshalled message is ++// written to it. ++func (c *Conn) writeHandshakeRecord(msg handshakeMessage, transcript transcriptHash) (int, error) { + c.out.Lock() + defer c.out.Unlock() + +- return c.writeRecordLocked(typ, data) ++ data, err := msg.marshal() ++ if err != nil { ++ return 0, err ++ } ++ if transcript != nil { ++ transcript.Write(data) ++ } ++ ++ return c.writeRecordLocked(recordTypeHandshake, data) ++} ++ ++// writeChangeCipherRecord writes a ChangeCipherSpec message to the connection and ++// updates the record layer state. ++func (c *Conn) writeChangeCipherRecord() error { ++ c.out.Lock() ++ defer c.out.Unlock() ++ _, err := c.writeRecordLocked(recordTypeChangeCipherSpec, []byte{1}) ++ return err + } + + // readHandshake reads the next handshake message from +-// the record layer. +-func (c *Conn) readHandshake() (interface{}, error) { ++// the record layer. If transcript is non-nil, the message ++// is written to the passed transcriptHash. ++ ++// backport 00b256e9e3c0fa02a278ec9dfc3e191e02ceaf80 ++// ++// Commit wants to set this to ++// ++// func (c *Conn) readHandshake(transcript transcriptHash) (any, error) { ++// ++// but that does not compile. Retain the original interface{} argument. ++// ++func (c *Conn) readHandshake(transcript transcriptHash) (interface{}, error) { + for c.hand.Len() < 4 { + if err := c.readRecord(); err != nil { + return nil, err +@@ -1084,6 +1112,11 @@ func (c *Conn) readHandshake() (interfac + if !m.unmarshal(data) { + return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } ++ ++ if transcript != nil { ++ transcript.Write(data) ++ } ++ + return m, nil + } + +@@ -1159,7 +1192,7 @@ func (c *Conn) handleRenegotiation() err + return errors.New("tls: internal error: unexpected renegotiation") + } + +- msg, err := c.readHandshake() ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +@@ -1205,7 +1238,7 @@ func (c *Conn) handlePostHandshakeMessag + return c.handleRenegotiation() + } + +- msg, err := c.readHandshake() ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +@@ -1241,7 +1274,11 @@ func (c *Conn) handleKeyUpdate(keyUpdate + defer c.out.Unlock() + + msg := &keyUpdateMsg{} +- _, err := c.writeRecordLocked(recordTypeHandshake, msg.marshal()) ++ msgBytes, err := msg.marshal() ++ if err != nil { ++ return err ++ } ++ _, err = c.writeRecordLocked(recordTypeHandshake, msgBytes) + if err != nil { + // Surface the error at the next write. + c.out.setErrorLocked(err) +--- go.orig/src/crypto/tls/handshake_client.go ++++ go/src/crypto/tls/handshake_client.go +@@ -157,7 +157,10 @@ func (c *Conn) clientHandshake(ctx conte + } + c.serverName = hello.serverName + +- cacheKey, session, earlySecret, binderKey := c.loadSession(hello) ++ cacheKey, session, earlySecret, binderKey, err := c.loadSession(hello) ++ if err != nil { ++ return err ++ } + if cacheKey != "" && session != nil { + defer func() { + // If we got a handshake failure when resuming a session, throw away +@@ -172,11 +175,12 @@ func (c *Conn) clientHandshake(ctx conte + }() + } + +- if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil { ++ if _, err := c.writeHandshakeRecord(hello, nil); err != nil { + return err + } + +- msg, err := c.readHandshake() ++ // serverHelloMsg is not included in the transcript ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +@@ -241,9 +245,9 @@ func (c *Conn) clientHandshake(ctx conte + } + + func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string, +- session *ClientSessionState, earlySecret, binderKey []byte) { ++ session *ClientSessionState, earlySecret, binderKey []byte, err error) { + if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { +- return "", nil, nil, nil ++ return "", nil, nil, nil, nil + } + + hello.ticketSupported = true +@@ -258,14 +262,14 @@ func (c *Conn) loadSession(hello *client + // renegotiation is primarily used to allow a client to send a client + // certificate, which would be skipped if session resumption occurred. + if c.handshakes != 0 { +- return "", nil, nil, nil ++ return "", nil, nil, nil, nil + } + + // Try to resume a previously negotiated TLS session, if available. + cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config) + session, ok := c.config.ClientSessionCache.Get(cacheKey) + if !ok || session == nil { +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + + // Check that version used for the previous session is still valid. +@@ -277,7 +281,7 @@ func (c *Conn) loadSession(hello *client + } + } + if !versOk { +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + + // Check that the cached server certificate is not expired, and that it's +@@ -286,16 +290,16 @@ func (c *Conn) loadSession(hello *client + if !c.config.InsecureSkipVerify { + if len(session.verifiedChains) == 0 { + // The original connection had InsecureSkipVerify, while this doesn't. +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + serverCert := session.serverCertificates[0] + if c.config.time().After(serverCert.NotAfter) { + // Expired certificate, delete the entry. + c.config.ClientSessionCache.Put(cacheKey, nil) +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + if err := serverCert.VerifyHostname(c.config.ServerName); err != nil { +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + } + +@@ -303,7 +307,7 @@ func (c *Conn) loadSession(hello *client + // In TLS 1.2 the cipher suite must match the resumed session. Ensure we + // are still offering it. + if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil { +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + + hello.sessionTicket = session.sessionTicket +@@ -313,14 +317,14 @@ func (c *Conn) loadSession(hello *client + // Check that the session ticket is not expired. + if c.config.time().After(session.useBy) { + c.config.ClientSessionCache.Put(cacheKey, nil) +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + + // In TLS 1.3 the KDF hash must match the resumed session. Ensure we + // offer at least one cipher suite with that hash. + cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite) + if cipherSuite == nil { +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + cipherSuiteOk := false + for _, offeredID := range hello.cipherSuites { +@@ -331,7 +335,7 @@ func (c *Conn) loadSession(hello *client + } + } + if !cipherSuiteOk { +- return cacheKey, nil, nil, nil ++ return cacheKey, nil, nil, nil, nil + } + + // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1. +@@ -349,9 +353,15 @@ func (c *Conn) loadSession(hello *client + earlySecret = cipherSuite.extract(psk, nil) + binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil) + transcript := cipherSuite.hash.New() +- transcript.Write(hello.marshalWithoutBinders()) ++ helloBytes, err := hello.marshalWithoutBinders() ++ if err != nil { ++ return "", nil, nil, nil, err ++ } ++ transcript.Write(helloBytes) + pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)} +- hello.updateBinders(pskBinders) ++ if err := hello.updateBinders(pskBinders); err != nil { ++ return "", nil, nil, nil, err ++ } + + return + } +@@ -396,8 +406,12 @@ func (hs *clientHandshakeState) handshak + hs.finishedHash.discardHandshakeBuffer() + } + +- hs.finishedHash.Write(hs.hello.marshal()) +- hs.finishedHash.Write(hs.serverHello.marshal()) ++ if err := transcriptMsg(hs.hello, &hs.finishedHash); err != nil { ++ return err ++ } ++ if err := transcriptMsg(hs.serverHello, &hs.finishedHash); err != nil { ++ return err ++ } + + c.buffering = true + c.didResume = isResume +@@ -468,7 +482,7 @@ func (hs *clientHandshakeState) pickCiph + func (hs *clientHandshakeState) doFullHandshake() error { + c := hs.c + +- msg, err := c.readHandshake() ++ msg, err := c.readHandshake(&hs.finishedHash) + if err != nil { + return err + } +@@ -477,9 +491,8 @@ func (hs *clientHandshakeState) doFullHa + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certMsg, msg) + } +- hs.finishedHash.Write(certMsg.marshal()) + +- msg, err = c.readHandshake() ++ msg, err = c.readHandshake(&hs.finishedHash) + if err != nil { + return err + } +@@ -497,11 +510,10 @@ func (hs *clientHandshakeState) doFullHa + c.sendAlert(alertUnexpectedMessage) + return errors.New("tls: received unexpected CertificateStatus message") + } +- hs.finishedHash.Write(cs.marshal()) + + c.ocspResponse = cs.response + +- msg, err = c.readHandshake() ++ msg, err = c.readHandshake(&hs.finishedHash) + if err != nil { + return err + } +@@ -530,14 +542,13 @@ func (hs *clientHandshakeState) doFullHa + + skx, ok := msg.(*serverKeyExchangeMsg) + if ok { +- hs.finishedHash.Write(skx.marshal()) + err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx) + if err != nil { + c.sendAlert(alertUnexpectedMessage) + return err + } + +- msg, err = c.readHandshake() ++ msg, err = c.readHandshake(&hs.finishedHash) + if err != nil { + return err + } +@@ -548,7 +559,6 @@ func (hs *clientHandshakeState) doFullHa + certReq, ok := msg.(*certificateRequestMsg) + if ok { + certRequested = true +- hs.finishedHash.Write(certReq.marshal()) + + cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq) + if chainToSend, err = c.getClientCertificate(cri); err != nil { +@@ -556,7 +566,7 @@ func (hs *clientHandshakeState) doFullHa + return err + } + +- msg, err = c.readHandshake() ++ msg, err = c.readHandshake(&hs.finishedHash) + if err != nil { + return err + } +@@ -567,7 +577,6 @@ func (hs *clientHandshakeState) doFullHa + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(shd, msg) + } +- hs.finishedHash.Write(shd.marshal()) + + // If the server requested a certificate then we have to send a + // Certificate message, even if it's empty because we don't have a +@@ -575,8 +584,7 @@ func (hs *clientHandshakeState) doFullHa + if certRequested { + certMsg = new(certificateMsg) + certMsg.certificates = chainToSend.Certificate +- hs.finishedHash.Write(certMsg.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil { + return err + } + } +@@ -587,8 +595,7 @@ func (hs *clientHandshakeState) doFullHa + return err + } + if ckx != nil { +- hs.finishedHash.Write(ckx.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(ckx, &hs.finishedHash); err != nil { + return err + } + } +@@ -635,8 +642,7 @@ func (hs *clientHandshakeState) doFullHa + return err + } + +- hs.finishedHash.Write(certVerify.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certVerify, &hs.finishedHash); err != nil { + return err + } + } +@@ -771,7 +777,10 @@ func (hs *clientHandshakeState) readFini + return err + } + +- msg, err := c.readHandshake() ++ // finishedMsg is included in the transcript, but not until after we ++ // check the client version, since the state before this message was ++ // sent is used during verification. ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +@@ -787,7 +796,11 @@ func (hs *clientHandshakeState) readFini + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: server's Finished message was incorrect") + } +- hs.finishedHash.Write(serverFinished.marshal()) ++ ++ if err := transcriptMsg(serverFinished, &hs.finishedHash); err != nil { ++ return err ++ } ++ + copy(out, verify) + return nil + } +@@ -798,7 +811,7 @@ func (hs *clientHandshakeState) readSess + } + + c := hs.c +- msg, err := c.readHandshake() ++ msg, err := c.readHandshake(&hs.finishedHash) + if err != nil { + return err + } +@@ -807,7 +820,6 @@ func (hs *clientHandshakeState) readSess + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(sessionTicketMsg, msg) + } +- hs.finishedHash.Write(sessionTicketMsg.marshal()) + + hs.session = &ClientSessionState{ + sessionTicket: sessionTicketMsg.ticket, +@@ -827,14 +839,13 @@ func (hs *clientHandshakeState) readSess + func (hs *clientHandshakeState) sendFinished(out []byte) error { + c := hs.c + +- if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { ++ if err := c.writeChangeCipherRecord(); err != nil { + return err + } + + finished := new(finishedMsg) + finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) +- hs.finishedHash.Write(finished.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil { + return err + } + copy(out, finished.verifyData) +--- go.orig/src/crypto/tls/handshake_client_test.go ++++ go/src/crypto/tls/handshake_client_test.go +@@ -1257,7 +1257,7 @@ func TestServerSelectingUnconfiguredAppl + cipherSuite: TLS_RSA_WITH_AES_128_GCM_SHA256, + alpnProtocol: "how-about-this", + } +- serverHelloBytes := serverHello.marshal() ++ serverHelloBytes := mustMarshal(t, serverHello) + + s.Write([]byte{ + byte(recordTypeHandshake), +@@ -1500,7 +1500,7 @@ func TestServerSelectingUnconfiguredCiph + random: make([]byte, 32), + cipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384, + } +- serverHelloBytes := serverHello.marshal() ++ serverHelloBytes := mustMarshal(t, serverHello) + + s.Write([]byte{ + byte(recordTypeHandshake), +--- go.orig/src/crypto/tls/handshake_client_tls13.go ++++ go/src/crypto/tls/handshake_client_tls13.go +@@ -58,7 +58,10 @@ func (hs *clientHandshakeStateTLS13) han + } + + hs.transcript = hs.suite.hash.New() +- hs.transcript.Write(hs.hello.marshal()) ++ ++ if err := transcriptMsg(hs.hello, hs.transcript); err != nil { ++ return err ++ } + + if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { + if err := hs.sendDummyChangeCipherSpec(); err != nil { +@@ -69,7 +72,9 @@ func (hs *clientHandshakeStateTLS13) han + } + } + +- hs.transcript.Write(hs.serverHello.marshal()) ++ if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil { ++ return err ++ } + + c.buffering = true + if err := hs.processServerHello(); err != nil { +@@ -168,8 +173,7 @@ func (hs *clientHandshakeStateTLS13) sen + } + hs.sentDummyCCS = true + +- _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) +- return err ++ return hs.c.writeChangeCipherRecord() + } + + // processHelloRetryRequest handles the HRR in hs.serverHello, modifies and +@@ -184,7 +188,9 @@ func (hs *clientHandshakeStateTLS13) pro + hs.transcript.Reset() + hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) + hs.transcript.Write(chHash) +- hs.transcript.Write(hs.serverHello.marshal()) ++ if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil { ++ return err ++ } + + // The only HelloRetryRequest extensions we support are key_share and + // cookie, and clients must abort the handshake if the HRR would not result +@@ -249,10 +255,18 @@ func (hs *clientHandshakeStateTLS13) pro + transcript := hs.suite.hash.New() + transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) + transcript.Write(chHash) +- transcript.Write(hs.serverHello.marshal()) +- transcript.Write(hs.hello.marshalWithoutBinders()) ++ if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil { ++ return err ++ } ++ helloBytes, err := hs.hello.marshalWithoutBinders() ++ if err != nil { ++ return err ++ } ++ transcript.Write(helloBytes) + pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)} +- hs.hello.updateBinders(pskBinders) ++ if err := hs.hello.updateBinders(pskBinders); err != nil { ++ return err ++ } + } else { + // Server selected a cipher suite incompatible with the PSK. + hs.hello.pskIdentities = nil +@@ -260,12 +274,12 @@ func (hs *clientHandshakeStateTLS13) pro + } + } + +- hs.transcript.Write(hs.hello.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil { + return err + } + +- msg, err := c.readHandshake() ++ // serverHelloMsg is not included in the transcript ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +@@ -354,6 +368,7 @@ func (hs *clientHandshakeStateTLS13) est + if !hs.usingPSK { + earlySecret = hs.suite.extract(nil, nil) + } ++ + handshakeSecret := hs.suite.extract(sharedKey, + hs.suite.deriveSecret(earlySecret, "derived", nil)) + +@@ -384,7 +399,7 @@ func (hs *clientHandshakeStateTLS13) est + func (hs *clientHandshakeStateTLS13) readServerParameters() error { + c := hs.c + +- msg, err := c.readHandshake() ++ msg, err := c.readHandshake(hs.transcript) + if err != nil { + return err + } +@@ -394,7 +409,6 @@ func (hs *clientHandshakeStateTLS13) rea + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(encryptedExtensions, msg) + } +- hs.transcript.Write(encryptedExtensions.marshal()) + + if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil { + c.sendAlert(alertUnsupportedExtension) +@@ -423,18 +437,16 @@ func (hs *clientHandshakeStateTLS13) rea + return nil + } + +- msg, err := c.readHandshake() ++ msg, err := c.readHandshake(hs.transcript) + if err != nil { + return err + } + + certReq, ok := msg.(*certificateRequestMsgTLS13) + if ok { +- hs.transcript.Write(certReq.marshal()) +- + hs.certReq = certReq + +- msg, err = c.readHandshake() ++ msg, err = c.readHandshake(hs.transcript) + if err != nil { + return err + } +@@ -449,7 +461,6 @@ func (hs *clientHandshakeStateTLS13) rea + c.sendAlert(alertDecodeError) + return errors.New("tls: received empty certificates message") + } +- hs.transcript.Write(certMsg.marshal()) + + c.scts = certMsg.certificate.SignedCertificateTimestamps + c.ocspResponse = certMsg.certificate.OCSPStaple +@@ -458,7 +469,10 @@ func (hs *clientHandshakeStateTLS13) rea + return err + } + +- msg, err = c.readHandshake() ++ // certificateVerifyMsg is included in the transcript, but not until ++ // after we verify the handshake signature, since the state before ++ // this message was sent is used. ++ msg, err = c.readHandshake(nil) + if err != nil { + return err + } +@@ -489,7 +503,9 @@ func (hs *clientHandshakeStateTLS13) rea + return errors.New("tls: invalid signature by the server certificate: " + err.Error()) + } + +- hs.transcript.Write(certVerify.marshal()) ++ if err := transcriptMsg(certVerify, hs.transcript); err != nil { ++ return err ++ } + + return nil + } +@@ -497,7 +513,10 @@ func (hs *clientHandshakeStateTLS13) rea + func (hs *clientHandshakeStateTLS13) readServerFinished() error { + c := hs.c + +- msg, err := c.readHandshake() ++ // finishedMsg is included in the transcript, but not until after we ++ // check the client version, since the state before this message was ++ // sent is used during verification. ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +@@ -514,7 +533,9 @@ func (hs *clientHandshakeStateTLS13) rea + return errors.New("tls: invalid server finished hash") + } + +- hs.transcript.Write(finished.marshal()) ++ if err := transcriptMsg(finished, hs.transcript); err != nil { ++ return err ++ } + + // Derive secrets that take context through the server Finished. + +@@ -563,8 +584,7 @@ func (hs *clientHandshakeStateTLS13) sen + certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0 + certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0 + +- hs.transcript.Write(certMsg.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil { + return err + } + +@@ -601,8 +621,7 @@ func (hs *clientHandshakeStateTLS13) sen + } + certVerifyMsg.signature = sig + +- hs.transcript.Write(certVerifyMsg.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil { + return err + } + +@@ -616,8 +635,7 @@ func (hs *clientHandshakeStateTLS13) sen + verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), + } + +- hs.transcript.Write(finished.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil { + return err + } + +--- go.orig/src/crypto/tls/handshake_messages.go ++++ go/src/crypto/tls/handshake_messages.go +@@ -5,6 +5,7 @@ + package tls + + import ( ++ "errors" + "fmt" + "strings" + +@@ -94,9 +95,181 @@ type clientHelloMsg struct { + pskBinders [][]byte + } + +-func (m *clientHelloMsg) marshal() []byte { ++func (m *clientHelloMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil ++ } ++ ++ var exts cryptobyte.Builder ++ if len(m.serverName) > 0 { ++ // RFC 6066, Section 3 ++ exts.AddUint16(extensionServerName) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8(0) // name_type = host_name ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes([]byte(m.serverName)) ++ }) ++ }) ++ }) ++ } ++ if m.ocspStapling { ++ // RFC 4366, Section 3.6 ++ exts.AddUint16(extensionStatusRequest) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8(1) // status_type = ocsp ++ exts.AddUint16(0) // empty responder_id_list ++ exts.AddUint16(0) // empty request_extensions ++ }) ++ } ++ if len(m.supportedCurves) > 0 { ++ // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7 ++ exts.AddUint16(extensionSupportedCurves) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, curve := range m.supportedCurves { ++ exts.AddUint16(uint16(curve)) ++ } ++ }) ++ }) ++ } ++ if len(m.supportedPoints) > 0 { ++ // RFC 4492, Section 5.1.2 ++ exts.AddUint16(extensionSupportedPoints) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.supportedPoints) ++ }) ++ }) ++ } ++ if m.ticketSupported { ++ // RFC 5077, Section 3.2 ++ exts.AddUint16(extensionSessionTicket) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.sessionTicket) ++ }) ++ } ++ if len(m.supportedSignatureAlgorithms) > 0 { ++ // RFC 5246, Section 7.4.1.4.1 ++ exts.AddUint16(extensionSignatureAlgorithms) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, sigAlgo := range m.supportedSignatureAlgorithms { ++ exts.AddUint16(uint16(sigAlgo)) ++ } ++ }) ++ }) ++ } ++ if len(m.supportedSignatureAlgorithmsCert) > 0 { ++ // RFC 8446, Section 4.2.3 ++ exts.AddUint16(extensionSignatureAlgorithmsCert) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, sigAlgo := range m.supportedSignatureAlgorithmsCert { ++ exts.AddUint16(uint16(sigAlgo)) ++ } ++ }) ++ }) ++ } ++ if m.secureRenegotiationSupported { ++ // RFC 5746, Section 3.2 ++ exts.AddUint16(extensionRenegotiationInfo) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.secureRenegotiation) ++ }) ++ }) ++ } ++ if len(m.alpnProtocols) > 0 { ++ // RFC 7301, Section 3.1 ++ exts.AddUint16(extensionALPN) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, proto := range m.alpnProtocols { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes([]byte(proto)) ++ }) ++ } ++ }) ++ }) ++ } ++ if m.scts { ++ // RFC 6962, Section 3.3.1 ++ exts.AddUint16(extensionSCT) ++ exts.AddUint16(0) // empty extension_data ++ } ++ if len(m.supportedVersions) > 0 { ++ // RFC 8446, Section 4.2.1 ++ exts.AddUint16(extensionSupportedVersions) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, vers := range m.supportedVersions { ++ exts.AddUint16(vers) ++ } ++ }) ++ }) ++ } ++ if len(m.cookie) > 0 { ++ // RFC 8446, Section 4.2.2 ++ exts.AddUint16(extensionCookie) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.cookie) ++ }) ++ }) ++ } ++ if len(m.keyShares) > 0 { ++ // RFC 8446, Section 4.2.8 ++ exts.AddUint16(extensionKeyShare) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, ks := range m.keyShares { ++ exts.AddUint16(uint16(ks.group)) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(ks.data) ++ }) ++ } ++ }) ++ }) ++ } ++ if m.earlyData { ++ // RFC 8446, Section 4.2.10 ++ exts.AddUint16(extensionEarlyData) ++ exts.AddUint16(0) // empty extension_data ++ } ++ if len(m.pskModes) > 0 { ++ // RFC 8446, Section 4.2.9 ++ exts.AddUint16(extensionPSKModes) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.pskModes) ++ }) ++ }) ++ } ++ if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension ++ // RFC 8446, Section 4.2.11 ++ exts.AddUint16(extensionPreSharedKey) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, psk := range m.pskIdentities { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(psk.label) ++ }) ++ exts.AddUint32(psk.obfuscatedTicketAge) ++ } ++ }) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, binder := range m.pskBinders { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(binder) ++ }) ++ } ++ }) ++ }) ++ } ++ extBytes, err := exts.Bytes() ++ if err != nil { ++ return nil, err + } + + var b cryptobyte.Builder +@@ -116,219 +289,53 @@ func (m *clientHelloMsg) marshal() []byt + b.AddBytes(m.compressionMethods) + }) + +- // If extensions aren't present, omit them. +- var extensionsPresent bool +- bWithoutExtensions := *b +- +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- if len(m.serverName) > 0 { +- // RFC 6066, Section 3 +- b.AddUint16(extensionServerName) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8(0) // name_type = host_name +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes([]byte(m.serverName)) +- }) +- }) +- }) +- } +- if m.ocspStapling { +- // RFC 4366, Section 3.6 +- b.AddUint16(extensionStatusRequest) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8(1) // status_type = ocsp +- b.AddUint16(0) // empty responder_id_list +- b.AddUint16(0) // empty request_extensions +- }) +- } +- if len(m.supportedCurves) > 0 { +- // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7 +- b.AddUint16(extensionSupportedCurves) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, curve := range m.supportedCurves { +- b.AddUint16(uint16(curve)) +- } +- }) +- }) +- } +- if len(m.supportedPoints) > 0 { +- // RFC 4492, Section 5.1.2 +- b.AddUint16(extensionSupportedPoints) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.supportedPoints) +- }) +- }) +- } +- if m.ticketSupported { +- // RFC 5077, Section 3.2 +- b.AddUint16(extensionSessionTicket) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.sessionTicket) +- }) +- } +- if len(m.supportedSignatureAlgorithms) > 0 { +- // RFC 5246, Section 7.4.1.4.1 +- b.AddUint16(extensionSignatureAlgorithms) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, sigAlgo := range m.supportedSignatureAlgorithms { +- b.AddUint16(uint16(sigAlgo)) +- } +- }) +- }) +- } +- if len(m.supportedSignatureAlgorithmsCert) > 0 { +- // RFC 8446, Section 4.2.3 +- b.AddUint16(extensionSignatureAlgorithmsCert) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, sigAlgo := range m.supportedSignatureAlgorithmsCert { +- b.AddUint16(uint16(sigAlgo)) +- } +- }) +- }) +- } +- if m.secureRenegotiationSupported { +- // RFC 5746, Section 3.2 +- b.AddUint16(extensionRenegotiationInfo) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.secureRenegotiation) +- }) +- }) +- } +- if len(m.alpnProtocols) > 0 { +- // RFC 7301, Section 3.1 +- b.AddUint16(extensionALPN) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, proto := range m.alpnProtocols { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes([]byte(proto)) +- }) +- } +- }) +- }) +- } +- if m.scts { +- // RFC 6962, Section 3.3.1 +- b.AddUint16(extensionSCT) +- b.AddUint16(0) // empty extension_data +- } +- if len(m.supportedVersions) > 0 { +- // RFC 8446, Section 4.2.1 +- b.AddUint16(extensionSupportedVersions) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, vers := range m.supportedVersions { +- b.AddUint16(vers) +- } +- }) +- }) +- } +- if len(m.cookie) > 0 { +- // RFC 8446, Section 4.2.2 +- b.AddUint16(extensionCookie) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.cookie) +- }) +- }) +- } +- if len(m.keyShares) > 0 { +- // RFC 8446, Section 4.2.8 +- b.AddUint16(extensionKeyShare) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, ks := range m.keyShares { +- b.AddUint16(uint16(ks.group)) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(ks.data) +- }) +- } +- }) +- }) +- } +- if m.earlyData { +- // RFC 8446, Section 4.2.10 +- b.AddUint16(extensionEarlyData) +- b.AddUint16(0) // empty extension_data +- } +- if len(m.pskModes) > 0 { +- // RFC 8446, Section 4.2.9 +- b.AddUint16(extensionPSKModes) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.pskModes) +- }) +- }) +- } +- if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension +- // RFC 8446, Section 4.2.11 +- b.AddUint16(extensionPreSharedKey) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, psk := range m.pskIdentities { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(psk.label) +- }) +- b.AddUint32(psk.obfuscatedTicketAge) +- } +- }) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, binder := range m.pskBinders { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(binder) +- }) +- } +- }) +- }) +- } +- +- extensionsPresent = len(b.BytesOrPanic()) > 2 +- }) +- +- if !extensionsPresent { +- *b = bWithoutExtensions +- } +- }) ++ if len(extBytes) > 0 { ++ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { ++ b.AddBytes(extBytes) ++ }) ++ } ++ }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + // marshalWithoutBinders returns the ClientHello through the + // PreSharedKeyExtension.identities field, according to RFC 8446, Section + // 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length. +-func (m *clientHelloMsg) marshalWithoutBinders() []byte { ++func (m *clientHelloMsg) marshalWithoutBinders() ([]byte, error) { + bindersLen := 2 // uint16 length prefix + for _, binder := range m.pskBinders { + bindersLen += 1 // uint8 length prefix + bindersLen += len(binder) + } + +- fullMessage := m.marshal() +- return fullMessage[:len(fullMessage)-bindersLen] ++ fullMessage, err := m.marshal() ++ if err != nil { ++ return nil, err ++ } ++ return fullMessage[:len(fullMessage)-bindersLen], nil + } + + // updateBinders updates the m.pskBinders field, if necessary updating the + // cached marshaled representation. The supplied binders must have the same + // length as the current m.pskBinders. +-func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) { ++func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) error { + if len(pskBinders) != len(m.pskBinders) { +- panic("tls: internal error: pskBinders length mismatch") ++ return errors.New("tls: internal error: pskBinders length mismatch") + } + for i := range m.pskBinders { + if len(pskBinders[i]) != len(m.pskBinders[i]) { +- panic("tls: internal error: pskBinders length mismatch") ++ return errors.New("tls: internal error: pskBinders length mismatch") + } + } + m.pskBinders = pskBinders + if m.raw != nil { +- lenWithoutBinders := len(m.marshalWithoutBinders()) ++ helloBytes, err := m.marshalWithoutBinders() ++ if err != nil { ++ return err ++ } ++ lenWithoutBinders := len(helloBytes) + // TODO(filippo): replace with NewFixedBuilder once CL 148882 is imported. + b := cryptobyte.NewBuilder(m.raw[:lenWithoutBinders]) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +@@ -339,9 +346,11 @@ func (m *clientHelloMsg) updateBinders(p + } + }) + if len(b.BytesOrPanic()) != len(m.raw) { +- panic("tls: internal error: failed to update binders") ++ return errors.New("tls: internal error: failed to update binders") + } + } ++ ++ return nil + } + + func (m *clientHelloMsg) unmarshal(data []byte) bool { +@@ -613,9 +622,98 @@ type serverHelloMsg struct { + selectedGroup CurveID + } + +-func (m *serverHelloMsg) marshal() []byte { ++func (m *serverHelloMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil ++ } ++ ++ var exts cryptobyte.Builder ++ if m.ocspStapling { ++ exts.AddUint16(extensionStatusRequest) ++ exts.AddUint16(0) // empty extension_data ++ } ++ if m.ticketSupported { ++ exts.AddUint16(extensionSessionTicket) ++ exts.AddUint16(0) // empty extension_data ++ } ++ if m.secureRenegotiationSupported { ++ exts.AddUint16(extensionRenegotiationInfo) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.secureRenegotiation) ++ }) ++ }) ++ } ++ if len(m.alpnProtocol) > 0 { ++ exts.AddUint16(extensionALPN) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes([]byte(m.alpnProtocol)) ++ }) ++ }) ++ }) ++ } ++ if len(m.scts) > 0 { ++ exts.AddUint16(extensionSCT) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ for _, sct := range m.scts { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(sct) ++ }) ++ } ++ }) ++ }) ++ } ++ if m.supportedVersion != 0 { ++ exts.AddUint16(extensionSupportedVersions) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16(m.supportedVersion) ++ }) ++ } ++ if m.serverShare.group != 0 { ++ exts.AddUint16(extensionKeyShare) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16(uint16(m.serverShare.group)) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.serverShare.data) ++ }) ++ }) ++ } ++ if m.selectedIdentityPresent { ++ exts.AddUint16(extensionPreSharedKey) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16(m.selectedIdentity) ++ }) ++ } ++ ++ if len(m.cookie) > 0 { ++ exts.AddUint16(extensionCookie) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.cookie) ++ }) ++ }) ++ } ++ if m.selectedGroup != 0 { ++ exts.AddUint16(extensionKeyShare) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint16(uint16(m.selectedGroup)) ++ }) ++ } ++ if len(m.supportedPoints) > 0 { ++ exts.AddUint16(extensionSupportedPoints) ++ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) { ++ exts.AddBytes(m.supportedPoints) ++ }) ++ }) ++ } ++ ++ extBytes, err := exts.Bytes() ++ if err != nil { ++ return nil, err + } + + var b cryptobyte.Builder +@@ -629,104 +727,15 @@ func (m *serverHelloMsg) marshal() []byt + b.AddUint16(m.cipherSuite) + b.AddUint8(m.compressionMethod) + +- // If extensions aren't present, omit them. +- var extensionsPresent bool +- bWithoutExtensions := *b +- +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- if m.ocspStapling { +- b.AddUint16(extensionStatusRequest) +- b.AddUint16(0) // empty extension_data +- } +- if m.ticketSupported { +- b.AddUint16(extensionSessionTicket) +- b.AddUint16(0) // empty extension_data +- } +- if m.secureRenegotiationSupported { +- b.AddUint16(extensionRenegotiationInfo) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.secureRenegotiation) +- }) +- }) +- } +- if len(m.alpnProtocol) > 0 { +- b.AddUint16(extensionALPN) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes([]byte(m.alpnProtocol)) +- }) +- }) +- }) +- } +- if len(m.scts) > 0 { +- b.AddUint16(extensionSCT) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- for _, sct := range m.scts { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(sct) +- }) +- } +- }) +- }) +- } +- if m.supportedVersion != 0 { +- b.AddUint16(extensionSupportedVersions) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16(m.supportedVersion) +- }) +- } +- if m.serverShare.group != 0 { +- b.AddUint16(extensionKeyShare) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16(uint16(m.serverShare.group)) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.serverShare.data) +- }) +- }) +- } +- if m.selectedIdentityPresent { +- b.AddUint16(extensionPreSharedKey) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16(m.selectedIdentity) +- }) +- } +- +- if len(m.cookie) > 0 { +- b.AddUint16(extensionCookie) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.cookie) +- }) +- }) +- } +- if m.selectedGroup != 0 { +- b.AddUint16(extensionKeyShare) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint16(uint16(m.selectedGroup)) +- }) +- } +- if len(m.supportedPoints) > 0 { +- b.AddUint16(extensionSupportedPoints) +- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { +- b.AddBytes(m.supportedPoints) +- }) +- }) +- } +- +- extensionsPresent = len(b.BytesOrPanic()) > 2 +- }) +- +- if !extensionsPresent { +- *b = bWithoutExtensions ++ if len(extBytes) > 0 { ++ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { ++ b.AddBytes(extBytes) ++ }) + } + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func (m *serverHelloMsg) unmarshal(data []byte) bool { +@@ -844,9 +853,9 @@ type encryptedExtensionsMsg struct { + alpnProtocol string + } + +-func (m *encryptedExtensionsMsg) marshal() []byte { ++func (m *encryptedExtensionsMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var b cryptobyte.Builder +@@ -866,8 +875,9 @@ func (m *encryptedExtensionsMsg) marshal + }) + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ var err error ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool { +@@ -915,10 +925,10 @@ func (m *encryptedExtensionsMsg) unmarsh + + type endOfEarlyDataMsg struct{} + +-func (m *endOfEarlyDataMsg) marshal() []byte { ++func (m *endOfEarlyDataMsg) marshal() ([]byte, error) { + x := make([]byte, 4) + x[0] = typeEndOfEarlyData +- return x ++ return x, nil + } + + func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool { +@@ -930,9 +940,9 @@ type keyUpdateMsg struct { + updateRequested bool + } + +-func (m *keyUpdateMsg) marshal() []byte { ++func (m *keyUpdateMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var b cryptobyte.Builder +@@ -945,8 +955,9 @@ func (m *keyUpdateMsg) marshal() []byte + } + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ var err error ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func (m *keyUpdateMsg) unmarshal(data []byte) bool { +@@ -978,9 +989,9 @@ type newSessionTicketMsgTLS13 struct { + maxEarlyData uint32 + } + +-func (m *newSessionTicketMsgTLS13) marshal() []byte { ++func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var b cryptobyte.Builder +@@ -1005,8 +1016,9 @@ func (m *newSessionTicketMsgTLS13) marsh + }) + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ var err error ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool { +@@ -1059,9 +1071,9 @@ type certificateRequestMsgTLS13 struct { + certificateAuthorities [][]byte + } + +-func (m *certificateRequestMsgTLS13) marshal() []byte { ++func (m *certificateRequestMsgTLS13) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var b cryptobyte.Builder +@@ -1120,8 +1132,9 @@ func (m *certificateRequestMsgTLS13) mar + }) + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ var err error ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool { +@@ -1205,9 +1218,9 @@ type certificateMsg struct { + certificates [][]byte + } + +-func (m *certificateMsg) marshal() (x []byte) { ++func (m *certificateMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var i int +@@ -1216,7 +1229,7 @@ func (m *certificateMsg) marshal() (x [] + } + + length := 3 + 3*len(m.certificates) + i +- x = make([]byte, 4+length) ++ x := make([]byte, 4+length) + x[0] = typeCertificate + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) +@@ -1237,7 +1250,7 @@ func (m *certificateMsg) marshal() (x [] + } + + m.raw = x +- return ++ return m.raw, nil + } + + func (m *certificateMsg) unmarshal(data []byte) bool { +@@ -1284,9 +1297,9 @@ type certificateMsgTLS13 struct { + scts bool + } + +-func (m *certificateMsgTLS13) marshal() []byte { ++func (m *certificateMsgTLS13) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var b cryptobyte.Builder +@@ -1304,8 +1317,9 @@ func (m *certificateMsgTLS13) marshal() + marshalCertificate(b, certificate) + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ var err error ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) { +@@ -1428,9 +1442,9 @@ type serverKeyExchangeMsg struct { + key []byte + } + +-func (m *serverKeyExchangeMsg) marshal() []byte { ++func (m *serverKeyExchangeMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + length := len(m.key) + x := make([]byte, length+4) +@@ -1441,7 +1455,7 @@ func (m *serverKeyExchangeMsg) marshal() + copy(x[4:], m.key) + + m.raw = x +- return x ++ return x, nil + } + + func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool { +@@ -1458,9 +1472,9 @@ type certificateStatusMsg struct { + response []byte + } + +-func (m *certificateStatusMsg) marshal() []byte { ++func (m *certificateStatusMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var b cryptobyte.Builder +@@ -1472,8 +1486,9 @@ func (m *certificateStatusMsg) marshal() + }) + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ var err error ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func (m *certificateStatusMsg) unmarshal(data []byte) bool { +@@ -1492,10 +1507,10 @@ func (m *certificateStatusMsg) unmarshal + + type serverHelloDoneMsg struct{} + +-func (m *serverHelloDoneMsg) marshal() []byte { ++func (m *serverHelloDoneMsg) marshal() ([]byte, error) { + x := make([]byte, 4) + x[0] = typeServerHelloDone +- return x ++ return x, nil + } + + func (m *serverHelloDoneMsg) unmarshal(data []byte) bool { +@@ -1507,9 +1522,9 @@ type clientKeyExchangeMsg struct { + ciphertext []byte + } + +-func (m *clientKeyExchangeMsg) marshal() []byte { ++func (m *clientKeyExchangeMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + length := len(m.ciphertext) + x := make([]byte, length+4) +@@ -1520,7 +1535,7 @@ func (m *clientKeyExchangeMsg) marshal() + copy(x[4:], m.ciphertext) + + m.raw = x +- return x ++ return x, nil + } + + func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool { +@@ -1541,9 +1556,9 @@ type finishedMsg struct { + verifyData []byte + } + +-func (m *finishedMsg) marshal() []byte { ++func (m *finishedMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var b cryptobyte.Builder +@@ -1552,8 +1567,9 @@ func (m *finishedMsg) marshal() []byte { + b.AddBytes(m.verifyData) + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ var err error ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func (m *finishedMsg) unmarshal(data []byte) bool { +@@ -1575,9 +1591,9 @@ type certificateRequestMsg struct { + certificateAuthorities [][]byte + } + +-func (m *certificateRequestMsg) marshal() (x []byte) { ++func (m *certificateRequestMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + // See RFC 4346, Section 7.4.4. +@@ -1592,7 +1608,7 @@ func (m *certificateRequestMsg) marshal( + length += 2 + 2*len(m.supportedSignatureAlgorithms) + } + +- x = make([]byte, 4+length) ++ x := make([]byte, 4+length) + x[0] = typeCertificateRequest + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) +@@ -1627,7 +1643,7 @@ func (m *certificateRequestMsg) marshal( + } + + m.raw = x +- return ++ return m.raw, nil + } + + func (m *certificateRequestMsg) unmarshal(data []byte) bool { +@@ -1713,9 +1729,9 @@ type certificateVerifyMsg struct { + signature []byte + } + +-func (m *certificateVerifyMsg) marshal() (x []byte) { ++func (m *certificateVerifyMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + var b cryptobyte.Builder +@@ -1729,8 +1745,9 @@ func (m *certificateVerifyMsg) marshal() + }) + }) + +- m.raw = b.BytesOrPanic() +- return m.raw ++ var err error ++ m.raw, err = b.Bytes() ++ return m.raw, err + } + + func (m *certificateVerifyMsg) unmarshal(data []byte) bool { +@@ -1753,15 +1770,15 @@ type newSessionTicketMsg struct { + ticket []byte + } + +-func (m *newSessionTicketMsg) marshal() (x []byte) { ++func (m *newSessionTicketMsg) marshal() ([]byte, error) { + if m.raw != nil { +- return m.raw ++ return m.raw, nil + } + + // See RFC 5077, Section 3.3. + ticketLen := len(m.ticket) + length := 2 + 4 + ticketLen +- x = make([]byte, 4+length) ++ x := make([]byte, 4+length) + x[0] = typeNewSessionTicket + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) +@@ -1772,7 +1789,7 @@ func (m *newSessionTicketMsg) marshal() + + m.raw = x + +- return ++ return m.raw, nil + } + + func (m *newSessionTicketMsg) unmarshal(data []byte) bool { +@@ -1800,10 +1817,25 @@ func (m *newSessionTicketMsg) unmarshal( + type helloRequestMsg struct { + } + +-func (*helloRequestMsg) marshal() []byte { +- return []byte{typeHelloRequest, 0, 0, 0} ++func (*helloRequestMsg) marshal() ([]byte, error) { ++ return []byte{typeHelloRequest, 0, 0, 0}, nil + } + + func (*helloRequestMsg) unmarshal(data []byte) bool { + return len(data) == 4 + } ++ ++type transcriptHash interface { ++ Write([]byte) (int, error) ++} ++ ++// transcriptMsg is a helper used to marshal and hash messages which typically ++// are not written to the wire, and as such aren't hashed during Conn.writeRecord. ++func transcriptMsg(msg handshakeMessage, h transcriptHash) error { ++ data, err := msg.marshal() ++ if err != nil { ++ return err ++ } ++ h.Write(data) ++ return nil ++} +--- go.orig/src/crypto/tls/handshake_messages_test.go ++++ go/src/crypto/tls/handshake_messages_test.go +@@ -37,6 +37,15 @@ var tests = []interface{}{ + &certificateMsgTLS13{}, + } + ++func mustMarshal(t *testing.T, msg handshakeMessage) []byte { ++ t.Helper() ++ b, err := msg.marshal() ++ if err != nil { ++ t.Fatal(err) ++ } ++ return b ++} ++ + func TestMarshalUnmarshal(t *testing.T) { + rand := rand.New(rand.NewSource(time.Now().UnixNano())) + +@@ -55,7 +64,7 @@ func TestMarshalUnmarshal(t *testing.T) + } + + m1 := v.Interface().(handshakeMessage) +- marshaled := m1.marshal() ++ marshaled := mustMarshal(t, m1) + m2 := iface.(handshakeMessage) + if !m2.unmarshal(marshaled) { + t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled) +@@ -408,12 +417,12 @@ func TestRejectEmptySCTList(t *testing.T + + var random [32]byte + sct := []byte{0x42, 0x42, 0x42, 0x42} +- serverHello := serverHelloMsg{ ++ serverHello := &serverHelloMsg{ + vers: VersionTLS12, + random: random[:], + scts: [][]byte{sct}, + } +- serverHelloBytes := serverHello.marshal() ++ serverHelloBytes := mustMarshal(t, serverHello) + + var serverHelloCopy serverHelloMsg + if !serverHelloCopy.unmarshal(serverHelloBytes) { +@@ -451,12 +460,12 @@ func TestRejectEmptySCT(t *testing.T) { + // not be zero length. + + var random [32]byte +- serverHello := serverHelloMsg{ ++ serverHello := &serverHelloMsg{ + vers: VersionTLS12, + random: random[:], + scts: [][]byte{nil}, + } +- serverHelloBytes := serverHello.marshal() ++ serverHelloBytes := mustMarshal(t, serverHello) + + var serverHelloCopy serverHelloMsg + if serverHelloCopy.unmarshal(serverHelloBytes) { +--- go.orig/src/crypto/tls/handshake_server.go ++++ go/src/crypto/tls/handshake_server.go +@@ -129,7 +129,9 @@ func (hs *serverHandshakeState) handshak + + // readClientHello reads a ClientHello message and selects the protocol version. + func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) { +- msg, err := c.readHandshake() ++ // clientHelloMsg is included in the transcript, but we haven't initialized ++ // it yet. The respective handshake functions will record it themselves. ++ msg, err := c.readHandshake(nil) + if err != nil { + return nil, err + } +@@ -456,9 +458,10 @@ func (hs *serverHandshakeState) doResume + hs.hello.ticketSupported = hs.sessionState.usedOldKey + hs.finishedHash = newFinishedHash(c.vers, hs.suite) + hs.finishedHash.discardHandshakeBuffer() +- hs.finishedHash.Write(hs.clientHello.marshal()) +- hs.finishedHash.Write(hs.hello.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { ++ if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil { ++ return err ++ } ++ if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil { + return err + } + +@@ -496,24 +499,23 @@ func (hs *serverHandshakeState) doFullHa + // certificates won't be used. + hs.finishedHash.discardHandshakeBuffer() + } +- hs.finishedHash.Write(hs.clientHello.marshal()) +- hs.finishedHash.Write(hs.hello.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { ++ if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil { ++ return err ++ } ++ if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil { + return err + } + + certMsg := new(certificateMsg) + certMsg.certificates = hs.cert.Certificate +- hs.finishedHash.Write(certMsg.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil { + return err + } + + if hs.hello.ocspStapling { + certStatus := new(certificateStatusMsg) + certStatus.response = hs.cert.OCSPStaple +- hs.finishedHash.Write(certStatus.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certStatus, &hs.finishedHash); err != nil { + return err + } + } +@@ -525,8 +527,7 @@ func (hs *serverHandshakeState) doFullHa + return err + } + if skx != nil { +- hs.finishedHash.Write(skx.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(skx, &hs.finishedHash); err != nil { + return err + } + } +@@ -552,15 +553,13 @@ func (hs *serverHandshakeState) doFullHa + if c.config.ClientCAs != nil { + certReq.certificateAuthorities = c.config.ClientCAs.Subjects() + } +- hs.finishedHash.Write(certReq.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certReq, &hs.finishedHash); err != nil { + return err + } + } + + helloDone := new(serverHelloDoneMsg) +- hs.finishedHash.Write(helloDone.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(helloDone, &hs.finishedHash); err != nil { + return err + } + +@@ -570,7 +569,7 @@ func (hs *serverHandshakeState) doFullHa + + var pub crypto.PublicKey // public key for client auth, if any + +- msg, err := c.readHandshake() ++ msg, err := c.readHandshake(&hs.finishedHash) + if err != nil { + return err + } +@@ -583,7 +582,6 @@ func (hs *serverHandshakeState) doFullHa + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certMsg, msg) + } +- hs.finishedHash.Write(certMsg.marshal()) + + if err := c.processCertsFromClient(Certificate{ + Certificate: certMsg.certificates, +@@ -594,7 +592,7 @@ func (hs *serverHandshakeState) doFullHa + pub = c.peerCertificates[0].PublicKey + } + +- msg, err = c.readHandshake() ++ msg, err = c.readHandshake(&hs.finishedHash) + if err != nil { + return err + } +@@ -612,7 +610,6 @@ func (hs *serverHandshakeState) doFullHa + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(ckx, msg) + } +- hs.finishedHash.Write(ckx.marshal()) + + preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers) + if err != nil { +@@ -632,7 +629,10 @@ func (hs *serverHandshakeState) doFullHa + // to the client's certificate. This allows us to verify that the client is in + // possession of the private key of the certificate. + if len(c.peerCertificates) > 0 { +- msg, err = c.readHandshake() ++ // certificateVerifyMsg is included in the transcript, but not until ++ // after we verify the handshake signature, since the state before ++ // this message was sent is used. ++ msg, err = c.readHandshake(nil) + if err != nil { + return err + } +@@ -667,7 +667,9 @@ func (hs *serverHandshakeState) doFullHa + return errors.New("tls: invalid signature by the client certificate: " + err.Error()) + } + +- hs.finishedHash.Write(certVerify.marshal()) ++ if err := transcriptMsg(certVerify, &hs.finishedHash); err != nil { ++ return err ++ } + } + + hs.finishedHash.discardHandshakeBuffer() +@@ -707,7 +709,10 @@ func (hs *serverHandshakeState) readFini + return err + } + +- msg, err := c.readHandshake() ++ // finishedMsg is included in the transcript, but not until after we ++ // check the client version, since the state before this message was ++ // sent is used during verification. ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +@@ -724,7 +729,10 @@ func (hs *serverHandshakeState) readFini + return errors.New("tls: client's Finished message is incorrect") + } + +- hs.finishedHash.Write(clientFinished.marshal()) ++ if err := transcriptMsg(clientFinished, &hs.finishedHash); err != nil { ++ return err ++ } ++ + copy(out, verify) + return nil + } +@@ -758,14 +766,16 @@ func (hs *serverHandshakeState) sendSess + masterSecret: hs.masterSecret, + certificates: certsFromClient, + } +- var err error +- m.ticket, err = c.encryptTicket(state.marshal()) ++ stateBytes, err := state.marshal() ++ if err != nil { ++ return err ++ } ++ m.ticket, err = c.encryptTicket(stateBytes) + if err != nil { + return err + } + +- hs.finishedHash.Write(m.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(m, &hs.finishedHash); err != nil { + return err + } + +@@ -775,14 +785,13 @@ func (hs *serverHandshakeState) sendSess + func (hs *serverHandshakeState) sendFinished(out []byte) error { + c := hs.c + +- if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { ++ if err := c.writeChangeCipherRecord(); err != nil { + return err + } + + finished := new(finishedMsg) + finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) +- hs.finishedHash.Write(finished.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil { + return err + } + +--- go.orig/src/crypto/tls/handshake_server_test.go ++++ go/src/crypto/tls/handshake_server_test.go +@@ -30,6 +30,13 @@ func testClientHello(t *testing.T, serve + testClientHelloFailure(t, serverConfig, m, "") + } + ++// testFatal is a hack to prevent the compiler from complaining that there is a ++// call to t.Fatal from a non-test goroutine ++func testFatal(t *testing.T, err error) { ++ t.Helper() ++ t.Fatal(err) ++} ++ + func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) { + c, s := localPipe(t) + go func() { +@@ -37,7 +44,9 @@ func testClientHelloFailure(t *testing.T + if ch, ok := m.(*clientHelloMsg); ok { + cli.vers = ch.vers + } +- cli.writeRecord(recordTypeHandshake, m.marshal()) ++ if _, err := cli.writeHandshakeRecord(m, nil); err != nil { ++ testFatal(t, err) ++ } + c.Close() + }() + ctx := context.Background() +@@ -194,7 +203,9 @@ func TestRenegotiationExtension(t *testi + go func() { + cli := Client(c, testConfig) + cli.vers = clientHello.vers +- cli.writeRecord(recordTypeHandshake, clientHello.marshal()) ++ if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil { ++ testFatal(t, err) ++ } + + buf := make([]byte, 1024) + n, err := c.Read(buf) +@@ -253,8 +264,10 @@ func TestTLS12OnlyCipherSuites(t *testin + go func() { + cli := Client(c, testConfig) + cli.vers = clientHello.vers +- cli.writeRecord(recordTypeHandshake, clientHello.marshal()) +- reply, err := cli.readHandshake() ++ if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil { ++ testFatal(t, err) ++ } ++ reply, err := cli.readHandshake(nil) + c.Close() + if err != nil { + replyChan <- err +@@ -308,8 +321,10 @@ func TestTLSPointFormats(t *testing.T) { + go func() { + cli := Client(c, testConfig) + cli.vers = clientHello.vers +- cli.writeRecord(recordTypeHandshake, clientHello.marshal()) +- reply, err := cli.readHandshake() ++ if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil { ++ testFatal(t, err) ++ } ++ reply, err := cli.readHandshake(nil) + c.Close() + if err != nil { + replyChan <- err +@@ -1425,7 +1440,9 @@ func TestSNIGivenOnFailure(t *testing.T) + go func() { + cli := Client(c, testConfig) + cli.vers = clientHello.vers +- cli.writeRecord(recordTypeHandshake, clientHello.marshal()) ++ if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil { ++ testFatal(t, err) ++ } + c.Close() + }() + conn := Server(s, serverConfig) +--- go.orig/src/crypto/tls/handshake_server_tls13.go ++++ go/src/crypto/tls/handshake_server_tls13.go +@@ -298,7 +298,12 @@ func (hs *serverHandshakeStateTLS13) che + c.sendAlert(alertInternalError) + return errors.New("tls: internal error: failed to clone hash") + } +- transcript.Write(hs.clientHello.marshalWithoutBinders()) ++ clientHelloBytes, err := hs.clientHello.marshalWithoutBinders() ++ if err != nil { ++ c.sendAlert(alertInternalError) ++ return err ++ } ++ transcript.Write(clientHelloBytes) + pskBinder := hs.suite.finishedHash(binderKey, transcript) + if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) { + c.sendAlert(alertDecryptError) +@@ -389,8 +394,7 @@ func (hs *serverHandshakeStateTLS13) sen + } + hs.sentDummyCCS = true + +- _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) +- return err ++ return hs.c.writeChangeCipherRecord() + } + + func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error { +@@ -398,7 +402,9 @@ func (hs *serverHandshakeStateTLS13) doH + + // The first ClientHello gets double-hashed into the transcript upon a + // HelloRetryRequest. See RFC 8446, Section 4.4.1. +- hs.transcript.Write(hs.clientHello.marshal()) ++ if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil { ++ return err ++ } + chHash := hs.transcript.Sum(nil) + hs.transcript.Reset() + hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) +@@ -414,8 +420,7 @@ func (hs *serverHandshakeStateTLS13) doH + selectedGroup: selectedGroup, + } + +- hs.transcript.Write(helloRetryRequest.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(helloRetryRequest, hs.transcript); err != nil { + return err + } + +@@ -423,7 +428,8 @@ func (hs *serverHandshakeStateTLS13) doH + return err + } + +- msg, err := c.readHandshake() ++ // clientHelloMsg is not included in the transcript. ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +@@ -514,9 +520,10 @@ func illegalClientHelloChange(ch, ch1 *c + func (hs *serverHandshakeStateTLS13) sendServerParameters() error { + c := hs.c + +- hs.transcript.Write(hs.clientHello.marshal()) +- hs.transcript.Write(hs.hello.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { ++ if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil { ++ return err ++ } ++ if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil { + return err + } + +@@ -559,8 +566,7 @@ func (hs *serverHandshakeStateTLS13) sen + encryptedExtensions.alpnProtocol = selectedProto + c.clientProtocol = selectedProto + +- hs.transcript.Write(encryptedExtensions.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(encryptedExtensions, hs.transcript); err != nil { + return err + } + +@@ -589,8 +595,7 @@ func (hs *serverHandshakeStateTLS13) sen + certReq.certificateAuthorities = c.config.ClientCAs.Subjects() + } + +- hs.transcript.Write(certReq.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certReq, hs.transcript); err != nil { + return err + } + } +@@ -601,8 +606,7 @@ func (hs *serverHandshakeStateTLS13) sen + certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0 + certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 + +- hs.transcript.Write(certMsg.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil { + return err + } + +@@ -633,8 +637,7 @@ func (hs *serverHandshakeStateTLS13) sen + } + certVerifyMsg.signature = sig + +- hs.transcript.Write(certVerifyMsg.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil { + return err + } + +@@ -648,8 +651,7 @@ func (hs *serverHandshakeStateTLS13) sen + verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), + } + +- hs.transcript.Write(finished.marshal()) +- if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { ++ if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil { + return err + } + +@@ -710,7 +712,9 @@ func (hs *serverHandshakeStateTLS13) sen + finishedMsg := &finishedMsg{ + verifyData: hs.clientFinished, + } +- hs.transcript.Write(finishedMsg.marshal()) ++ if err := transcriptMsg(finishedMsg, hs.transcript); err != nil { ++ return err ++ } + + if !hs.shouldSendSessionTickets() { + return nil +@@ -735,8 +739,12 @@ func (hs *serverHandshakeStateTLS13) sen + SignedCertificateTimestamps: c.scts, + }, + } +- var err error +- m.label, err = c.encryptTicket(state.marshal()) ++ stateBytes, err := state.marshal() ++ if err != nil { ++ c.sendAlert(alertInternalError) ++ return err ++ } ++ m.label, err = c.encryptTicket(stateBytes) + if err != nil { + return err + } +@@ -755,7 +763,7 @@ func (hs *serverHandshakeStateTLS13) sen + // ticket_nonce, which must be unique per connection, is always left at + // zero because we only ever send one ticket per connection. + +- if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { ++ if _, err := c.writeHandshakeRecord(m, nil); err != nil { + return err + } + +@@ -780,7 +788,7 @@ func (hs *serverHandshakeStateTLS13) rea + // If we requested a client certificate, then the client must send a + // certificate message. If it's empty, no CertificateVerify is sent. + +- msg, err := c.readHandshake() ++ msg, err := c.readHandshake(hs.transcript) + if err != nil { + return err + } +@@ -790,7 +798,6 @@ func (hs *serverHandshakeStateTLS13) rea + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certMsg, msg) + } +- hs.transcript.Write(certMsg.marshal()) + + if err := c.processCertsFromClient(certMsg.certificate); err != nil { + return err +@@ -804,7 +811,10 @@ func (hs *serverHandshakeStateTLS13) rea + } + + if len(certMsg.certificate.Certificate) != 0 { +- msg, err = c.readHandshake() ++ // certificateVerifyMsg is included in the transcript, but not until ++ // after we verify the handshake signature, since the state before ++ // this message was sent is used. ++ msg, err = c.readHandshake(nil) + if err != nil { + return err + } +@@ -835,7 +845,9 @@ func (hs *serverHandshakeStateTLS13) rea + return errors.New("tls: invalid signature by the client certificate: " + err.Error()) + } + +- hs.transcript.Write(certVerify.marshal()) ++ if err := transcriptMsg(certVerify, hs.transcript); err != nil { ++ return err ++ } + } + + // If we waited until the client certificates to send session tickets, we +@@ -850,7 +862,8 @@ func (hs *serverHandshakeStateTLS13) rea + func (hs *serverHandshakeStateTLS13) readClientFinished() error { + c := hs.c + +- msg, err := c.readHandshake() ++ // finishedMsg is not included in the transcript. ++ msg, err := c.readHandshake(nil) + if err != nil { + return err + } +--- go.orig/src/crypto/tls/key_schedule.go ++++ go/src/crypto/tls/key_schedule.go +@@ -8,6 +8,7 @@ import ( + "crypto/elliptic" + "crypto/hmac" + "errors" ++ "fmt" + "hash" + "io" + "math/big" +@@ -42,8 +43,24 @@ func (c *cipherSuiteTLS13) expandLabel(s + hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(context) + }) ++ hkdfLabelBytes, err := hkdfLabel.Bytes() ++ if err != nil { ++ // Rather than calling BytesOrPanic, we explicitly handle this error, in ++ // order to provide a reasonable error message. It should be basically ++ // impossible for this to panic, and routing errors back through the ++ // tree rooted in this function is quite painful. The labels are fixed ++ // size, and the context is either a fixed-length computed hash, or ++ // parsed from a field which has the same length limitation. As such, an ++ // error here is likely to only be caused during development. ++ // ++ // NOTE: another reasonable approach here might be to return a ++ // randomized slice if we encounter an error, which would break the ++ // connection, but avoid panicking. This would perhaps be safer but ++ // significantly more confusing to users. ++ panic(fmt.Errorf("failed to construct HKDF label: %s", err)) ++ } + out := make([]byte, length) +- n, err := hkdf.Expand(c.hash.New, secret, hkdfLabel.BytesOrPanic()).Read(out) ++ n, err := hkdf.Expand(c.hash.New, secret, hkdfLabelBytes).Read(out) + if err != nil || n != length { + panic("tls: HKDF-Expand-Label invocation failed unexpectedly") + } +--- go.orig/src/crypto/tls/ticket.go ++++ go/src/crypto/tls/ticket.go +@@ -32,7 +32,7 @@ type sessionState struct { + usedOldKey bool + } + +-func (m *sessionState) marshal() []byte { ++func (m *sessionState) marshal() ([]byte, error) { + var b cryptobyte.Builder + b.AddUint16(m.vers) + b.AddUint16(m.cipherSuite) +@@ -47,7 +47,7 @@ func (m *sessionState) marshal() []byte + }) + } + }) +- return b.BytesOrPanic() ++ return b.Bytes() + } + + func (m *sessionState) unmarshal(data []byte) bool { +@@ -86,7 +86,7 @@ type sessionStateTLS13 struct { + certificate Certificate // CertificateEntry certificate_list<0..2^24-1>; + } + +-func (m *sessionStateTLS13) marshal() []byte { ++func (m *sessionStateTLS13) marshal() ([]byte, error) { + var b cryptobyte.Builder + b.AddUint16(VersionTLS13) + b.AddUint8(0) // revision +@@ -96,7 +96,7 @@ func (m *sessionStateTLS13) marshal() [] + b.AddBytes(m.resumptionSecret) + }) + marshalCertificate(&b, m.certificate) +- return b.BytesOrPanic() ++ return b.Bytes() + } + + func (m *sessionStateTLS13) unmarshal(data []byte) bool { diff --git a/meta/recipes-devtools/go/go-1.19/cve-2022-41725.patch b/meta/recipes-devtools/go/go-1.19/cve-2022-41725.patch new file mode 100644 index 0000000000..a71d07e3f1 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.19/cve-2022-41725.patch @@ -0,0 +1,652 @@ +From 5c55ac9bf1e5f779220294c843526536605f42ab Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Wed, 25 Jan 2023 09:27:01 -0800 +Subject: [PATCH] [release-branch.go1.19] mime/multipart: limit memory/inode + consumption of ReadForm + +Reader.ReadForm is documented as storing "up to maxMemory bytes + 10MB" +in memory. Parsed forms can consume substantially more memory than +this limit, since ReadForm does not account for map entry overhead +and MIME headers. + +In addition, while the amount of disk memory consumed by ReadForm can +be constrained by limiting the size of the parsed input, ReadForm will +create one temporary file per form part stored on disk, potentially +consuming a large number of inodes. + +Update ReadForm's memory accounting to include part names, +MIME headers, and map entry overhead. + +Update ReadForm to store all on-disk file parts in a single +temporary file. + +Files returned by FileHeader.Open are documented as having a concrete +type of *os.File when a file is stored on disk. The change to use a +single temporary file for all parts means that this is no longer the +case when a form contains more than a single file part stored on disk. + +The previous behavior of storing each file part in a separate disk +file may be reenabled with GODEBUG=multipartfiles=distinct. + +Update Reader.NextPart and Reader.NextRawPart to set a 10MiB cap +on the size of MIME headers. + +Thanks to Jakob Ackermann (@das7pad) for reporting this issue. + +Updates #58006 +Fixes #58362 +Fixes CVE-2022-41725 + +Change-Id: Ibd780a6c4c83ac8bcfd3cbe344f042e9940f2eab +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1714276 +Reviewed-by: Julie Qiu +TryBot-Result: Security TryBots +Reviewed-by: Roland Shoemaker +Run-TryBot: Damien Neil +(cherry picked from commit ed4664330edcd91b24914c9371c377c132dbce8c) +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1728949 +Reviewed-by: Tatiana Bradley +Run-TryBot: Roland Shoemaker +Reviewed-by: Damien Neil +Reviewed-on: https://go-review.googlesource.com/c/go/+/468116 +TryBot-Result: Gopher Robot +Reviewed-by: Than McIntosh +Run-TryBot: Michael Pratt +Auto-Submit: Michael Pratt +--- + +CVE: CVE-2022-41725 + +Upstream-Status: Backport [see text] + +https://github.com/golong/go.git commit 5c55ac9bf1e5... +modified for reader.go + +Signed-off-by: Joe Slater + +___ + src/mime/multipart/formdata.go | 132 ++++++++++++++++++++----- + src/mime/multipart/formdata_test.go | 140 ++++++++++++++++++++++++++- + src/mime/multipart/multipart.go | 25 +++-- + src/mime/multipart/readmimeheader.go | 14 +++ + src/net/http/request_test.go | 2 +- + src/net/textproto/reader.go | 20 +++- + 6 files changed, 295 insertions(+), 38 deletions(-) + create mode 100644 src/mime/multipart/readmimeheader.go + +--- go.orig/src/mime/multipart/formdata.go ++++ go/src/mime/multipart/formdata.go +@@ -7,6 +7,7 @@ package multipart + import ( + "bytes" + "errors" ++ "internal/godebug" + "io" + "math" + "net/textproto" +@@ -33,23 +34,58 @@ func (r *Reader) ReadForm(maxMemory int6 + + func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) { + form := &Form{make(map[string][]string), make(map[string][]*FileHeader)} ++ var ( ++ file *os.File ++ fileOff int64 ++ ) ++ numDiskFiles := 0 ++ multipartFiles := godebug.Get("multipartfiles") ++ combineFiles := multipartFiles != "distinct" + defer func() { ++ if file != nil { ++ if cerr := file.Close(); err == nil { ++ err = cerr ++ } ++ } ++ if combineFiles && numDiskFiles > 1 { ++ for _, fhs := range form.File { ++ for _, fh := range fhs { ++ fh.tmpshared = true ++ } ++ } ++ } + if err != nil { + form.RemoveAll() ++ if file != nil { ++ os.Remove(file.Name()) ++ } + } + }() + +- // Reserve an additional 10 MB for non-file parts. +- maxValueBytes := maxMemory + int64(10<<20) +- if maxValueBytes <= 0 { ++ // maxFileMemoryBytes is the maximum bytes of file data we will store in memory. ++ // Data past this limit is written to disk. ++ // This limit strictly applies to content, not metadata (filenames, MIME headers, etc.), ++ // since metadata is always stored in memory, not disk. ++ // ++ // maxMemoryBytes is the maximum bytes we will store in memory, including file content, ++ // non-file part values, metdata, and map entry overhead. ++ // ++ // We reserve an additional 10 MB in maxMemoryBytes for non-file data. ++ // ++ // The relationship between these parameters, as well as the overly-large and ++ // unconfigurable 10 MB added on to maxMemory, is unfortunate but difficult to change ++ // within the constraints of the API as documented. ++ maxFileMemoryBytes := maxMemory ++ maxMemoryBytes := maxMemory + int64(10<<20) ++ if maxMemoryBytes <= 0 { + if maxMemory < 0 { +- maxValueBytes = 0 ++ maxMemoryBytes = 0 + } else { +- maxValueBytes = math.MaxInt64 ++ maxMemoryBytes = math.MaxInt64 + } + } + for { +- p, err := r.NextPart() ++ p, err := r.nextPart(false, maxMemoryBytes) + if err == io.EOF { + break + } +@@ -63,16 +99,27 @@ func (r *Reader) readForm(maxMemory int6 + } + filename := p.FileName() + ++ // Multiple values for the same key (one map entry, longer slice) are cheaper ++ // than the same number of values for different keys (many map entries), but ++ // using a consistent per-value cost for overhead is simpler. ++ maxMemoryBytes -= int64(len(name)) ++ maxMemoryBytes -= 100 // map overhead ++ if maxMemoryBytes < 0 { ++ // We can't actually take this path, since nextPart would already have ++ // rejected the MIME headers for being too large. Check anyway. ++ return nil, ErrMessageTooLarge ++ } ++ + var b bytes.Buffer + + if filename == "" { + // value, store as string in memory +- n, err := io.CopyN(&b, p, maxValueBytes+1) ++ n, err := io.CopyN(&b, p, maxMemoryBytes+1) + if err != nil && err != io.EOF { + return nil, err + } +- maxValueBytes -= n +- if maxValueBytes < 0 { ++ maxMemoryBytes -= n ++ if maxMemoryBytes < 0 { + return nil, ErrMessageTooLarge + } + form.Value[name] = append(form.Value[name], b.String()) +@@ -80,35 +127,45 @@ func (r *Reader) readForm(maxMemory int6 + } + + // file, store in memory or on disk ++ maxMemoryBytes -= mimeHeaderSize(p.Header) ++ if maxMemoryBytes < 0 { ++ return nil, ErrMessageTooLarge ++ } + fh := &FileHeader{ + Filename: filename, + Header: p.Header, + } +- n, err := io.CopyN(&b, p, maxMemory+1) ++ n, err := io.CopyN(&b, p, maxFileMemoryBytes+1) + if err != nil && err != io.EOF { + return nil, err + } +- if n > maxMemory { +- // too big, write to disk and flush buffer +- file, err := os.CreateTemp("", "multipart-") +- if err != nil { +- return nil, err ++ if n > maxFileMemoryBytes { ++ if file == nil { ++ file, err = os.CreateTemp(r.tempDir, "multipart-") ++ if err != nil { ++ return nil, err ++ } + } ++ numDiskFiles++ + size, err := io.Copy(file, io.MultiReader(&b, p)) +- if cerr := file.Close(); err == nil { +- err = cerr +- } + if err != nil { +- os.Remove(file.Name()) + return nil, err + } + fh.tmpfile = file.Name() + fh.Size = size ++ fh.tmpoff = fileOff ++ fileOff += size ++ if !combineFiles { ++ if err := file.Close(); err != nil { ++ return nil, err ++ } ++ file = nil ++ } + } else { + fh.content = b.Bytes() + fh.Size = int64(len(fh.content)) +- maxMemory -= n +- maxValueBytes -= n ++ maxFileMemoryBytes -= n ++ maxMemoryBytes -= n + } + form.File[name] = append(form.File[name], fh) + } +@@ -116,6 +173,17 @@ func (r *Reader) readForm(maxMemory int6 + return form, nil + } + ++func mimeHeaderSize(h textproto.MIMEHeader) (size int64) { ++ for k, vs := range h { ++ size += int64(len(k)) ++ size += 100 // map entry overhead ++ for _, v := range vs { ++ size += int64(len(v)) ++ } ++ } ++ return size ++} ++ + // Form is a parsed multipart form. + // Its File parts are stored either in memory or on disk, + // and are accessible via the *FileHeader's Open method. +@@ -133,7 +201,7 @@ func (f *Form) RemoveAll() error { + for _, fh := range fhs { + if fh.tmpfile != "" { + e := os.Remove(fh.tmpfile) +- if e != nil && err == nil { ++ if e != nil && !errors.Is(e, os.ErrNotExist) && err == nil { + err = e + } + } +@@ -148,15 +216,25 @@ type FileHeader struct { + Header textproto.MIMEHeader + Size int64 + +- content []byte +- tmpfile string ++ content []byte ++ tmpfile string ++ tmpoff int64 ++ tmpshared bool + } + + // Open opens and returns the FileHeader's associated File. + func (fh *FileHeader) Open() (File, error) { + if b := fh.content; b != nil { + r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))) +- return sectionReadCloser{r}, nil ++ return sectionReadCloser{r, nil}, nil ++ } ++ if fh.tmpshared { ++ f, err := os.Open(fh.tmpfile) ++ if err != nil { ++ return nil, err ++ } ++ r := io.NewSectionReader(f, fh.tmpoff, fh.Size) ++ return sectionReadCloser{r, f}, nil + } + return os.Open(fh.tmpfile) + } +@@ -175,8 +253,12 @@ type File interface { + + type sectionReadCloser struct { + *io.SectionReader ++ io.Closer + } + + func (rc sectionReadCloser) Close() error { ++ if rc.Closer != nil { ++ return rc.Closer.Close() ++ } + return nil + } +--- go.orig/src/mime/multipart/formdata_test.go ++++ go/src/mime/multipart/formdata_test.go +@@ -6,8 +6,10 @@ package multipart + + import ( + "bytes" ++ "fmt" + "io" + "math" ++ "net/textproto" + "os" + "strings" + "testing" +@@ -208,8 +210,8 @@ Content-Disposition: form-data; name="la + maxMemory int64 + err error + }{ +- {"smaller", 50, nil}, +- {"exact-fit", 25, nil}, ++ {"smaller", 50 + int64(len("largetext")) + 100, nil}, ++ {"exact-fit", 25 + int64(len("largetext")) + 100, nil}, + {"too-large", 0, ErrMessageTooLarge}, + } + for _, tc := range testCases { +@@ -224,7 +226,7 @@ Content-Disposition: form-data; name="la + defer f.RemoveAll() + } + if tc.err != err { +- t.Fatalf("ReadForm error - got: %v; expected: %v", tc.err, err) ++ t.Fatalf("ReadForm error - got: %v; expected: %v", err, tc.err) + } + if err == nil { + if g := f.Value["largetext"][0]; g != largeTextValue { +@@ -234,3 +236,135 @@ Content-Disposition: form-data; name="la + }) + } + } ++ ++// TestReadForm_MetadataTooLarge verifies that we account for the size of field names, ++// MIME headers, and map entry overhead while limiting the memory consumption of parsed forms. ++func TestReadForm_MetadataTooLarge(t *testing.T) { ++ for _, test := range []struct { ++ name string ++ f func(*Writer) ++ }{{ ++ name: "large name", ++ f: func(fw *Writer) { ++ name := strings.Repeat("a", 10<<20) ++ w, _ := fw.CreateFormField(name) ++ w.Write([]byte("value")) ++ }, ++ }, { ++ name: "large MIME header", ++ f: func(fw *Writer) { ++ h := make(textproto.MIMEHeader) ++ h.Set("Content-Disposition", `form-data; name="a"`) ++ h.Set("X-Foo", strings.Repeat("a", 10<<20)) ++ w, _ := fw.CreatePart(h) ++ w.Write([]byte("value")) ++ }, ++ }, { ++ name: "many parts", ++ f: func(fw *Writer) { ++ for i := 0; i < 110000; i++ { ++ w, _ := fw.CreateFormField("f") ++ w.Write([]byte("v")) ++ } ++ }, ++ }} { ++ t.Run(test.name, func(t *testing.T) { ++ var buf bytes.Buffer ++ fw := NewWriter(&buf) ++ test.f(fw) ++ if err := fw.Close(); err != nil { ++ t.Fatal(err) ++ } ++ fr := NewReader(&buf, fw.Boundary()) ++ _, err := fr.ReadForm(0) ++ if err != ErrMessageTooLarge { ++ t.Errorf("fr.ReadForm() = %v, want ErrMessageTooLarge", err) ++ } ++ }) ++ } ++} ++ ++// TestReadForm_ManyFiles_Combined tests that a multipart form containing many files only ++// results in a single on-disk file. ++func TestReadForm_ManyFiles_Combined(t *testing.T) { ++ const distinct = false ++ testReadFormManyFiles(t, distinct) ++} ++ ++// TestReadForm_ManyFiles_Distinct tests that setting GODEBUG=multipartfiles=distinct ++// results in every file in a multipart form being placed in a distinct on-disk file. ++func TestReadForm_ManyFiles_Distinct(t *testing.T) { ++ t.Setenv("GODEBUG", "multipartfiles=distinct") ++ const distinct = true ++ testReadFormManyFiles(t, distinct) ++} ++ ++func testReadFormManyFiles(t *testing.T, distinct bool) { ++ var buf bytes.Buffer ++ fw := NewWriter(&buf) ++ const numFiles = 10 ++ for i := 0; i < numFiles; i++ { ++ name := fmt.Sprint(i) ++ w, err := fw.CreateFormFile(name, name) ++ if err != nil { ++ t.Fatal(err) ++ } ++ w.Write([]byte(name)) ++ } ++ if err := fw.Close(); err != nil { ++ t.Fatal(err) ++ } ++ fr := NewReader(&buf, fw.Boundary()) ++ fr.tempDir = t.TempDir() ++ form, err := fr.ReadForm(0) ++ if err != nil { ++ t.Fatal(err) ++ } ++ for i := 0; i < numFiles; i++ { ++ name := fmt.Sprint(i) ++ if got := len(form.File[name]); got != 1 { ++ t.Fatalf("form.File[%q] has %v entries, want 1", name, got) ++ } ++ fh := form.File[name][0] ++ file, err := fh.Open() ++ if err != nil { ++ t.Fatalf("form.File[%q].Open() = %v", name, err) ++ } ++ if distinct { ++ if _, ok := file.(*os.File); !ok { ++ t.Fatalf("form.File[%q].Open: %T, want *os.File", name, file) ++ } ++ } ++ got, err := io.ReadAll(file) ++ file.Close() ++ if string(got) != name || err != nil { ++ t.Fatalf("read form.File[%q]: %q, %v; want %q, nil", name, string(got), err, name) ++ } ++ } ++ dir, err := os.Open(fr.tempDir) ++ if err != nil { ++ t.Fatal(err) ++ } ++ defer dir.Close() ++ names, err := dir.Readdirnames(0) ++ if err != nil { ++ t.Fatal(err) ++ } ++ wantNames := 1 ++ if distinct { ++ wantNames = numFiles ++ } ++ if len(names) != wantNames { ++ t.Fatalf("temp dir contains %v files; want 1", len(names)) ++ } ++ if err := form.RemoveAll(); err != nil { ++ t.Fatalf("form.RemoveAll() = %v", err) ++ } ++ names, err = dir.Readdirnames(0) ++ if err != nil { ++ t.Fatal(err) ++ } ++ if len(names) != 0 { ++ t.Fatalf("temp dir contains %v files; want 0", len(names)) ++ } ++} +--- go.orig/src/mime/multipart/multipart.go ++++ go/src/mime/multipart/multipart.go +@@ -128,12 +128,12 @@ func (r *stickyErrorReader) Read(p []byt + return n, r.err + } + +-func newPart(mr *Reader, rawPart bool) (*Part, error) { ++func newPart(mr *Reader, rawPart bool, maxMIMEHeaderSize int64) (*Part, error) { + bp := &Part{ + Header: make(map[string][]string), + mr: mr, + } +- if err := bp.populateHeaders(); err != nil { ++ if err := bp.populateHeaders(maxMIMEHeaderSize); err != nil { + return nil, err + } + bp.r = partReader{bp} +@@ -149,12 +149,16 @@ func newPart(mr *Reader, rawPart bool) ( + return bp, nil + } + +-func (bp *Part) populateHeaders() error { ++func (bp *Part) populateHeaders(maxMIMEHeaderSize int64) error { + r := textproto.NewReader(bp.mr.bufReader) +- header, err := r.ReadMIMEHeader() ++ header, err := readMIMEHeader(r, maxMIMEHeaderSize) + if err == nil { + bp.Header = header + } ++ // TODO: Add a distinguishable error to net/textproto. ++ if err != nil && err.Error() == "message too large" { ++ err = ErrMessageTooLarge ++ } + return err + } + +@@ -294,6 +298,7 @@ func (p *Part) Close() error { + // isn't supported. + type Reader struct { + bufReader *bufio.Reader ++ tempDir string // used in tests + + currentPart *Part + partsRead int +@@ -304,6 +309,10 @@ type Reader struct { + dashBoundary []byte // "--boundary" + } + ++// maxMIMEHeaderSize is the maximum size of a MIME header we will parse, ++// including header keys, values, and map overhead. ++const maxMIMEHeaderSize = 10 << 20 ++ + // NextPart returns the next part in the multipart or an error. + // When there are no more parts, the error io.EOF is returned. + // +@@ -311,7 +320,7 @@ type Reader struct { + // has a value of "quoted-printable", that header is instead + // hidden and the body is transparently decoded during Read calls. + func (r *Reader) NextPart() (*Part, error) { +- return r.nextPart(false) ++ return r.nextPart(false, maxMIMEHeaderSize) + } + + // NextRawPart returns the next part in the multipart or an error. +@@ -320,10 +329,10 @@ func (r *Reader) NextPart() (*Part, erro + // Unlike NextPart, it does not have special handling for + // "Content-Transfer-Encoding: quoted-printable". + func (r *Reader) NextRawPart() (*Part, error) { +- return r.nextPart(true) ++ return r.nextPart(true, maxMIMEHeaderSize) + } + +-func (r *Reader) nextPart(rawPart bool) (*Part, error) { ++func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize int64) (*Part, error) { + if r.currentPart != nil { + r.currentPart.Close() + } +@@ -348,7 +357,7 @@ func (r *Reader) nextPart(rawPart bool) + + if r.isBoundaryDelimiterLine(line) { + r.partsRead++ +- bp, err := newPart(r, rawPart) ++ bp, err := newPart(r, rawPart, maxMIMEHeaderSize) + if err != nil { + return nil, err + } +--- /dev/null ++++ go/src/mime/multipart/readmimeheader.go +@@ -0,0 +1,14 @@ ++// Copyright 2023 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++package multipart ++ ++import ( ++ "net/textproto" ++ _ "unsafe" // for go:linkname ++) ++ ++// readMIMEHeader is defined in package net/textproto. ++// ++//go:linkname readMIMEHeader net/textproto.readMIMEHeader ++func readMIMEHeader(r *textproto.Reader, lim int64) (textproto.MIMEHeader, error) +--- go.orig/src/net/http/request_test.go ++++ go/src/net/http/request_test.go +@@ -1110,7 +1110,7 @@ func testMissingFile(t *testing.T, req * + t.Errorf("FormFile file = %v, want nil", f) + } + if fh != nil { +- t.Errorf("FormFile file header = %q, want nil", fh) ++ t.Errorf("FormFile file header = %v, want nil", fh) + } + if err != ErrMissingFile { + t.Errorf("FormFile err = %q, want ErrMissingFile", err) +--- go.orig/src/net/textproto/reader.go ++++ go/src/net/textproto/reader.go +@@ -7,8 +7,10 @@ package textproto + import ( + "bufio" + "bytes" ++ "errors" + "fmt" + "io" ++ "math" + "strconv" + "strings" + "sync" +@@ -481,6 +483,12 @@ func (r *Reader) ReadDotLines() ([]strin + // } + // + func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) { ++ return readMIMEHeader(r, math.MaxInt64) ++} ++ ++// readMIMEHeader is a version of ReadMIMEHeader which takes a limit on the header size. ++// It is called by the mime/multipart package. ++func readMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) { + // Avoid lots of small slice allocations later by allocating one + // large one ahead of time which we'll cut up into smaller + // slices. If this isn't big enough later, we allocate small ones. +@@ -521,6 +529,16 @@ func (r *Reader) ReadMIMEHeader() (MIMEH + continue + } + ++ // backport 5c55ac9bf1e5f779220294c843526536605f42ab ++ // ++ // value is computed as ++ // ++ // value := string(bytes.TrimLeft(v, " \t")) ++ // ++ // in the original patch from 1.19. This relies on ++ // 'v' which does not exist in 1.17. We leave the ++ // 1.17 method unchanged. ++ + // Skip initial spaces in value. + i++ // skip colon + for i < len(kv) && (kv[i] == ' ' || kv[i] == '\t') { +@@ -529,6 +547,16 @@ func (r *Reader) ReadMIMEHeader() (MIMEH + value := string(kv[i:]) + + vv := m[key] ++ if vv == nil { ++ lim -= int64(len(key)) ++ lim -= 100 // map entry overhead ++ } ++ lim -= int64(len(value)) ++ if lim < 0 { ++ // TODO: This should be a distinguishable error (ErrMessageTooLarge) ++ // to allow mime/multipart to detect it. ++ return m, errors.New("message too large") ++ } + if vv == nil && len(strs) > 0 { + // More than likely this will be a single-element key. + // Most headers aren't multi-valued. From patchwork Sat Apr 15 15:26:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 22649 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE5B3C77B70 for ; Sat, 15 Apr 2023 15:27:17 +0000 (UTC) Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.178]) by mx.groups.io with SMTP id smtpd.web11.10388.1681572428402728457 for ; Sat, 15 Apr 2023 08:27:08 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@sakoman-com.20221208.gappssmtp.com header.s=20221208 header.b=BnfY7Vho; spf=softfail (domain: sakoman.com, ip: 209.85.210.178, mailfrom: steve@sakoman.com) Received: by mail-pf1-f178.google.com with SMTP id d2e1a72fcca58-63b62d2f729so433809b3a.1 for ; Sat, 15 Apr 2023 08:27:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20221208.gappssmtp.com; s=20221208; t=1681572427; x=1684164427; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=xR8eyXG3SUI3Dy6xjaxgVB9PeDUcBvWiIVNl95g3fqs=; b=BnfY7VhoN1t+ws69MTbZjk3dRzOw9fdvCRf3sAn/+KluAI0nkZ78qyBD6GahD3nWiG CBzUz/+gONbazzY/y+P/fxpVog2iXiJOAHPdWfevjtmeGAKPJbip5N3BGz5lJVLWUo4U g8FnrvdfG51MTY26pg+x1AzRAibXO9DDuWlsZDcaX/9QQeipT6aeQTtnlurvemitCgJP 3W13uST0hU01WAeJ20mvY0Yz4OoYVksJ0E6Fto4ahWg8OtyLNsde74slbJowVh5X5BeZ xqj9WSWx0IMEvN2TCEyKAIO8hQ1FRmp7l5qrzznr6n16woGUfiglQccsJAULo9xWj07e Inhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681572427; x=1684164427; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xR8eyXG3SUI3Dy6xjaxgVB9PeDUcBvWiIVNl95g3fqs=; b=AmRigIR30Rn7HAMMBtUSjnal3zJbmjkEXG2yFMbmRh658ysQbaFva+oMdRKo4h1Co6 y4ZpsNGbRzqkQZvpaSWoD/r5fYn56zX/B11aMGbbhHHfSf74i5JHJ3+TUyqwp4aZ2UiE MiWCaOohw00VRR1whCXWULqfkIvGfX3hQtfF17ymEFImm/wou1zlktu+WswcK4ZqCdiq 90taT0s6CN90KcjLINAC+EDhDXgXfXlgby7/nABWn0jSmzTfCnDzeEy7lJTZxzzkInuW Q0vcNde2o1TAYFSCMr7WOrw25Gf8V9EvyL/ALF1NnamZ6399WdIN64cQUgpyit1EGg9N EVTg== X-Gm-Message-State: AAQBX9fqfBrOfRM1+5RLKVTfImNXj6AqkvhLB0Uj2p7VR3HvkvAJ3DJE Sn0AZMMmpl1688yc26VJcYm2DoO5AdBKbr1QHq4= X-Google-Smtp-Source: AKy350b7EYb9ovC4yNzvJKUjFH2GrDYFuZHRikKxiZOUu3OEbRVP4F536/OD37sgAbMosqVcyaa5dA== X-Received: by 2002:a05:6a00:22d6:b0:625:ebc3:b26c with SMTP id f22-20020a056a0022d600b00625ebc3b26cmr14380823pfj.22.1681572427384; Sat, 15 Apr 2023 08:27:07 -0700 (PDT) Received: from hexa.router0800d9.com (dhcp-72-253-4-112.hawaiiantel.net. [72.253.4.112]) by smtp.gmail.com with ESMTPSA id u22-20020aa78496000000b0063b1e7ffc5fsm4824410pfn.39.2023.04.15.08.27.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Apr 2023 08:27:07 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 6/7] openssl: Move microblaze to linux-latomic config Date: Sat, 15 Apr 2023 05:26:43 -1000 Message-Id: <26b4db753c4f2080a132fb176b514efafa3ff8e3.1681572283.git.steve@sakoman.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 15 Apr 2023 15:27:17 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/180016 From: Mark Hatle When building with the previous a number of atomic functions come back as undefined. Switching to linux-latomic fixes this. (From OE-Core rev: 88d5bf78ffb1d120df48139b1ed3c2e3fa8310d0) Signed-off-by: Mark Hatle Signed-off-by: Mark Hatle Signed-off-by: Luca Ceresoli Signed-off-by: Richard Purdie Signed-off-by: Steve Sakoman --- meta/recipes-connectivity/openssl/openssl_3.0.8.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meta/recipes-connectivity/openssl/openssl_3.0.8.bb b/meta/recipes-connectivity/openssl/openssl_3.0.8.bb index e1f30d7a47..82f3e18dd7 100644 --- a/meta/recipes-connectivity/openssl/openssl_3.0.8.bb +++ b/meta/recipes-connectivity/openssl/openssl_3.0.8.bb @@ -80,7 +80,7 @@ do_configure () { esac target="$os-${HOST_ARCH}" case $target in - linux-arc) + linux-arc | linux-microblaze*) target=linux-latomic ;; linux-arm*) @@ -108,7 +108,7 @@ do_configure () { linux-*-mips64 | linux-mips64 | linux-*-mips64el | linux-mips64el) target=linux64-mips64 ;; - linux-microblaze* | linux-nios2* | linux-sh3 | linux-sh4 | linux-arc*) + linux-nios2* | linux-sh3 | linux-sh4 | linux-arc*) target=linux-generic32 ;; linux-powerpc) From patchwork Sat Apr 15 15:26:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 22648 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE47CC7619A for ; Sat, 15 Apr 2023 15:27:17 +0000 (UTC) Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) by mx.groups.io with SMTP id smtpd.web11.10389.1681572430161420102 for ; Sat, 15 Apr 2023 08:27:10 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@sakoman-com.20221208.gappssmtp.com header.s=20221208 header.b=uaTmu3IG; spf=softfail (domain: sakoman.com, ip: 209.85.216.41, mailfrom: steve@sakoman.com) Received: by mail-pj1-f41.google.com with SMTP id kx14so1274174pjb.1 for ; Sat, 15 Apr 2023 08:27:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20221208.gappssmtp.com; s=20221208; t=1681572429; x=1684164429; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=yQG5QkkdxzMWaiywD+45WoZhYKSQYl/RBmgG4tXiWro=; b=uaTmu3IGeDLcg7tZKZ9ui78G51yJMz7qA/NDli6rS0W1tzIaSnumUtjQPF1wF42xZq phIJrb8Q8KpPNLtM/JD+Ts13hetV1C7XLHAPYZy7VdIYzonZrYT+QF3EC/ACt7Qk1kgW 0ifs3dUJCL7tsxjxOjImVet1UFr1f9RreA3j3IyNkZpJwAiAw6XRPPJULHurHkNs8Ju0 S+M+AySpks687G/3pbOlHnRgdJQJKn7CcBG76a0+iC0/9veA/C8h80oI4/0AW6rjxqfe AhO7fORXeuF8IfpaBGPxCp+OmgsZmb6FyHF0igZvo4IEC3hsewbylM6nYEdJPrruZ9f0 6R2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681572429; x=1684164429; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yQG5QkkdxzMWaiywD+45WoZhYKSQYl/RBmgG4tXiWro=; b=hDXaPezLa1DajwhBalumf4c4Fwu26OdHuwOseq5U0pY8p9yV15kz6bg2QQDFSGqD45 KX1lvJK5iQs7l3GrUDQw6GNF0dK8ops/mIFsLu+0MZOL/qOtdwjhPZwd2XuNYtrQIALY TX/3vlHkB32wgk4g55uaeMNCP1sKinvBLohSntT1KHSFKoaBAw1UIi/5uh1AR/3X6hG/ tvhqw8klHd+Um/sNgCdZGXT3RreJRrLIuQCkJQNwN+cR9cfZA135Z26Q1mkXAD2oOY3Z +G4Is+1mG6zmUh8aAy61cLI7mlewGR4TPW4MjoPGUmXWxd1E6T3HDAxH5iw9MG56sUO+ P2pA== X-Gm-Message-State: AAQBX9ePuGrbtWRD/c6I7uFjOav7SBhAATja2kVjU2DswY4UYb/UZmSO JHUtd03kNrvhi42cZgz1R+UZRvPjiPINqXdwxmU= X-Google-Smtp-Source: AKy350ai8hobaXQ1/wVJWi834oF9isAJfJJz1l4xduMpLo3wiJneW5qMoUpNUxrhV0LZTUnbAko2jg== X-Received: by 2002:a05:6a20:4927:b0:ea:e535:ce2c with SMTP id ft39-20020a056a20492700b000eae535ce2cmr8896838pzb.0.1681572429242; Sat, 15 Apr 2023 08:27:09 -0700 (PDT) Received: from hexa.router0800d9.com (dhcp-72-253-4-112.hawaiiantel.net. [72.253.4.112]) by smtp.gmail.com with ESMTPSA id u22-20020aa78496000000b0063b1e7ffc5fsm4824410pfn.39.2023.04.15.08.27.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Apr 2023 08:27:08 -0700 (PDT) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][kirkstone 7/7] package.bbclass: correct check for /build in copydebugsources() Date: Sat, 15 Apr 2023 05:26:44 -1000 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sat, 15 Apr 2023 15:27:17 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/180017 From: Peter Marko Newly introduced kirkstone-only commit https://git.openembedded.org/openembedded-core/commit/?h=kirkstone&id=80839835ec9fcb63069289225a3c1af257ffdef7 broke builds with externalsrc in Gitlab-CI. This is yocto-4.0.9 regression. It checks if directory starts with "build" instead of if checking if it equals to "build". Gitlab-CI uses directory "/builds" which matches the check but directory /build does not exist, only /builds. After successful check it tries to move this non-existent directory which does not exists and thus do_package fails. Signed-off-by: Peter Marko Signed-off-by: Steve Sakoman --- meta/classes/package.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass index 2950218145..67acc278d1 100644 --- a/meta/classes/package.bbclass +++ b/meta/classes/package.bbclass @@ -638,7 +638,7 @@ def copydebugsources(debugsrcdir, sources, d): if os.path.exists(dvar + debugsrcdir + sdir): # Special case for /build since we need to move into # /usr/src/debug/build so rename sdir to build.build - if sdir.find("/build") == 0: + if sdir == "/build" or sdir.find("/build/") == 0: cmd = "mv %s%s%s %s%s%s" % (dvar, debugsrcdir, "/build", dvar, debugsrcdir, "/build.build") subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) sdir = sdir.replace("/build", "/build.build", 1)