diff --git a/.curl.checksum b/.curl.checksum
index fa911ff730af80d89f2a079acd319253e4011aef..dfba0881e9ce388b204cf2e18faee2e36a71d231 100644
--- a/.curl.checksum
+++ b/.curl.checksum
@@ -1 +1 @@
-d6fd57f998fd22f5a8adc5ab523d72bcfb936ec0154c9a92d3067ba13406bbc2
+041ce8183798bc2a0df672adf54830ab71cbf73474233d8a0818eda07f4d0df7
diff --git a/SOURCES/0054-curl-7.61.1-64K-sftp.patch b/SOURCES/0054-curl-7.61.1-64K-sftp.patch
new file mode 100644
index 0000000000000000000000000000000000000000..136a4bf2bdb433c4f4a2a3bde8fcd1ae6ab4c856
--- /dev/null
+++ b/SOURCES/0054-curl-7.61.1-64K-sftp.patch
@@ -0,0 +1,31 @@
+From 35eb2614d86316ba9f5a6806ce64f56680fa1e97 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Tue, 5 Sep 2023 17:33:41 +0200
+Subject: [PATCH] libssh: cap SFTP packet size sent
+
+Due to libssh limitations
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+
+Closes #11804
+---
+ lib/ssh-libssh.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
+index dea0084575859..7c6a2e53f338f 100644
+--- a/lib/ssh-libssh.c
++++ b/lib/ssh-libssh.c
+@@ -2412,6 +2412,12 @@ static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
+   ssize_t nwrite;
+   (void)sockindex;
+ 
++  /* limit the writes to the maximum specified in Section 3 of
++   * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02
++   */
++  if(len > 32768)
++    len = 32768;
++
+   nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
+ 
+   myssh_block2waitfor(conn, FALSE);
diff --git a/SOURCES/0056-curl-7.61.1-CVE-2023-38546.patch b/SOURCES/0056-curl-7.61.1-CVE-2023-38546.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4aa552b4ff58373e583239bf928961b9a24f3af0
--- /dev/null
+++ b/SOURCES/0056-curl-7.61.1-CVE-2023-38546.patch
@@ -0,0 +1,124 @@
+From 61275672b46d9abb3285740467b882e22ed75da8 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Thu, 14 Sep 2023 23:28:32 +0200
+Subject: [PATCH] cookie: remove unnecessary struct fields
+
+Plus: reduce the hash table size from 256 to 63. It seems unlikely to
+make much of a speed difference for most use cases but saves 1.5KB of
+data per instance.
+
+Closes #11862
+---
+ lib/cookie.c | 13 +------------
+ lib/cookie.h | 13 ++++---------
+ lib/easy.c   |  4 +---
+ 3 files changed, 6 insertions(+), 24 deletions(-)
+
+diff --git a/lib/cookie.c b/lib/cookie.c
+index 4345a84c6fd9d..e39c89a94a960 100644
+--- a/lib/cookie.c
++++ b/lib/cookie.c
+@@ -119,7 +119,6 @@ static void freecookie(struct Cookie *co)
+   free(co->name);
+   free(co->value);
+   free(co->maxage);
+-  free(co->version);
+   free(co);
+ }
+ 
+@@ -717,11 +716,7 @@ Curl_cookie_add(struct Curl_easy *data,
+           }
+         }
+         else if(strcasecompare("version", name)) {
+-          strstore(&co->version, whatptr);
+-          if(!co->version) {
+-            badcookie = TRUE;
+-            break;
+-          }
++          /* just ignore */
+         }
+         else if(strcasecompare("max-age", name)) {
+           /* Defined in RFC2109:
+@@ -1159,7 +1154,6 @@ Curl_cookie_add(struct Curl_easy *data,
+         free(clist->path);
+         free(clist->spath);
+         free(clist->expirestr);
+-        free(clist->version);
+         free(clist->maxage);
+ 
+         *clist = *co;  /* then store all the new data */
+@@ -1223,9 +1217,6 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
+     c = calloc(1, sizeof(struct CookieInfo));
+     if(!c)
+       return NULL; /* failed to get memory */
+-    c->filename = strdup(file?file:"none"); /* copy the name just in case */
+-    if(!c->filename)
+-      goto fail; /* failed to get memory */
+   }
+   else {
+     /* we got an already existing one, use that */
+@@ -1378,7 +1369,6 @@ static struct Cookie *dup_cookie(struct Cookie *src)
+     CLONE(name);
+     CLONE(value);
+     CLONE(maxage);
+-    CLONE(version);
+     d->expires = src->expires;
+     d->tailmatch = src->tailmatch;
+     d->secure = src->secure;
+@@ -1595,7 +1585,6 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
+ {
+   if(c) {
+     unsigned int i;
+-    free(c->filename);
+     for(i = 0; i < COOKIE_HASH_SIZE; i++)
+       Curl_cookie_freelist(c->cookies[i]);
+     free(c); /* free the base struct as well */
+diff --git a/lib/cookie.h b/lib/cookie.h
+index b3c0063b2cfb2..41e9e7a6914e0 100644
+--- a/lib/cookie.h
++++ b/lib/cookie.h
+@@ -36,11 +36,7 @@ struct Cookie {
+   curl_off_t expires;  /* expires = <this> */
+   char *expirestr;   /* the plain text version */
+   bool tailmatch;    /* whether we do tail-matching of the domain name */
+-
+-  /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
+-  char *version;     /* Version = <value> */
+   char *maxage;      /* Max-Age = <value> */
+-
+   bool secure;       /* whether the 'secure' keyword was used */
+   bool livecookie;   /* updated from a server, not a stored file */
+   bool httponly;     /* true if the httponly directive is present */
+@@ -56,15 +52,14 @@ struct Cookie {
+   int creationtime;  /* time when the cookie was written */
+ };
+ 
+-#define COOKIE_HASH_SIZE 256
++#define COOKIE_HASH_SIZE 63
+ 
+ struct CookieInfo {
+   /* linked list of cookies we know of */
+   struct Cookie *cookies[COOKIE_HASH_SIZE];
+ 
+-  char *filename;  /* file we read from/write to */
+   bool running;    /* state info, for cookie adding information */
+-  long numcookies; /* number of cookies in the "jar" */
++  int numcookies; /* number of cookies in the "jar" */
+   bool newsession; /* new session, discard session cookies on load */
+   int lastct;      /* last creation-time used in the jar */
+ };
+diff --git a/lib/easy.c b/lib/easy.c
+index 16bbd35251d40..03195481f9780 100644
+--- a/lib/easy.c
++++ b/lib/easy.c
+@@ -925,9 +925,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
+   if(data->cookies) {
+     /* If cookies are enabled in the parent handle, we enable them
+        in the clone as well! */
+-    outcurl->cookies = Curl_cookie_init(data,
+-                                        data->cookies->filename,
+-                                        outcurl->cookies,
++    outcurl->cookies = Curl_cookie_init(data, NULL, outcurl->cookies,
+                                         data->set.cookiesession);
+     if(!outcurl->cookies)
+       goto fail;
diff --git a/SOURCES/0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch b/SOURCES/0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c6ffea99a5b93c2378158cdf1d1bdb773696812b
--- /dev/null
+++ b/SOURCES/0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch
@@ -0,0 +1,193 @@
+diff -up curl-7.61.1/lib/http2.c.25a25f45 curl-7.61.1/lib/http2.c
+--- curl-7.61.1/lib/http2.c.25a25f45	2023-08-07 14:03:42.043463284 +0200
++++ curl-7.61.1/lib/http2.c	2023-08-07 14:10:24.769489855 +0200
+@@ -1202,7 +1202,7 @@ CURLcode Curl_http2_request_upgrade(Curl
+   binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
+                                          httpc->local_settings,
+                                          httpc->local_settings_num);
+-  if(!binlen) {
++  if(binlen <= 0) {
+     failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
+     Curl_add_buffer_free(req);
+     return CURLE_FAILED_INIT;
+@@ -1285,6 +1285,14 @@ static int h2_process_pending_input(stru
+     return -1;
+   }
+ 
++  if(nghttp2_session_check_request_allowed(httpc->h2) == 0) {
++    /* No more requests are allowed in the current session, so
++       the connection may not be reused. This is set when a
++       GOAWAY frame has been received or when the limit of stream
++       identifiers has been reached. */
++    connclose(conn, "http/2: No new requests allowed");
++  }
++
+   if(should_close_session(httpc)) {
+     H2BUGF(infof(data,
+                  "h2_process_pending_input: nothing to do in this session\n"));
+@@ -1297,7 +1305,6 @@ static int h2_process_pending_input(stru
+     }
+     return -1;
+   }
+-
+   return 0;
+ }
+ 
+@@ -1455,8 +1462,6 @@ static int h2_session_send(struct Curl_e
+ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
+                           char *mem, size_t len, CURLcode *err)
+ {
+-  CURLcode result = CURLE_OK;
+-  ssize_t rv;
+   ssize_t nread;
+   struct http_conn *httpc = &conn->proto.httpc;
+   struct Curl_easy *data = conn->data;
+@@ -1519,8 +1524,7 @@ static ssize_t http2_recv(struct connect
+       /* We have paused nghttp2, but we have no pause data (see
+          on_data_chunk_recv). */
+       httpc->pause_stream_id = 0;
+-      if(h2_process_pending_input(conn, httpc, &result) != 0) {
+-        *err = result;
++      if(h2_process_pending_input(conn, httpc, err) != 0) {
+         return -1;
+       }
+     }
+@@ -1549,8 +1553,7 @@ static ssize_t http2_recv(struct connect
+          frames, then we have to call it again with 0-length data.
+          Without this, on_stream_close callback will not be called,
+          and stream could be hanged. */
+-      if(h2_process_pending_input(conn, httpc, &result) != 0) {
+-        *err = result;
++      if(h2_process_pending_input(conn, httpc, err) != 0) {
+         return -1;
+       }
+     }
+@@ -1573,7 +1576,6 @@ static ssize_t http2_recv(struct connect
+     return -1;
+   }
+   else {
+-    char *inbuf;
+     /* remember where to store incoming data for this stream and how big the
+        buffer is */
+     stream->mem = mem;
+@@ -1582,16 +1584,15 @@ static ssize_t http2_recv(struct connect
+ 
+     if(httpc->inbuflen == 0) {
+       nread = ((Curl_recv *)httpc->recv_underlying)(
+-          conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
++          conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
+ 
+       if(nread == -1) {
+-        if(result != CURLE_AGAIN)
++        if(*err != CURLE_AGAIN)
+           failf(data, "Failed receiving HTTP2 data");
+         else if(stream->closed)
+           /* received when the stream was already closed! */
+           return http2_handle_stream_close(conn, data, stream, err);
+ 
+-        *err = result;
+         return -1;
+       }
+ 
+@@ -1604,47 +1605,17 @@ static ssize_t http2_recv(struct connect
+       H2BUGF(infof(data, "nread=%zd\n", nread));
+ 
+       httpc->inbuflen = nread;
+-      inbuf = httpc->inbuf;
++
++      DEBUGASSERT(httpc->nread_inbuf == 0);
+     }
+     else {
+       nread = httpc->inbuflen - httpc->nread_inbuf;
+-      inbuf = httpc->inbuf + httpc->nread_inbuf;
+-
++      (void)nread;  /* silence warning, used in debug */
+       H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
+                    nread));
+     }
+-    rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
+-
+-    if(nghttp2_is_fatal((int)rv)) {
+-      failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n",
+-            rv, nghttp2_strerror((int)rv));
+-      *err = CURLE_RECV_ERROR;
+-      return -1;
+-    }
+-    H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
+-    if(nread == rv) {
+-      H2BUGF(infof(data, "All data in connection buffer processed\n"));
+-      httpc->inbuflen = 0;
+-      httpc->nread_inbuf = 0;
+-    }
+-    else {
+-      httpc->nread_inbuf += rv;
+-      H2BUGF(infof(data, "%zu bytes left in connection buffer\n",
+-                   httpc->inbuflen - httpc->nread_inbuf));
+-    }
+-    /* Always send pending frames in nghttp2 session, because
+-       nghttp2_session_mem_recv() may queue new frame */
+-    rv = h2_session_send(data, httpc->h2);
+-    if(rv != 0) {
+-      *err = CURLE_SEND_ERROR;
+-      return -1;
+-    }
+-
+-    if(should_close_session(httpc)) {
+-      H2BUGF(infof(data, "http2_recv: nothing to do in this session\n"));
+-      *err = CURLE_HTTP2;
++    if(h2_process_pending_input(conn, httpc, err) != 0)
+       return -1;
+-    }
+   }
+   if(stream->memlen) {
+     ssize_t retlen = stream->memlen;
+@@ -2108,7 +2079,6 @@ CURLcode Curl_http2_switched(struct conn
+   CURLcode result;
+   struct http_conn *httpc = &conn->proto.httpc;
+   int rv;
+-  ssize_t nproc;
+   struct Curl_easy *data = conn->data;
+   struct HTTP *stream = conn->data->req.protop;
+ 
+@@ -2186,39 +2156,10 @@ CURLcode Curl_http2_switched(struct conn
+     memcpy(httpc->inbuf, mem, nread);
+   httpc->inbuflen = nread;
+ 
+-  nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
+-                                   httpc->inbuflen);
++  DEBUGASSERT(httpc->nread_inbuf == 0);
+ 
+-  if(nghttp2_is_fatal((int)nproc)) {
+-    failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
+-          nghttp2_strerror((int)nproc), (int)nproc);
++  if(-1 == h2_process_pending_input(conn, httpc, &result))
+     return CURLE_HTTP2;
+-  }
+-
+-  H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
+-
+-  if((ssize_t)nread == nproc) {
+-    httpc->inbuflen = 0;
+-    httpc->nread_inbuf = 0;
+-  }
+-  else {
+-    httpc->nread_inbuf += nproc;
+-  }
+-
+-  /* Try to send some frames since we may read SETTINGS already. */
+-  rv = h2_session_send(data, httpc->h2);
+-
+-  if(rv != 0) {
+-    failf(data, "nghttp2_session_send() failed: %s(%d)",
+-          nghttp2_strerror(rv), rv);
+-    return CURLE_HTTP2;
+-  }
+-
+-  if(should_close_session(httpc)) {
+-    H2BUGF(infof(data,
+-                 "nghttp2_session_send(): nothing to do in this session\n"));
+-    return CURLE_HTTP2;
+-  }
+ 
+   return CURLE_OK;
+ }
diff --git a/SOURCES/0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch b/SOURCES/0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5dc8ada88497bab15e13be3b3f7ef3929e5568d4
--- /dev/null
+++ b/SOURCES/0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch
@@ -0,0 +1,15 @@
+diff -up curl-7.61.1/lib/http2.c.c1b6a384 curl-7.61.1/lib/http2.c
+--- curl-7.61.1/lib/http2.c.c1b6a384	2023-08-07 13:59:18.482137005 +0200
++++ curl-7.61.1/lib/http2.c	2023-08-07 14:03:42.043463284 +0200
+@@ -1467,6 +1467,11 @@ static ssize_t http2_recv(struct connect
+   if(should_close_session(httpc)) {
+     H2BUGF(infof(data,
+                  "http2_recv: nothing to do in this session\n"));
++    if(conn->bits.close) {
++      /* already marked for closure, return OK and we're done */
++      *err = CURLE_OK;
++      return 0;
++    }
+     *err = CURLE_HTTP2;
+     return -1;
+   }
diff --git a/SOURCES/0059-curl-7.61.1-CVE-2023-46218.patch b/SOURCES/0059-curl-7.61.1-CVE-2023-46218.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6a7b72a56eb6f76c4c25763972f9a48b8ffd0d60
--- /dev/null
+++ b/SOURCES/0059-curl-7.61.1-CVE-2023-46218.patch
@@ -0,0 +1,48 @@
+From 2b0994c29a721c91c572cff7808c572a24d251eb Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Thu, 23 Nov 2023 08:15:47 +0100
+Subject: [PATCH] cookie: lowercase the domain names before PSL checks
+
+Reported-by: Harry Sintonen
+
+Closes #12387
+---
+ lib/cookie.c | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/lib/cookie.c b/lib/cookie.c
+index 568cf537ad1b1f..9095cea3e97f22 100644
+--- a/lib/cookie.c
++++ b/lib/cookie.c
+@@ -1027,15 +1027,23 @@ Curl_cookie_add(struct Curl_easy *data,
+ #ifdef USE_LIBPSL
+   /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */
+   if(domain && co->domain && !isip(co->domain)) {
+-    const psl_ctx_t *psl = Curl_psl_use(data);
+-    int acceptable;
+-
+-    if(psl) {
+-      acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain);
+-      Curl_psl_release(data);
++    bool acceptable = FALSE;
++    char lcase[256];
++    char lcookie[256];
++    size_t dlen = strlen(domain);
++    size_t clen = strlen(co->domain);
++    if((dlen < sizeof(lcase)) && (clen < sizeof(lcookie))) {
++      const psl_ctx_t *psl = Curl_psl_use(data);
++      if(psl) {
++        /* the PSL check requires lowercase domain name and pattern */
++        Curl_strntolower(lcase, domain, dlen + 1);
++        Curl_strntolower(lcookie, co->domain, clen + 1);
++        acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie);
++        Curl_psl_release(data);
++      }
++      else
++        acceptable = !bad_domain(domain);
+     }
+-    else
+-      acceptable = !bad_domain(domain);
+ 
+     if(!acceptable) {
+       infof(data, "cookie '%s' dropped, domain '%s' must not "
diff --git a/SOURCES/0060-curl-7.61.1-lowercase-headernames.patch b/SOURCES/0060-curl-7.61.1-lowercase-headernames.patch
new file mode 100644
index 0000000000000000000000000000000000000000..e15ec11cba273dab8b94454c50b4c99a7972b30e
--- /dev/null
+++ b/SOURCES/0060-curl-7.61.1-lowercase-headernames.patch
@@ -0,0 +1,136 @@
+From 0023fce38d3bd6ee0e9b6ff8708fee1195057846 Mon Sep 17 00:00:00 2001
+From: Barry Pollard <barry_pollard@hotmail.com>
+Date: Sun, 22 Sep 2019 21:17:12 +0100
+Subject: [PATCH] http: lowercase headernames for HTTP/2 and HTTP/3
+
+Closes #4401
+Fixes #4400
+---
+ lib/strcase.c      | 84 ++++++++++++++++++++++++++++++++++++++++++++++
+ lib/strcase.h      |  2 ++
+ 5 files changed, 95 insertions(+), 3 deletions(-)
+
+diff --git a/lib/strcase.c b/lib/strcase.c
+index 24bcca932..098cec7a8 100644
+--- a/lib/strcase.c
++++ b/lib/strcase.c
+@@ -93,6 +93,75 @@ char Curl_raw_toupper(char in)
+   return in;
+ }
+ 
++
++/* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because
++   its behavior is altered by the current locale. */
++char Curl_raw_tolower(char in)
++{
++#if !defined(CURL_DOES_CONVERSIONS)
++  if(in >= 'A' && in <= 'Z')
++    return (char)('a' + in - 'A');
++#else
++  switch(in) {
++  case 'A':
++    return 'a';
++  case 'B':
++    return 'b';
++  case 'C':
++    return 'c';
++  case 'D':
++    return 'd';
++  case 'E':
++    return 'e';
++  case 'F':
++    return 'f';
++  case 'G':
++    return 'g';
++  case 'H':
++    return 'h';
++  case 'I':
++    return 'i';
++  case 'J':
++    return 'j';
++  case 'K':
++    return 'k';
++  case 'L':
++    return 'l';
++  case 'M':
++    return 'm';
++  case 'N':
++    return 'n';
++  case 'O':
++    return 'o';
++  case 'P':
++    return 'p';
++  case 'Q':
++    return 'q';
++  case 'R':
++    return 'r';
++  case 'S':
++    return 's';
++  case 'T':
++    return 't';
++  case 'U':
++    return 'u';
++  case 'V':
++    return 'v';
++  case 'W':
++    return 'w';
++  case 'X':
++    return 'X';
++  case 'Y':
++    return 'y';
++  case 'Z':
++    return 'z';
++  }
++#endif
++
++  return in;
++}
++
++
+ /*
+  * Curl_strcasecompare() is for doing "raw" case insensitive strings. This is
+  * meant to be locale independent and only compare strings we know are safe
+@@ -234,6 +303,21 @@ void Curl_strntoupper(char *dest, const char *src, size_t n)
+   } while(*src++ && --n);
+ }
+ 
++/* Copy a lower case version of the string from src to dest.  The
++ * strings may overlap.  No more than n characters of the string are copied
++ * (including any NUL) and the destination string will NOT be
++ * NUL-terminated if that limit is reached.
++ */
++void Curl_strntolower(char *dest, const char *src, size_t n)
++{
++  if(n < 1)
++    return;
++
++  do {
++    *dest++ = Curl_raw_tolower(*src);
++  } while(*src++ && --n);
++}
++
+ /* Compare case-sensitive NUL-terminated strings, taking care of possible
+  * null pointers. Return true if arguments match.
+  */
+diff --git a/lib/strcase.h b/lib/strcase.h
+index 6fee3840e..2f07a74c9 100644
+--- a/lib/strcase.h
++++ b/lib/strcase.h
+@@ -40,12 +40,14 @@ int Curl_safe_strcasecompare(const char *first, const char *second);
+ int Curl_strncasecompare(const char *first, const char *second, size_t max);
+ 
+ char Curl_raw_toupper(char in);
++char Curl_raw_tolower(char in);
+ 
+ /* checkprefix() is a shorter version of the above, used when the first
+    argument is zero-byte terminated */
+ #define checkprefix(a,b)    curl_strnequal(a,b,strlen(a))
+ 
+ void Curl_strntoupper(char *dest, const char *src, size_t n);
++void Curl_strntolower(char *dest, const char *src, size_t n);
+ 
+ bool Curl_safecmp(char *a, char *b);
+ int Curl_timestrcmp(const char *first, const char *second);
+-- 
+2.43.0
+
diff --git a/SOURCES/0061-curl-7.61.1-CVE-2024-2398.patch b/SOURCES/0061-curl-7.61.1-CVE-2024-2398.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8c0345535af5dbe652da4c77105477679c25511d
--- /dev/null
+++ b/SOURCES/0061-curl-7.61.1-CVE-2024-2398.patch
@@ -0,0 +1,80 @@
+From deca8039991886a559b67bcd6701db800a5cf764 Mon Sep 17 00:00:00 2001
+From: Stefan Eissing <stefan@eissing.org>
+Date: Wed, 6 Mar 2024 09:36:08 +0100
+Subject: [PATCH] http2: push headers better cleanup
+
+- provide common cleanup method for push headers
+
+Closes #13054
+---
+ lib/http2.c | 34 +++++++++++++++-------------------
+ 1 file changed, 15 insertions(+), 19 deletions(-)
+
+diff --git a/lib/http2.c b/lib/http2.c
+index c63ecd38371ab4..96868728a53a1f 100644
+--- a/lib/http2.c
++++ b/lib/http2.c
+@@ -271,6 +271,15 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf,
+   return http2_perform_getsock(conn, sock, numsocks);
+ }
+ 
++static void free_push_headers(struct HTTP *http)
++{
++  size_t i;
++  for(i = 0; i<http->push_headers_used; i++)
++    free(http->push_headers[i]);
++  Curl_safefree(http->push_headers);
++  http->push_headers_used = 0;
++}
++
+ /*
+  * http2_stream_free() free HTTP2 stream related data
+  */
+@@ -306,11 +315,7 @@ static void http2_data_done(struct Curl_cfilter *cf,
+     http->header_recvbuf = NULL; /* clear the pointer */
+     Curl_add_buffer_free(http->trailer_recvbuf);
+     http->trailer_recvbuf = NULL; /* clear the pointer */
+-    for(; http->push_headers_used > 0; --http->push_headers_used) {
+-      free(http->push_headers[http->push_headers_used - 1]);
+-    }
+-    free(http->push_headers);
+-    http->push_headers = NULL;
++    free_push_headers(http);
+   }
+ }
+ 
+@@ -860,7 +861,6 @@ static int push_promise(struct Curl_cfilter *cf,
+     struct curl_pushheaders heads;
+     CURLMcode rc;
+     struct http_conn *httpc;
+-    size_t i;
+     /* clone the parent */
+     struct Curl_easy *newhandle = duphandle(data);
+     if(!newhandle) {
+@@ -904,11 +904,7 @@ static int push_promise(struct Curl_cfilter *cf,
+     Curl_set_in_callback(data, false);
+ 
+     /* free the headers again */
+-    for(i = 0; i<stream->push_headers_used; i++)
+-      free(stream->push_headers[i]);
+-    free(stream->push_headers);
+-    stream->push_headers = NULL;
+-    stream->push_headers_used = 0;
++    free_push_headers(stream);
+ 
+     if(rv) {
+       /* denied, kill off the new handle again */
+@@ -1426,10 +1422,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
+             stream->push_headers_alloc) {
+       char **headp;
+       stream->push_headers_alloc *= 2;
+-      headp = Curl_saferealloc(stream->push_headers,
+-                               stream->push_headers_alloc * sizeof(char *));
++      headp = realloc(stream->push_headers,
++                      stream->push_headers_alloc * sizeof(char *));
+       if(!headp) {
+-        stream->push_headers = NULL;
++        free_push_headers(stream);
+         return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+       }
+       stream->push_headers = headp;
diff --git a/SPECS/curl.spec b/SPECS/curl.spec
index 692d063a05eac187722504b52b9f737e5e89756d..6a05e4d489271867a173f9cb085b6217ef98135f 100644
--- a/SPECS/curl.spec
+++ b/SPECS/curl.spec
@@ -1,7 +1,7 @@
 Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
 Name: curl
 Version: 7.61.1
-Release: 33%{?dist}.5
+Release: 34%{?dist}.2
 License: MIT
 Source: https://curl.haxx.se/download/%{name}-%{version}.tar.xz
 
@@ -154,26 +154,29 @@ Patch52:  0052-curl-7.61.1-certs.patch
 # when keyboard-interactive auth fails, try password
 Patch53:  0053-curl-7.61.1-password-when-keyboard-interactive-fails.patch
 
-# fix cookie injection with none file (CVE-2023-38546)
-Patch54:  0054-curl-7.61.1-CVE-2023-38546.patch
+# cap SFTP packet size sent
+Patch54:  0054-curl-7.61.1-64K-sftp.patch
 
 # unify the upload/method handling (CVE-2023-28322)
 Patch55:  0055-curl-7.61.1-CVE-2023-28322.patch
 
+# fix cookie injection with none file (CVE-2023-38546)
+Patch56:  0056-curl-7.61.1-CVE-2023-38546.patch
+
 # consolidate nghttp2_session_mem_recv() call paths
-Patch56:  0056-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch
+Patch57:  0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch
 
 # when marked for closure and wanted to close == OK
-Patch57:  0057-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch
+Patch58:  0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch
 
 # lowercase the domain names before PSL checks (CVE-2023-46218)
-Patch58:  0058-curl-7.61.1-CVE-2023-46218.patch
+Patch59:  0059-curl-7.61.1-CVE-2023-46218.patch
 
 # lowercase headernames
-Patch59:  0059-curl-7.61.1-lowercase-headernames.patch
+Patch60:  0060-curl-7.61.1-lowercase-headernames.patch
 
-# cap SFTP packet size sent
-Patch60:  0060-curl-7.61.1-64K-sftp.patch
+# provide common cleanup method for push headers (CVE-2024-2398)
+Patch61:  0061-curl-7.61.1-CVE-2024-2398.patch
 
 # patch making libcurl multilib ready
 Patch101: 0101-curl-7.32.0-multilib.patch
@@ -408,6 +411,7 @@ git apply %{PATCH52}
 %patch58 -p1
 %patch59 -p1
 %patch60 -p1
+%patch61 -p1
 
 # make tests/*.py use Python 3
 sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py
@@ -570,22 +574,19 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la
 %{_libdir}/libcurl.so.4.[0-9].[0-9].minimal
 
 %changelog
-* Wed Jan 24 2024 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-33.el8_9.5
-- cap SFTP packet size sent (RHEL-5485)
+* Wed Aug 14 2024 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.2
+- provide common cleanup method for push headers (CVE-2024-2398)
 
-* Tue Dec 05 2023 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-33.el8_9.4
-- unify the upload/method handling (CVE-2023-28322)
-- fix HTTP2 connection failure with HTTP2 framing layer (RHEL-15296)
-- lowercase the domain names before PSL checks (CVE-2023-46218)
+* Tue Jun 25 2024 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34.el8_10.1
+- fix incorrect backport of bz2229800 (RHEL-44684)
 
-* Thu Oct 12 2023 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-33.el8_9.3
+* Tue Sep 19 2023 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-34
+- when keyboard-interactive auth fails, try password (#2229800)
+- cap SFTP packet size sent (RHEL-5311)
+- unify the upload/method handling (CVE-2023-28322)
 - fix cookie injection with none file (CVE-2023-38546)
-
-* Mon Sep 25 2023 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-33.el8_9.2
-- fix 'incompatible pointer type' reported by OpenScanHub (#2240033)
-
-* Fri Sep 22 2023 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-33.el8_9.1
-- when keyboard-interactive auth fails, try password (#2240033)
+- fix HTTP2 connection failure with HTTP2 framing layer (RHEL-5657)
+- lowercase the domain names before PSL checks (CVE-2023-46218)
 
 * Tue Jun 27 2023 Jacek Migacz <jmigacz@redhat.com> - 7.61.1-33
 - fix host name wildcard checking (CVE-2023-28321)