new file mode 100644
@@ -0,0 +1,127 @@
+From b9eaedeb9d5440eae886c0b33f4ee48859d7123d Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Sat, 16 May 2026 00:19:09 +0200
+Subject: [PATCH] cookie: trim trailing dots when checking PSL
+
+Verified with test 1629
+
+Closes #21636
+
+CVE: CVE-2026-8924
+Upstream-Status: Backport [https://github.com/curl/curl/commit/51beed175dbfc37da3113f6acce60c630c070ce8]
+
+Backport Changes:
+- curl 8.7.1 performs the PSL check inline in Curl_cookie_add(). Apply the
+ upstream trailing-dot length normalization at that equivalent code path.
+- Register test1629 in the target-generated Makefile.inc instead of the newer
+ Makefile.am list.
+
+(cherry picked from commit 51beed175dbfc37da3113f6acce60c630c070ce8)
+Signed-off-by: Devansh Patel <devanshp@cisco.com>
+---
+ lib/cookie.c | 13 ++++++++--
+ tests/data/Makefile.inc | 2 +-
+ tests/data/test1629 | 53 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 65 insertions(+), 3 deletions(-)
+ create mode 100644 tests/data/test1629
+
+diff --git a/lib/cookie.c b/lib/cookie.c
+index 67494d2855..11081e0ba0 100644
+--- a/lib/cookie.c
++++ b/lib/cookie.c
+@@ -1032,12 +1032,21 @@ Curl_cookie_add(struct Curl_easy *data,
+ char lcookie[256];
+ size_t dlen = strlen(domain);
+ size_t clen = strlen(co->domain);
++
++ /* trim trailing dots */
++ if(dlen && (domain[dlen - 1] == '.'))
++ dlen--;
++ if(clen && (co->domain[clen - 1] == '.'))
++ clen--;
++
+ 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);
++ Curl_strntolower(lcase, domain, dlen);
++ lcase[dlen] = 0;
++ Curl_strntolower(lcookie, co->domain, clen);
++ lcookie[clen] = 0;
+ acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie);
+ Curl_psl_release(data);
+ }
+diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
+index 461eb37b92..9fd47df771 100644
+--- a/tests/data/Makefile.inc
++++ b/tests/data/Makefile.inc
+@@ -207,7 +207,7 @@ test1598 \
+ test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \
+ test1608 test1609 test1610 test1611 test1612 test1613 test1614 test1615 \
+ \
+-test1620 test1621 \
++test1620 test1621 test1629 \
+ \
+ test1630 test1631 test1632 test1633 test1634 test1635 \
+ \
+diff --git a/tests/data/test1629 b/tests/data/test1629
+new file mode 100644
+index 0000000000..6ee479ba31
+--- /dev/null
++++ b/tests/data/test1629
+@@ -0,0 +1,53 @@
++<?xml version="1.0" encoding="US-ASCII"?>
++<testcase>
++<info>
++<keywords>
++HTTP
++HTTP GET
++</keywords>
++</info>
++
++# Server-side
++<reply>
++<data crlf="headers">
++HTTP/1.1 200 OK
++Content-Length: 6
++Set-Cookie: something=1; Domain=co.uk.; Path=/
++
++-foo-
++</data>
++</reply>
++
++# Client-side
++<client>
++<features>
++PSL
++cookies
++</features>
++<server>
++http
++</server>
++<name>
++cookies with trailing dot after PSL domain
++</name>
++<command>
++http://foo.co.uk.:%HTTPPORT/ http://bar.co.uk.:%HTTPPORT/ -b "" --resolve foo.co.uk.:%HTTPPORT:%HOSTIP --resolve bar.co.uk.:%HTTPPORT:%HOSTIP
++</command>
++</client>
++
++# Verify data after the test has been "shot"
++<verify>
++<protocol crlf="headers">
++GET / HTTP/1.1
++Host: foo.co.uk.:%HTTPPORT
++User-Agent: curl/%VERSION
++Accept: */*
++
++GET / HTTP/1.1
++Host: bar.co.uk.:%HTTPPORT
++User-Agent: curl/%VERSION
++Accept: */*
++
++</protocol>
++</verify>
++</testcase>
@@ -42,6 +42,7 @@ SRC_URI = " \
file://CVE-2026-6253.patch \
file://CVE-2026-4873.patch \
file://CVE-2026-8286.patch \
+ file://CVE-2026-8924.patch \
"
SRC_URI:append:class-nativesdk = " \