new file mode 100644
@@ -0,0 +1,77 @@
+From ad27c1762cd00df8b808925ab240fc4c0766c228 Mon Sep 17 00:00:00 2001
+From: "W.C.A. Wijngaards" <wouter@nlnetlabs.nl>
+Date: Wed, 22 Jul 2026 10:14:35 +0200
+Subject: [PATCH] - Fix CVE-2026-50248, BOGUS configured primary hostname
+ accepted for XFR in auth/rpz zones. Thanks to Qifan Zhang, Palo Alto
+ Networks, for the report.
+
+(cherry picked from commit 3530c81e29e64ed19c612ae3dea21c8800d882e1)
+
+CVE: CVE-2026-50248
+Upstream-Status: Backport [https://github.com/NLnetLabs/unbound/commit/3530c81e29e64ed19c612ae3dea21c8800d882e1]
+
+Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
+---
+ services/authzone.c | 28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/services/authzone.c b/services/authzone.c
+index 60ccc8698..357c1c590 100644
+--- a/services/authzone.c
++++ b/services/authzone.c
+@@ -5693,8 +5693,7 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
+
+ /** callback for task_transfer lookup of host name, of A or AAAA */
+ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
+- enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
+- int ATTR_UNUSED(was_ratelimited))
++ enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited))
+ {
+ struct auth_xfer* xfr = (struct auth_xfer*)arg;
+ struct module_env* env;
+@@ -5707,7 +5706,16 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
+ }
+
+ /* process result */
+- if(rcode == LDNS_RCODE_NOERROR) {
++ if(sec == sec_status_bogus || sec == sec_status_secure_sentinel_fail) {
++ if(verbosity >= VERB_OPS) {
++ char zname[LDNS_MAX_DOMAINLEN];
++ dname_str(xfr->name, zname);
++ verbose(VERB_OPS, "auth zone %s: primary %s address lookup is DNSSEC bogus: %s",
++ zname, xfr->task_transfer->lookup_target->host,
++ (why_bogus?why_bogus:""));
++ }
++ /* fall through to next-lookup / next-master */
++ } else if(rcode == LDNS_RCODE_NOERROR) {
+ uint16_t wanted_qtype = LDNS_RR_TYPE_A;
+ struct regional* temp = env->scratch;
+ struct query_info rq;
+@@ -6756,8 +6764,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
+
+ /** callback for task_probe lookup of host name, of A or AAAA */
+ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
+- enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
+- int ATTR_UNUSED(was_ratelimited))
++ enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited))
+ {
+ struct auth_xfer* xfr = (struct auth_xfer*)arg;
+ struct module_env* env;
+@@ -6770,7 +6777,16 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
+ }
+
+ /* process result */
+- if(rcode == LDNS_RCODE_NOERROR) {
++ if(sec == sec_status_bogus || sec == sec_status_secure_sentinel_fail) {
++ if(verbosity >= VERB_OPS) {
++ char zname[LDNS_MAX_DOMAINLEN];
++ dname_str(xfr->name, zname);
++ verbose(VERB_OPS, "auth zone %s: primary %s address probe lookup is DNSSEC bogus: %s",
++ zname, xfr->task_transfer->lookup_target->host,
++ (why_bogus?why_bogus:""));
++ }
++ /* fall through to next-lookup / next-master */
++ } else if(rcode == LDNS_RCODE_NOERROR) {
+ uint16_t wanted_qtype = LDNS_RR_TYPE_A;
+ struct regional* temp = env->scratch;
+ struct query_info rq;
@@ -31,6 +31,7 @@ SRC_URI = "git://github.com/NLnetLabs/unbound.git;protocol=https;branch=master;t
file://CVE-2026-50045.patch \
file://CVE-2026-50046.patch \
file://CVE-2026-50243.patch \
+ file://CVE-2026-50248.patch \
"
SRCREV = "f6269baa605d31859f28770e01a24e3677e5f82c"