Subject: [bug#73361] [PATCH] gnu: curl: Update to 8.10.1 [security fixes].

From: "Ashish SHUKLA" <[email-masked]>
Date: Sat, 28 Sep 2024 01:24:05 +0000

On Fri Sep 27, 2024 at 8:52 PM CEST, John Kehayias wrote:
> Hello,
>
> On Thu, Sep 19, 2024 at 03:17 PM, Ashish SHUKLA wrote:
>
> > * gnu/packages/curl.scm (curl): Update to 8.10.1.
> >
>
> As curl causes a rebuild of just about everything, this will need to
> done as a graft on master. (And ungrafted with a world rebuild on a
> branch.) Would you like to take a stab at that?

Prepared a new revision (attached) to add a new package 'curl/fixed' 
with just the fix from upstream applied[0][1].

As for the actual update to 8.10.1, I can send a patch (either in this 
thread, or in separate issue report).

Please let me know if something is amiss with my patch.

References:
[0] https://curl.se/docs/CVE-2024-8096.html
[1] https://github.com/curl/curl/commit/aeb1a281cab13c7ba

Thanks!
--
Ashish SHUKLA | GPG: F682 CDCC 39DC 0FEA E116  20B6 C746 CFA9 E74F A4B0

"If I destroy you, what business is it of yours ?" (Dark Forest, Liu Cixin)

From 82e4c9fdf2e4bc78dfad87ee956fd78051bbc763 Mon Sep 17 00:00:00 2001
Message-ID: <8[email-masked]>
From: Ashish SHUKLA <[email-masked]>
Date: Sat, 28 Sep 2024 01:40:45 +0200
Subject: [PATCH v2] gnu: curl: Fix security vulnerability.

Fixes CVE-2024-8096.

* gnu/packages/curl.scm (curl)[replacement]: New field.
(curl/fixed): New variable.
* gnu/packages/patches/curl-CVE-2024-8096.patch: New file.
* gnu/local.mk (dist_patch_DATA): Register it.

Change-Id: I42facad095d97dc94302e9db60626b9fa00f3738
---
 gnu/local.mk                                  |   1 +
 gnu/packages/curl.scm                         |  11 +
 gnu/packages/patches/curl-CVE-2024-8096.patch | 200 ++++++++++++++++++
 3 files changed, 212 insertions(+)
 create mode 100644 gnu/packages/patches/curl-CVE-2024-8096.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 9fdad12b63..a2215ad4c2 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1114,6 +1114,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/crda-optional-gcrypt.patch		\
   %D%/packages/patches/clucene-contribs-lib.patch               \
   %D%/packages/patches/cube-nocheck.patch			\
+  %D%/packages/patches/curl-CVE-2024-8096.patch			\
   %D%/packages/patches/curl-use-ssl-cert-env.patch		\
   %D%/packages/patches/curlftpfs-fix-error-closing-file.patch	\
   %D%/packages/patches/curlftpfs-fix-file-names.patch		\
diff --git a/gnu/packages/curl.scm b/gnu/packages/curl.scm
index 9f74018205..bbb266e236 100644
--- a/gnu/packages/curl.scm
+++ b/gnu/packages/curl.scm
@@ -16,6 +16,7 @@
 ;;; Copyright © 2021 Felix Gruber <[email-masked]>
 ;;; Copyright © 2023 Sharlatan Hellseher <[email-masked]>
 ;;; Copyright © 2023 John Kehayias <[email-masked]>
+;;; Copyright © 2024 Ashish SHUKLA <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -67,6 +68,7 @@ (define-public curl
   (package
     (name "curl")
     (version "8.6.0")
+    (replacement curl/fixed)
     (source (origin
               (method url-fetch)
               (uri (string-append "https://curl.se/download/curl-"
@@ -176,6 +178,15 @@ (define-public curl
                                    "See COPYING in the distribution."))
     (home-page "https://curl.haxx.se/")))
 
+(define-public curl/fixed
+  (hidden-package
+   (package
+     (inherit curl)
+     (replacement curl/fixed)
+     (source (origin
+               (inherit (package-source curl))
+               (patches (search-patches "curl-CVE-2024-8096.patch")))))))
+
 (define-public gnurl (deprecated-package "gnurl" curl))
 
 (define-public curl-ssh
diff --git a/gnu/packages/patches/curl-CVE-2024-8096.patch b/gnu/packages/patches/curl-CVE-2024-8096.patch
new file mode 100644
index 0000000000..0f780f08c3
--- /dev/null
+++ b/gnu/packages/patches/curl-CVE-2024-8096.patch
@@ -0,0 +1,200 @@
+From aeb1a281cab13c7ba791cb104e556b20e713941f Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email-masked]>
+Date: Tue, 20 Aug 2024 16:14:39 +0200
+Subject: [PATCH] gtls: fix OCSP stapling management
+
+Reported-by: Hiroki Kurosawa
+Closes #14642
+---
+ lib/vtls/gtls.c | 146 ++++++++++++++++++++++++------------------------
+ 1 file changed, 73 insertions(+), 73 deletions(-)
+
+diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
+index 03d6fcc038aac3..c7589d9d39bc81 100644
+--- a/lib/vtls/gtls.c
++++ b/lib/vtls/gtls.c
+@@ -850,6 +850,13 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf,
+   init_flags |= GNUTLS_NO_TICKETS;
+ #endif
+ 
++#if defined(GNUTLS_NO_STATUS_REQUEST)
++  if(!config->verifystatus)
++    /* Disable the "status_request" TLS extension, enabled by default since
++       GnuTLS 3.8.0. */
++    init_flags |= GNUTLS_NO_STATUS_REQUEST;
++#endif
++
+   rc = gnutls_init(&gtls->session, init_flags);
+   if(rc != GNUTLS_E_SUCCESS) {
+     failf(data, "gnutls_init() failed: %d", rc);
+@@ -1321,104 +1328,97 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
+     infof(data, "  server certificate verification SKIPPED");
+ 
+   if(config->verifystatus) {
+-    if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
+-      gnutls_datum_t status_request;
+-      gnutls_ocsp_resp_t ocsp_resp;
++    gnutls_datum_t status_request;
++    gnutls_ocsp_resp_t ocsp_resp;
++    gnutls_ocsp_cert_status_t status;
++    gnutls_x509_crl_reason_t reason;
+ 
+-      gnutls_ocsp_cert_status_t status;
+-      gnutls_x509_crl_reason_t reason;
++    rc = gnutls_ocsp_status_request_get(session, &status_request);
+ 
+-      rc = gnutls_ocsp_status_request_get(session, &status_request);
++    if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
++      failf(data, "No OCSP response received");
++      return CURLE_SSL_INVALIDCERTSTATUS;
++    }
+ 
+-      infof(data, " server certificate status verification FAILED");
++    if(rc < 0) {
++      failf(data, "Invalid OCSP response received");
++      return CURLE_SSL_INVALIDCERTSTATUS;
++    }
+ 
+-      if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+-        failf(data, "No OCSP response received");
+-        return CURLE_SSL_INVALIDCERTSTATUS;
+-      }
++    gnutls_ocsp_resp_init(&ocsp_resp);
+ 
+-      if(rc < 0) {
+-        failf(data, "Invalid OCSP response received");
+-        return CURLE_SSL_INVALIDCERTSTATUS;
+-      }
++    rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
++    if(rc < 0) {
++      failf(data, "Invalid OCSP response received");
++      return CURLE_SSL_INVALIDCERTSTATUS;
++    }
+ 
+-      gnutls_ocsp_resp_init(&ocsp_resp);
++    (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
++                                      &status, NULL, NULL, NULL, &reason);
+ 
+-      rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
+-      if(rc < 0) {
+-        failf(data, "Invalid OCSP response received");
+-        return CURLE_SSL_INVALIDCERTSTATUS;
+-      }
++    switch(status) {
++    case GNUTLS_OCSP_CERT_GOOD:
++      break;
+ 
+-      (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
+-                                        &status, NULL, NULL, NULL, &reason);
++    case GNUTLS_OCSP_CERT_REVOKED: {
++      const char *crl_reason;
+ 
+-      switch(status) {
+-      case GNUTLS_OCSP_CERT_GOOD:
++      switch(reason) {
++      default:
++      case GNUTLS_X509_CRLREASON_UNSPECIFIED:
++        crl_reason = "unspecified reason";
+         break;
+ 
+-      case GNUTLS_OCSP_CERT_REVOKED: {
+-        const char *crl_reason;
+-
+-        switch(reason) {
+-          default:
+-          case GNUTLS_X509_CRLREASON_UNSPECIFIED:
+-            crl_reason = "unspecified reason";
+-            break;
+-
+-          case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
+-            crl_reason = "private key compromised";
+-            break;
+-
+-          case GNUTLS_X509_CRLREASON_CACOMPROMISE:
+-            crl_reason = "CA compromised";
+-            break;
+-
+-          case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
+-            crl_reason = "affiliation has changed";
+-            break;
++      case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
++        crl_reason = "private key compromised";
++        break;
+ 
+-          case GNUTLS_X509_CRLREASON_SUPERSEDED:
+-            crl_reason = "certificate superseded";
+-            break;
++      case GNUTLS_X509_CRLREASON_CACOMPROMISE:
++        crl_reason = "CA compromised";
++        break;
+ 
+-          case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
+-            crl_reason = "operation has ceased";
+-            break;
++      case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
++        crl_reason = "affiliation has changed";
++        break;
+ 
+-          case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
+-            crl_reason = "certificate is on hold";
+-            break;
++      case GNUTLS_X509_CRLREASON_SUPERSEDED:
++        crl_reason = "certificate superseded";
++        break;
+ 
+-          case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
+-            crl_reason = "will be removed from delta CRL";
+-            break;
++      case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
++        crl_reason = "operation has ceased";
++        break;
+ 
+-          case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
+-            crl_reason = "privilege withdrawn";
+-            break;
++      case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
++        crl_reason = "certificate is on hold";
++        break;
+ 
+-          case GNUTLS_X509_CRLREASON_AACOMPROMISE:
+-            crl_reason = "AA compromised";
+-            break;
+-        }
++      case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
++        crl_reason = "will be removed from delta CRL";
++        break;
+ 
+-        failf(data, "Server certificate was revoked: %s", crl_reason);
++      case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
++        crl_reason = "privilege withdrawn";
+         break;
+-      }
+ 
+-      default:
+-      case GNUTLS_OCSP_CERT_UNKNOWN:
+-        failf(data, "Server certificate status is unknown");
++      case GNUTLS_X509_CRLREASON_AACOMPROMISE:
++        crl_reason = "AA compromised";
+         break;
+       }
+ 
+-      gnutls_ocsp_resp_deinit(ocsp_resp);
++      failf(data, "Server certificate was revoked: %s", crl_reason);
++      break;
++    }
+ 
+-      return CURLE_SSL_INVALIDCERTSTATUS;
++    default:
++    case GNUTLS_OCSP_CERT_UNKNOWN:
++      failf(data, "Server certificate status is unknown");
++      break;
+     }
+-    else
+-      infof(data, "  server certificate status verification OK");
++
++    gnutls_ocsp_resp_deinit(ocsp_resp);
++    if(status != GNUTLS_OCSP_CERT_GOOD)
++      return CURLE_SSL_INVALIDCERTSTATUS;
+   }
+   else
+     infof(data, "  server certificate status verification SKIPPED");

base-commit: 5e888ec915cfdd256e726959cdc23293bc36277e
-- 
2.46.1