From patchwork Thu Aug 8 11:05:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Polampalli, Archana" X-Patchwork-Id: 47528 X-Patchwork-Delegate: steve@sakoman.com 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 290CDC52D73 for ; Thu, 8 Aug 2024 11:06:07 +0000 (UTC) Received: from mx0a-0064b401.pphosted.com (mx0a-0064b401.pphosted.com [205.220.166.238]) by mx.groups.io with SMTP id smtpd.web11.57399.1723115161115501884 for ; Thu, 08 Aug 2024 04:06:01 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.166.238, mailfrom: prvs=8950103a07=archana.polampalli@windriver.com) Received: from pps.filterd (m0250810.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4784OW3w004144 for ; Thu, 8 Aug 2024 04:06:00 -0700 Received: from ala-exchng01.corp.ad.wrs.com (ala-exchng01.wrs.com [147.11.82.252]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 40v0hv9g0q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 08 Aug 2024 04:06:00 -0700 (PDT) Received: from blr-linux-engg1.wrs.com (147.11.136.210) by ala-exchng01.corp.ad.wrs.com (147.11.82.252) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 8 Aug 2024 04:05:58 -0700 From: To: Subject: [oe-core][kirkstone][PATCH 1/3] ghostscript: fix CVE-2024-29509 Date: Thu, 8 Aug 2024 11:05:42 +0000 Message-ID: <20240808110544.2591803-1-archana.polampalli@windriver.com> X-Mailer: git-send-email 2.40.0 MIME-Version: 1.0 X-Originating-IP: [147.11.136.210] X-ClientProxiedBy: ala-exchng01.corp.ad.wrs.com (147.11.82.252) To ala-exchng01.corp.ad.wrs.com (147.11.82.252) X-Proofpoint-ORIG-GUID: ZlzCClHFEwb0ss0aj4bC9XCxMHttCP6s X-Proofpoint-GUID: ZlzCClHFEwb0ss0aj4bC9XCxMHttCP6s X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-08-08_11,2024-08-07_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 mlxscore=0 spamscore=0 impostorscore=0 clxscore=1011 bulkscore=0 mlxlogscore=999 priorityscore=1501 lowpriorityscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.21.0-2407110000 definitions=main-2408080079 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 ; Thu, 08 Aug 2024 11:06:07 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/203132 From: Archana Polampalli Signed-off-by: Archana Polampalli --- .../ghostscript/CVE-2024-29509.patch | 45 +++++++++++++++++++ .../ghostscript/ghostscript_9.55.0.bb | 1 + 2 files changed, 46 insertions(+) create mode 100644 meta/recipes-extended/ghostscript/ghostscript/CVE-2024-29509.patch diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2024-29509.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2024-29509.patch new file mode 100644 index 0000000000..8de97f91a0 --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2024-29509.patch @@ -0,0 +1,45 @@ +From 917b3a71fb20748965254631199ad98210d6c2fb Mon Sep 17 00:00:00 2001 +From: Ken Sharp +Date: Thu, 25 Jan 2024 11:58:22 +0000 +Subject: [PATCH] Bug 707510 - don't use strlen on passwords + +Item #1 of the report. This looks like an oversight when first coding +the routine. We should use the PostScript string length, because +PostScript strings may not be NULL terminated (and as here may contain +internal NULL characters). + +Fix the R6 handler which has the same problem too. + +CVE: CVE-2024-29509 + +Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=917b3a71fb20748965254631199ad98210d6c2fb] + +Signed-off-by: Archana Polampalli +--- + pdf/pdf_sec.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/pdf/pdf_sec.c b/pdf/pdf_sec.c +index ff60805..2bb59e1 100644 +--- a/pdf/pdf_sec.c ++++ b/pdf/pdf_sec.c +@@ -1250,7 +1250,7 @@ static int check_password_R5(pdf_context *ctx, char *Password, int PasswordLen, + if (code < 0) { + pdf_string *P = NULL, *P_UTF8 = NULL; + +- code = pdfi_object_alloc(ctx, PDF_STRING, strlen(ctx->encryption.Password), (pdf_obj **)&P); ++ code = pdfi_object_alloc(ctx, PDF_STRING, PasswordLen, (pdf_obj **)&P); + if (code < 0) { + return code; + } +@@ -1300,7 +1300,7 @@ static int check_password_R6(pdf_context *ctx, char *Password, int PasswordLen, + if (code < 0) { + pdf_string *P = NULL, *P_UTF8 = NULL; + +- code = pdfi_object_alloc(ctx, PDF_STRING, strlen(ctx->encryption.Password), (pdf_obj **)&P); ++ code = pdfi_object_alloc(ctx, PDF_STRING, PasswordLen, (pdf_obj **)&P); + if (code < 0) + return code; + memcpy(P->data, Password, PasswordLen); +-- +2.40.0 diff --git a/meta/recipes-extended/ghostscript/ghostscript_9.55.0.bb b/meta/recipes-extended/ghostscript/ghostscript_9.55.0.bb index ab4a2def4c..f738b0133f 100644 --- a/meta/recipes-extended/ghostscript/ghostscript_9.55.0.bb +++ b/meta/recipes-extended/ghostscript/ghostscript_9.55.0.bb @@ -52,6 +52,7 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d file://CVE-2023-52722.patch \ file://CVE-2024-29511-0001.patch \ file://CVE-2024-29511-0002.patch \ + file://CVE-2024-29509.patch \ " SRC_URI = "${SRC_URI_BASE} \ From patchwork Thu Aug 8 11:05:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Polampalli, Archana" X-Patchwork-Id: 47529 X-Patchwork-Delegate: steve@sakoman.com 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 2817DC52D6F for ; Thu, 8 Aug 2024 11:06:07 +0000 (UTC) Received: from mx0a-0064b401.pphosted.com (mx0a-0064b401.pphosted.com [205.220.166.238]) by mx.groups.io with SMTP id smtpd.web11.57401.1723115162722541184 for ; Thu, 08 Aug 2024 04:06:02 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.166.238, mailfrom: prvs=8950103a07=archana.polampalli@windriver.com) Received: from pps.filterd (m0250810.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4789fdJe025659 for ; Thu, 8 Aug 2024 04:06:02 -0700 Received: from ala-exchng01.corp.ad.wrs.com (ala-exchng01.wrs.com [147.11.82.252]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 40v0hv9g0t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 08 Aug 2024 04:06:02 -0700 (PDT) Received: from blr-linux-engg1.wrs.com (147.11.136.210) by ala-exchng01.corp.ad.wrs.com (147.11.82.252) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 8 Aug 2024 04:06:00 -0700 From: To: Subject: [oe-core][kirkstone][PATCH 2/3] ghostscript: fix CVE-2024-29506 Date: Thu, 8 Aug 2024 11:05:43 +0000 Message-ID: <20240808110544.2591803-2-archana.polampalli@windriver.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20240808110544.2591803-1-archana.polampalli@windriver.com> References: <20240808110544.2591803-1-archana.polampalli@windriver.com> MIME-Version: 1.0 X-Originating-IP: [147.11.136.210] X-ClientProxiedBy: ala-exchng01.corp.ad.wrs.com (147.11.82.252) To ala-exchng01.corp.ad.wrs.com (147.11.82.252) X-Proofpoint-ORIG-GUID: WNMtJ1fvxG9S_QKKuJlCNJJWUxYeOyou X-Proofpoint-GUID: WNMtJ1fvxG9S_QKKuJlCNJJWUxYeOyou X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-08-08_11,2024-08-07_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 mlxscore=0 spamscore=0 impostorscore=0 clxscore=1015 bulkscore=0 mlxlogscore=999 priorityscore=1501 lowpriorityscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.21.0-2407110000 definitions=main-2408080079 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 ; Thu, 08 Aug 2024 11:06:07 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/203133 From: Archana Polampalli Signed-off-by: Archana Polampalli --- .../ghostscript/CVE-2024-29506.patch | 45 +++++++++++++++++++ .../ghostscript/ghostscript_9.55.0.bb | 1 + 2 files changed, 46 insertions(+) create mode 100644 meta/recipes-extended/ghostscript/ghostscript/CVE-2024-29506.patch diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2024-29506.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2024-29506.patch new file mode 100644 index 0000000000..9f3f3e5da2 --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2024-29506.patch @@ -0,0 +1,45 @@ +From 77dc7f699beba606937b7ea23b50cf5974fa64b1 Mon Sep 17 00:00:00 2001 +From: Ken Sharp +Date: Thu, 25 Jan 2024 11:55:49 +0000 +Subject: [PATCH] Bug 707510 - don't allow PDF files with bad Filters to + overflow the debug buffer + +Item #2 of the report. + +Allocate a buffer to hold the filter name, instead of assuming it will +fit in a fixed buffer. + +Reviewed all the other PDFDEBUG cases, no others use a fixed buffer like +this. + +CVE: CVE-2024-29506 + +Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=77dc7f699beba606937b7ea23b50cf5974fa64b1] + +Signed-off-by: Archana Polampalli +--- + pdf/pdf_file.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/pdf/pdf_file.c b/pdf/pdf_file.c +index 214d448..93c2402 100644 +--- a/pdf/pdf_file.c ++++ b/pdf/pdf_file.c +@@ -767,10 +767,14 @@ static int pdfi_apply_filter(pdf_context *ctx, pdf_dict *dict, pdf_name *n, pdf_ + + if (ctx->args.pdfdebug) + { +- char str[100]; ++ char *str; ++ str = gs_alloc_bytes(ctx->memory, n->length + 1, "temp string for debug"); ++ if (str == NULL) ++ return_error(gs_error_VMerror); + memcpy(str, (const char *)n->data, n->length); + str[n->length] = '\0'; + dmprintf1(ctx->memory, "FILTER NAME:%s\n", str); ++ gs_free_object(ctx->memory, str, "temp string for debug"); + } + + if (pdfi_name_is(n, "RunLengthDecode")) { +-- +2.40.0 diff --git a/meta/recipes-extended/ghostscript/ghostscript_9.55.0.bb b/meta/recipes-extended/ghostscript/ghostscript_9.55.0.bb index f738b0133f..525086e2af 100644 --- a/meta/recipes-extended/ghostscript/ghostscript_9.55.0.bb +++ b/meta/recipes-extended/ghostscript/ghostscript_9.55.0.bb @@ -53,6 +53,7 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d file://CVE-2024-29511-0001.patch \ file://CVE-2024-29511-0002.patch \ file://CVE-2024-29509.patch \ + file://CVE-2024-29506.patch \ " SRC_URI = "${SRC_URI_BASE} \ From patchwork Thu Aug 8 11:05:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Polampalli, Archana" X-Patchwork-Id: 47530 X-Patchwork-Delegate: steve@sakoman.com 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 381F9C3DA4A for ; Thu, 8 Aug 2024 11:06:07 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.web10.57395.1723115165668106037 for ; Thu, 08 Aug 2024 04:06:05 -0700 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=8950103a07=archana.polampalli@windriver.com) Received: from pps.filterd (m0250811.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 47870nv6004821 for ; Thu, 8 Aug 2024 11:06:05 GMT Received: from ala-exchng01.corp.ad.wrs.com (ala-exchng01.wrs.com [147.11.82.252]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 40v0bshgfp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 08 Aug 2024 11:06:04 +0000 (GMT) Received: from blr-linux-engg1.wrs.com (147.11.136.210) by ala-exchng01.corp.ad.wrs.com (147.11.82.252) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 8 Aug 2024 04:06:02 -0700 From: To: Subject: [oe-core][kirkstone][PATCH 3/3] go: fix CVE-2024-24791 Date: Thu, 8 Aug 2024 11:05:44 +0000 Message-ID: <20240808110544.2591803-3-archana.polampalli@windriver.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20240808110544.2591803-1-archana.polampalli@windriver.com> References: <20240808110544.2591803-1-archana.polampalli@windriver.com> MIME-Version: 1.0 X-Originating-IP: [147.11.136.210] X-ClientProxiedBy: ala-exchng01.corp.ad.wrs.com (147.11.82.252) To ala-exchng01.corp.ad.wrs.com (147.11.82.252) X-Proofpoint-ORIG-GUID: sQLFrTJ_jIo_i65Q4qgEyQ3pek6LbsVK X-Proofpoint-GUID: sQLFrTJ_jIo_i65Q4qgEyQ3pek6LbsVK X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-08-08_11,2024-08-07_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 bulkscore=0 phishscore=0 spamscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 adultscore=0 mlxscore=0 mlxlogscore=999 clxscore=1015 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.21.0-2407110000 definitions=main-2408080079 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 ; Thu, 08 Aug 2024 11:06:07 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/203134 From: Archana Polampalli Signed-off-by: Archana Polampalli --- meta/recipes-devtools/go/go-1.17.13.inc | 1 + .../go/go-1.21/CVE-2024-24791.patch | 359 ++++++++++++++++++ 2 files changed, 360 insertions(+) create mode 100644 meta/recipes-devtools/go/go-1.21/CVE-2024-24791.patch diff --git a/meta/recipes-devtools/go/go-1.17.13.inc b/meta/recipes-devtools/go/go-1.17.13.inc index 95fb572362..ed4428b22e 100644 --- a/meta/recipes-devtools/go/go-1.17.13.inc +++ b/meta/recipes-devtools/go/go-1.17.13.inc @@ -56,6 +56,7 @@ SRC_URI += "\ file://CVE-2024-24784.patch \ file://CVE-2024-24785.patch \ file://CVE-2023-45288.patch \ + file://CVE-2024-24791.patch \ " SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd" diff --git a/meta/recipes-devtools/go/go-1.21/CVE-2024-24791.patch b/meta/recipes-devtools/go/go-1.21/CVE-2024-24791.patch new file mode 100644 index 0000000000..9f6a969cf6 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.21/CVE-2024-24791.patch @@ -0,0 +1,359 @@ +From c9be6ae748b7679b644a38182d456cb5a6ac06ee Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Thu, 6 Jun 2024 12:50:46 -0700 +Subject: [PATCH] [release-branch.go1.21] net/http: send body or close + connection on expect-100-continue requests + +When sending a request with an "Expect: 100-continue" header, +we must send the request body before sending any further requests +on the connection. + +When receiving a non-1xx response to an "Expect: 100-continue" request, +send the request body if the connection isn't being closed after +processing the response. In other words, if either the request +or response contains a "Connection: close" header, then skip sending +the request body (because the connection will not be used for +further requests), but otherwise send it. + +Correct a comment on the server-side Expect: 100-continue handling +that implied sending the request body is optional. It isn't. + +For #67555 +Fixes #68199 + +Change-Id: Ia2f12091bee697771087f32ac347509ec5922d54 +Reviewed-on: https://go-review.googlesource.com/c/go/+/591255 +LUCI-TryBot-Result: Go LUCI +Reviewed-by: Jonathan Amsterdam +(cherry picked from commit cf501e05e138e6911f759a5db786e90b295499b9) +Reviewed-on: https://go-review.googlesource.com/c/go/+/595096 +Reviewed-by: Joedian Reid +Reviewed-by: Dmitri Shuralyov + +CVE: CVE-2024-24791 + +Upstream-Status: Backport [https://github.com/golang/go/commit/c9be6ae748b7679b644a38182d456cb5a6ac06ee ] + +Signed-off-by: Archana Polampalli +--- + src/net/http/server.go | 25 ++-- + src/net/http/transport.go | 34 ++++-- + src/net/http/transport_test.go | 203 ++++++++++++++++++++------------- + 3 files changed, 164 insertions(+), 98 deletions(-) + +diff --git a/src/net/http/server.go b/src/net/http/server.go +index 4fc8fed..1648f1c 100644 +--- a/src/net/http/server.go ++++ b/src/net/http/server.go +@@ -1297,16 +1297,21 @@ func (cw *chunkWriter) writeHeader(p []byte) { + + // If the client wanted a 100-continue but we never sent it to + // them (or, more strictly: we never finished reading their +- // request body), don't reuse this connection because it's now +- // in an unknown state: we might be sending this response at +- // the same time the client is now sending its request body +- // after a timeout. (Some HTTP clients send Expect: +- // 100-continue but knowing that some servers don't support +- // it, the clients set a timer and send the body later anyway) +- // If we haven't seen EOF, we can't skip over the unread body +- // because we don't know if the next bytes on the wire will be +- // the body-following-the-timer or the subsequent request. +- // See Issue 11549. ++ // request body), don't reuse this connection. ++ // ++ // This behavior was first added on the theory that we don't know ++ // if the next bytes on the wire are going to be the remainder of ++ // the request body or the subsequent request (see issue 11549), ++ // but that's not correct: If we keep using the connection, ++ // the client is required to send the request body whether we ++ // asked for it or not. ++ // ++ // We probably do want to skip reusing the connection in most cases, ++ // however. If the client is offering a large request body that we ++ // don't intend to use, then it's better to close the connection ++ // than to read the body. For now, assume that if we're sending ++ // headers, the handler is done reading the body and we should ++ // drop the connection if we haven't seen EOF. + if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.isSet() { + w.closeAfterReply = true + } +diff --git a/src/net/http/transport.go b/src/net/http/transport.go +index 309194e..e46ddef 100644 +--- a/src/net/http/transport.go ++++ b/src/net/http/transport.go +@@ -2282,17 +2282,12 @@ func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTr + return + } + resCode := resp.StatusCode +- if continueCh != nil { +- if resCode == 100 { +- if trace != nil && trace.Got100Continue != nil { +- trace.Got100Continue() +- } +- continueCh <- struct{}{} +- continueCh = nil +- } else if resCode >= 200 { +- close(continueCh) +- continueCh = nil ++ if continueCh != nil && resCode == StatusContinue { ++ if trace != nil && trace.Got100Continue != nil { ++ trace.Got100Continue() + } ++ continueCh <- struct{}{} ++ continueCh = nil + } + is1xx := 100 <= resCode && resCode <= 199 + // treat 101 as a terminal status, see issue 26161 +@@ -2315,6 +2310,25 @@ func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTr + if resp.isProtocolSwitch() { + resp.Body = newReadWriteCloserBody(pc.br, pc.conn) + } ++ if continueCh != nil { ++ // We send an "Expect: 100-continue" header, but the server ++ // responded with a terminal status and no 100 Continue. ++ // ++ // If we're going to keep using the connection, we need to send the request body. ++ // Tell writeLoop to skip sending the body if we're going to close the connection, ++ // or to send it otherwise. ++ // ++ // The case where we receive a 101 Switching Protocols response is a bit ++ // ambiguous, since we don't know what protocol we're switching to. ++ // Conceivably, it's one that doesn't need us to send the body. ++ // Given that we'll send the body if ExpectContinueTimeout expires, ++ // be consistent and always send it if we aren't closing the connection. ++ if resp.Close || rc.req.Close { ++ close(continueCh) // don't send the body; the connection will close ++ } else { ++ continueCh <- struct{}{} // send the body ++ } ++ } + + resp.TLS = pc.tlsState + return +diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go +index 58f12af..8000ecc 100644 +--- a/src/net/http/transport_test.go ++++ b/src/net/http/transport_test.go +@@ -1130,95 +1130,142 @@ func TestTransportGzip(t *testing.T) { + } + } + +-// If a request has Expect:100-continue header, the request blocks sending body until the first response. +-// Premature consumption of the request body should not be occurred. +-func TestTransportExpect100Continue(t *testing.T) { +- setParallel(t) +- defer afterTest(t) ++// A transport100Continue test exercises Transport behaviors when sending a ++// request with an Expect: 100-continue header. ++type transport100ContinueTest struct { ++ t *testing.T + +- ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { +- switch req.URL.Path { +- case "/100": +- // This endpoint implicitly responds 100 Continue and reads body. +- if _, err := io.Copy(io.Discard, req.Body); err != nil { +- t.Error("Failed to read Body", err) +- } +- rw.WriteHeader(StatusOK) +- case "/200": +- // Go 1.5 adds Connection: close header if the client expect +- // continue but not entire request body is consumed. +- rw.WriteHeader(StatusOK) +- case "/500": +- rw.WriteHeader(StatusInternalServerError) +- case "/keepalive": +- // This hijacked endpoint responds error without Connection:close. +- _, bufrw, err := rw.(Hijacker).Hijack() +- if err != nil { +- log.Fatal(err) +- } +- bufrw.WriteString("HTTP/1.1 500 Internal Server Error\r\n") +- bufrw.WriteString("Content-Length: 0\r\n\r\n") +- bufrw.Flush() +- case "/timeout": +- // This endpoint tries to read body without 100 (Continue) response. +- // After ExpectContinueTimeout, the reading will be started. +- conn, bufrw, err := rw.(Hijacker).Hijack() +- if err != nil { +- log.Fatal(err) +- } +- if _, err := io.CopyN(io.Discard, bufrw, req.ContentLength); err != nil { +- t.Error("Failed to read Body", err) +- } +- bufrw.WriteString("HTTP/1.1 200 OK\r\n\r\n") +- bufrw.Flush() +- conn.Close() +- } ++ reqdone chan struct{} ++ resp *Response ++ respErr error + +- })) +- defer ts.Close() ++ conn net.Conn ++ reader *bufio.Reader ++} + +- tests := []struct { +- path string +- body []byte +- sent int +- status int +- }{ +- {path: "/100", body: []byte("hello"), sent: 5, status: 200}, // Got 100 followed by 200, entire body is sent. +- {path: "/200", body: []byte("hello"), sent: 0, status: 200}, // Got 200 without 100. body isn't sent. +- {path: "/500", body: []byte("hello"), sent: 0, status: 500}, // Got 500 without 100. body isn't sent. +- {path: "/keepalive", body: []byte("hello"), sent: 0, status: 500}, // Although without Connection:close, body isn't sent. +- {path: "/timeout", body: []byte("hello"), sent: 5, status: 200}, // Timeout exceeded and entire body is sent. ++const transport100ContinueTestBody = "request body" ++ ++// newTransport100ContinueTest creates a Transport and sends an Expect: 100-continue ++// request on it. ++func newTransport100ContinueTest(t *testing.T, timeout time.Duration) *transport100ContinueTest { ++ ln := newLocalListener(t) ++ defer ln.Close() ++ ++ test := &transport100ContinueTest{ ++ t: t, ++ reqdone: make(chan struct{}), + } + +- c := ts.Client() +- for i, v := range tests { +- tr := &Transport{ +- ExpectContinueTimeout: 2 * time.Second, +- } +- defer tr.CloseIdleConnections() +- c.Transport = tr +- body := bytes.NewReader(v.body) +- req, err := NewRequest("PUT", ts.URL+v.path, body) +- if err != nil { +- t.Fatal(err) +- } ++ tr := &Transport{ ++ ExpectContinueTimeout: timeout, ++ } ++ go func() { ++ defer close(test.reqdone) ++ body := strings.NewReader(transport100ContinueTestBody) ++ req, _ := NewRequest("PUT", "http://"+ln.Addr().String(), body) + req.Header.Set("Expect", "100-continue") +- req.ContentLength = int64(len(v.body)) ++ req.ContentLength = int64(len(transport100ContinueTestBody)) ++ test.resp, test.respErr = tr.RoundTrip(req) ++ test.resp.Body.Close() ++ }() + +- resp, err := c.Do(req) +- if err != nil { +- t.Fatal(err) ++ c, err := ln.Accept() ++ if err != nil { ++ t.Fatalf("Accept: %v", err) ++ } ++ t.Cleanup(func() { ++ c.Close() ++ }) ++ br := bufio.NewReader(c) ++ _, err = ReadRequest(br) ++ if err != nil { ++ t.Fatalf("ReadRequest: %v", err) ++ } ++ test.conn = c ++ test.reader = br ++ t.Cleanup(func() { ++ <-test.reqdone ++ tr.CloseIdleConnections() ++ got, _ := io.ReadAll(test.reader) ++ if len(got) > 0 { ++ t.Fatalf("Transport sent unexpected bytes: %q", got) + } +- resp.Body.Close() ++ }) + +- sent := len(v.body) - body.Len() +- if v.status != resp.StatusCode { +- t.Errorf("test %d: status code should be %d but got %d. (%s)", i, v.status, resp.StatusCode, v.path) +- } +- if v.sent != sent { +- t.Errorf("test %d: sent body should be %d but sent %d. (%s)", i, v.sent, sent, v.path) ++ return test ++} ++ ++// respond sends response lines from the server to the transport. ++func (test *transport100ContinueTest) respond(lines ...string) { ++ for _, line := range lines { ++ if _, err := test.conn.Write([]byte(line + "\r\n")); err != nil { ++ test.t.Fatalf("Write: %v", err) + } + } ++ if _, err := test.conn.Write([]byte("\r\n")); err != nil { ++ test.t.Fatalf("Write: %v", err) ++ } ++} ++ ++// wantBodySent ensures the transport has sent the request body to the server. ++func (test *transport100ContinueTest) wantBodySent() { ++ got, err := io.ReadAll(io.LimitReader(test.reader, int64(len(transport100ContinueTestBody)))) ++ if err != nil { ++ test.t.Fatalf("unexpected error reading body: %v", err) ++ } ++ if got, want := string(got), transport100ContinueTestBody; got != want { ++ test.t.Fatalf("unexpected body: got %q, want %q", got, want) ++ } ++} ++ ++// wantRequestDone ensures the Transport.RoundTrip has completed with the expected status. ++func (test *transport100ContinueTest) wantRequestDone(want int) { ++ <-test.reqdone ++ if test.respErr != nil { ++ test.t.Fatalf("unexpected RoundTrip error: %v", test.respErr) ++ } ++ if got := test.resp.StatusCode; got != want { ++ test.t.Fatalf("unexpected response code: got %v, want %v", got, want) ++ } ++} ++ ++func TestTransportExpect100ContinueSent(t *testing.T) { ++ test := newTransport100ContinueTest(t, 1*time.Hour) ++ // Server sends a 100 Continue response, and the client sends the request body. ++ test.respond("HTTP/1.1 100 Continue") ++ test.wantBodySent() ++ test.respond("HTTP/1.1 200", "Content-Length: 0") ++ test.wantRequestDone(200) ++} ++ ++func TestTransportExpect100Continue200ResponseNoConnClose(t *testing.T) { ++ test := newTransport100ContinueTest(t, 1*time.Hour) ++ // No 100 Continue response, no Connection: close header. ++ test.respond("HTTP/1.1 200", "Content-Length: 0") ++ test.wantBodySent() ++ test.wantRequestDone(200) ++} ++ ++func TestTransportExpect100Continue200ResponseWithConnClose(t *testing.T) { ++ test := newTransport100ContinueTest(t, 1*time.Hour) ++ // No 100 Continue response, Connection: close header set. ++ test.respond("HTTP/1.1 200", "Connection: close", "Content-Length: 0") ++ test.wantRequestDone(200) ++} ++ ++func TestTransportExpect100Continue500ResponseNoConnClose(t *testing.T) { ++ test := newTransport100ContinueTest(t, 1*time.Hour) ++ // No 100 Continue response, no Connection: close header. ++ test.respond("HTTP/1.1 500", "Content-Length: 0") ++ test.wantBodySent() ++ test.wantRequestDone(500) ++} ++ ++func TestTransportExpect100Continue500ResponseTimeout(t *testing.T) { ++ test := newTransport100ContinueTest(t, 5*time.Millisecond) // short timeout ++ test.wantBodySent() // after timeout ++ test.respond("HTTP/1.1 200", "Content-Length: 0") ++ test.wantRequestDone(200) + } + + func TestSOCKS5Proxy(t *testing.T) { +-- +2.40.0