From patchwork Mon Sep 7 10:22:45 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97470 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 B49CDC79F9F for ; Mon, 7 Sep 2026 10:23:38 +0000 (UTC) Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31682.1788776608220084972 for ; Mon, 07 Sep 2026 03:23:28 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=KxPVmF7B; spf=pass (domain: gmail.com, ip: 209.85.216.47, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f47.google.com with SMTP id 98e67ed59e1d1-38dfe910e9dso3687946a91.3 for ; Mon, 07 Sep 2026 03:23:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776607; x=1789381407; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=CUeUmHBX5fcxhd9G5E8Bd9Pj21b7DJSq6nybGyJloBU=; b=KxPVmF7BV/qX93L/sx64uBNwzUvjNI1hbrCCzVYMC7Sb+5WDa5hJCt1+NhaxCQCsbi zq4f4ClpjYBBJwlnTE6s9V25UrltIfgVyh0JdWYXWn2ByByI5iu2EGkx23HxWYdjew7B LBD+aIADHJEt2lXiM9R+ibp3hlucK88KhxG6oRjq9/VOUoFCIE0UAiXpvmK6N3MRmUMI 1kG6WYwK0oC9CF6A9tR5/8hiCp8fHuy3zEW9miHZGzWzuHLocxnaXhHDQgEwvRudx/c/ +lWqQjJVGrKfNVY4BtE7xV7PPGSET2KpLZ7LunMf1UvneoWdMiE000JeTBWP6F43JC0f izng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776607; x=1789381407; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=CUeUmHBX5fcxhd9G5E8Bd9Pj21b7DJSq6nybGyJloBU=; b=o/Adxru8SxUo2zCHKTPL2p9w8dudBTa9kzB6XaT02/j48l7q7E27NvHyU+mW3UCLho fYVoAdu9fmi8+XgQbBP8pYIuhtSXnXikfxPaK8KylCK/sWYeVMYV17RpXWYyAv/tgwkU eVjYOd+l7M70alh3CQP+0r7/esPSUjICRbBjSlhIIS6yf0XFRCpj4FEOANWEsSY3XRWH o4kWwdlRdkyXwRGMkAqsDtF45eeFDsXfGXOLBl9UKxuXSgNGm4XMVyAi25CTw5z5Unju c+H0TzD8mHONtBbZaZnlafMD221EOb3LP4XtIwiWFtqq3dE/6OoW12nKDHMl2mvhJTr/ m9Ww== X-Gm-Message-State: AFuF++ngJh8p9DCAACwKH11ykQrWKIKWNFjkGubeCARdPjqQQllfcFxs 0htmlve2zM/WF3swnPd2tMyqXRhbdgjND7CvZPHE6Gmo36n7qIKixJKt9Q1Bz0fX X-Gm-Gg: AYBFou1+2ajBBgf2QEhqWZWUGaK1NwgPUJ4c/PgMsFwI3Ixoi4jQy9bwoKZN2znVu/v CU3B2nYgeI0a6qGlAIRatFU6d0uF3RBpnOHbqiv2UYlZ41KsJvVey7iSHrCOTAVIBoqoFXUtLtk Hadr2e4yJfm0W5zc27HZ81qSzjQNY8RbvnLRzZJ1RyUUG/nQD3wl/jlDB7te4CCuio+B4yWxLZx vZimZJ0wXmqJQm5+JnyhWDT6r8exrVH1qxC/yHoYMpXTQT2ktO05lDK+6lOq9U/1s+Aso7XgCa0 eUyDtr+0geBLeqp9q8bYFNn2+HwS25ZKWEa5fdy6AwKZjhFeteqO7Q5pHRUHyPoprNwNDSwGyny jjhFLSzqA0Ic0kO+ZWa8RW548bm3kWGfPNETHVxJYF//p8tlJFruZXMw9IWIRtBlPhTufcEo0li wDmGpOU8li5a8Zf8NQ/WP6zXpqRXgcOr/F8j1BdJ2vDQ7WpI/zhk/JFpMx8xURfxtVqbv0BYZ6i g== X-Received: by 2002:a17:90a:e7c2:b0:398:9be8:ea66 with SMTP id 98e67ed59e1d1-39b261da126mr32325601a91.19.1788776607445; Mon, 07 Sep 2026 03:23:27 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:27 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 1/33] libnfs: patch CVE-2026-53689 Date: Mon, 7 Sep 2026 22:22:45 +1200 Message-ID: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129813 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-53689 Signed-off-by: Ankur Tyagi --- .../libnfs/libnfs/CVE-2026-53689.patch | 34 +++++++++++++++++++ .../libnfs/libnfs_6.0.2.bb | 1 + 2 files changed, 35 insertions(+) create mode 100644 meta-oe/recipes-connectivity/libnfs/libnfs/CVE-2026-53689.patch diff --git a/meta-oe/recipes-connectivity/libnfs/libnfs/CVE-2026-53689.patch b/meta-oe/recipes-connectivity/libnfs/libnfs/CVE-2026-53689.patch new file mode 100644 index 0000000000..0c624c7219 --- /dev/null +++ b/meta-oe/recipes-connectivity/libnfs/libnfs/CVE-2026-53689.patch @@ -0,0 +1,34 @@ +From d45a7d6cdc899ac2a62abc21280d674ae91ae0ae Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Wed, 10 Jun 2026 11:43:28 +1000 +Subject: [PATCH] ZDR: check the string size for sanity + +It could otherwise cause an overflow in the bounds check later. + +Reported-by: Nick Hummel +Signed-off-by: Ronnie Sahlberg +(cherry picked from commit 55c18ea33a83d667f79f0ef209c96895795c729f) + +CVE: CVE-2026-53689 +Upstream-Status: Backport [https://github.com/sahlberg/libnfs/commit/55c18ea33a83d667f79f0ef209c96895795c729f] + +Signed-off-by: Ankur Tyagi +--- + lib/libnfs-zdr.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/libnfs-zdr.c b/lib/libnfs-zdr.c +index bc507eb..cbdb650 100644 +--- a/lib/libnfs-zdr.c ++++ b/lib/libnfs-zdr.c +@@ -305,7 +305,9 @@ bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize) + if (!libnfs_zdr_u_int(zdrs, &size)) { + return FALSE; + } +- ++ if (size > zdrs->size) { ++ return FALSE; ++ } + if (zdrs->pos + (int)size > zdrs->size) { + return FALSE; + } diff --git a/meta-oe/recipes-connectivity/libnfs/libnfs_6.0.2.bb b/meta-oe/recipes-connectivity/libnfs/libnfs_6.0.2.bb index 83f32d3a07..403bae9465 100644 --- a/meta-oe/recipes-connectivity/libnfs/libnfs_6.0.2.bb +++ b/meta-oe/recipes-connectivity/libnfs/libnfs_6.0.2.bb @@ -5,6 +5,7 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=825301ba17efc9d188ee0abd4b924ada" SRC_URI = "git://github.com/sahlberg/libnfs.git;protocol=https;branch=master \ file://0001-CMakeLists.txt-respect-CMAKE_INSTALL_LIBDIR-for-mult.patch \ + file://CVE-2026-53689.patch \ " SRCREV = "18c5c73ee88bb7dc8da0d55dc95164bb77e49dc6" From patchwork Mon Sep 7 10:22:46 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97469 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 A8C84C79F99 for ; Mon, 7 Sep 2026 10:23:38 +0000 (UTC) Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31903.1788776611019318122 for ; Mon, 07 Sep 2026 03:23:31 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=XFrEBkDp; spf=pass (domain: gmail.com, ip: 209.85.216.53, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-38dfe7eb825so2720985a91.0 for ; Mon, 07 Sep 2026 03:23:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776610; x=1789381410; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=mSIhpuBUtQzGa1mzyMB4MJfcTE6WMyIvFYwMQtldhpo=; b=XFrEBkDppYhXcOYsRchN9imaxfdbetSYkSmZM3XI3/62zO7DhetgwF3yEFFDRP7tgK eXQfIQ22uzhR3xKTKi3Xi5p+fHkwJGSWGHL9J+ksKMckEK4Nu7ZM7r5otoeTt87yZhga 6rljjBeYvTNOvaG9whu0wtmWBpfCc+ZsXdYuDFky6dDl0rHVvYKXPGP+RgEg9EAYu8Zt bJQult6nrD0sKDxmeerPmpnDsmEHyWqupQqCSM70vi5VyOcUfO/OfUYCvocieNCd53J8 yX1QZOphWfLZYu8bY5/YcOwxK8eg6opq1ma5RCexViJf21iaYWKmoC8evI1fvC9peAXw G7rA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776610; x=1789381410; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=mSIhpuBUtQzGa1mzyMB4MJfcTE6WMyIvFYwMQtldhpo=; b=FV1kWLPq14DR0sqc/5XUFRtg3WJiMsyoT6LAl2NoQoxYeiMsZm8pScoGdH8083DCKF zByuTpS81Fx/dlYuGxgkkuW2WSjF0/Pz5nOFlJv1GgBykszaU0k7RlgDveuH/qxp1uS4 1A5MtJZSLRuSxuROhtzel7rnh2j9PEMoZ4A5VM4Dh6AsfaWULP4niPCzDNQkSGZq5clh xsFp7JhhKy+/Rr7fjDY2TSB2vHaMgypTOmIcnbwTVdcnL/9978mbRQIJGZ4O+++pJNQ0 8t60sTn3dgg46WJN9UqXBWwNe48+9Yxg9wZF1KeJz8Qkb8CYF7DGLSnKbI9zJKUNx7v3 Fvyg== X-Gm-Message-State: AFuF++my3kpGI8wwq0DBclxbEbcrBQIFJYVvFou+1Sy9gg3yihb8U6sq 0TwP5jvsXnyeLR6a67N/M463IPZsX1t5+Mz/PLSsd7TKxAJnNDQavblX4QhKvvUL X-Gm-Gg: AYBFou2BQFJnk0aTV26x2IpmhWxEaFxjBJpMyLvRApPGjykoXvjE2zyQxNIY3MpIoEa u1IjxcsAWOrSQnhuNP3YbU9kk3RLNL0VC9xojlFEsbGVv7eGRsGz7C72SIW+rL/TWq+ndPJ8YGT SaDxKvn6IHzwrHMDzUA7Ci4m90PnDrnbAPVJ7WBItGlYyc52c1L4FsR0uZK9T/OwZapr182r5KV pLRtFKHXRqRh46Rs5UM9M98qOOZU8ecljah3VA0itPa5c9ovAd2/Mf/UMh/q7Xxq2TGjMBYVi57 ldc5iY63Lq/SXeEXZGB1ljaYq8WOMKjLrOH4Kdjt6/oXKuJOD4Z6NeWn8BCmmf31H6N+G62K5jj o+1JRsGzpzDlt+YlC5prE/dBminw0HPVNiHWo1PlUqfoMUsOO7QsxbitzLQ75DomWBxRGt1hAVd l85Xn5+iQlb6LPEPy2Od+hKLEundlBG6JHejetnrz1byPMxPG5VRLFT//4+OpsocQy7WEWqNMdr w== X-Received: by 2002:a17:90b:578c:b0:398:e6b6:acc2 with SMTP id 98e67ed59e1d1-39b261e7649mr35340541a91.12.1788776610202; Mon, 07 Sep 2026 03:23:30 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:29 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 2/33] libnfs: patch CVE-2026-57918 Date: Mon, 7 Sep 2026 22:22:46 +1200 Message-ID: <20260907102318.2459883-2-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129814 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-57918 Signed-off-by: Ankur Tyagi --- .../libnfs/libnfs/CVE-2026-57918.patch | 34 +++++++++++++++++++ .../libnfs/libnfs_6.0.2.bb | 1 + 2 files changed, 35 insertions(+) create mode 100644 meta-oe/recipes-connectivity/libnfs/libnfs/CVE-2026-57918.patch diff --git a/meta-oe/recipes-connectivity/libnfs/libnfs/CVE-2026-57918.patch b/meta-oe/recipes-connectivity/libnfs/libnfs/CVE-2026-57918.patch new file mode 100644 index 0000000000..27c99b5704 --- /dev/null +++ b/meta-oe/recipes-connectivity/libnfs/libnfs/CVE-2026-57918.patch @@ -0,0 +1,34 @@ +From 589568b88a06d92b298ecce563ae57b5fad91238 Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Wed, 10 Jun 2026 12:21:58 +1000 +Subject: [PATCH] socket: prevent an underflow in xid + +if the expected pdu-size is larger than the absolute pdu size +from the xid/record-marker. + +Reported-by: Nick Hummel +Signed-off-by: Ronnie Sahlberg +(cherry picked from commit 935b8db712b3c6649bc57ddc276526c4a31680de) + +CVE: CVE-2026-57918 +Upstream-Status: Backport [https://github.com/sahlberg/libnfs/commit/935b8db712b3c6649bc57ddc276526c4a31680de] + +Signed-off-by: Ankur Tyagi +--- + lib/socket.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/lib/socket.c b/lib/socket.c +index f51ca4d..8e38eb8 100644 +--- a/lib/socket.c ++++ b/lib/socket.c +@@ -929,6 +929,9 @@ rpc_read_from_socket(struct rpc_context *rpc) + break; + case READ_IOVEC: + rpc->pdu->read_count -= rpc->pdu_size; ++ if (rpc->rm_xid[0] < rpc->pdu_size) { ++ return -1; ++ } + rpc->rm_xid[0] -= rpc->pdu_size; + if (!rpc->rm_xid[0]) { + rpc_finished_pdu(rpc); diff --git a/meta-oe/recipes-connectivity/libnfs/libnfs_6.0.2.bb b/meta-oe/recipes-connectivity/libnfs/libnfs_6.0.2.bb index 403bae9465..36676708cb 100644 --- a/meta-oe/recipes-connectivity/libnfs/libnfs_6.0.2.bb +++ b/meta-oe/recipes-connectivity/libnfs/libnfs_6.0.2.bb @@ -6,6 +6,7 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=825301ba17efc9d188ee0abd4b924ada" SRC_URI = "git://github.com/sahlberg/libnfs.git;protocol=https;branch=master \ file://0001-CMakeLists.txt-respect-CMAKE_INSTALL_LIBDIR-for-mult.patch \ file://CVE-2026-53689.patch \ + file://CVE-2026-57918.patch \ " SRCREV = "18c5c73ee88bb7dc8da0d55dc95164bb77e49dc6" From patchwork Mon Sep 7 10:22:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97471 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 9E511C79F89 for ; Mon, 7 Sep 2026 10:23:38 +0000 (UTC) Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com [209.85.216.48]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31904.1788776613550593010 for ; Mon, 07 Sep 2026 03:23:33 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=RICQ+ZZ9; spf=pass (domain: gmail.com, ip: 209.85.216.48, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f48.google.com with SMTP id 98e67ed59e1d1-38d489b6b71so3897468a91.0 for ; Mon, 07 Sep 2026 03:23:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776613; x=1789381413; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=8JqrXwl6h7QGB2BknWQ/LStccuFo0ZPROXJlx78y80U=; b=RICQ+ZZ9RHWfxV+EXgC4+p8IeT5zEtuSeYfsK6pRuZxahkLlJOwxgbf5qBiObR4mZD wwScZHHVm0CMwKPSZ5+5NfSP6k2YdD0B4UvfkqEnJwZanMAVshLKpHz/UZgi5S04AO6z Nq04BWeajc3+KOBapyF0dI/xcR5I9Mx7NCImL5KfbHRDYVEiVFhLqWjxeSc9fR/SMoRs jw2i6w2zPY8HABu7umO7idS7YkAMUapfiublkKqvg393E23nHFB8pbgov0DtLMZ1CnTG 0/8XrnDz6eVmHhD6Sn5AU3GBAh+SKXd0q6na3x9drLYsqO/W3Ez0RqM8H5qT/9KFl9Y8 7MCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776613; x=1789381413; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=8JqrXwl6h7QGB2BknWQ/LStccuFo0ZPROXJlx78y80U=; b=GJf3uTYlfJ0LY3/9qp0p/ED1RgJ5EBJo+nSIVUyLnCZAOzTLgPdJoDGePJvK+9BdYl XStvCY7eB+J8sfADO5GDsM6o/vObzyWEnI0lFzLMGz4enAUEAoZfE6G0hOVJd9x4vNOk qVOCWLUffbOT8DqxG/UDyy1ZzU7/CKp1BUd86hltby2Nbj4KmXhrFMW0rvhHHS7HuwfV tKU+QMgrDYjRy7dafXey+jGzKw9IFu3LoUpvm085YVPVN/VGcob+e5gOfj+fu0xzlUhx HdmF/NSm36vJFy394uqRsZS0yRxSIhTkepRdRHVVz3DYLwr3QFsht3WD7M2TgA+4eAPT 5E9g== X-Gm-Message-State: AFuF++m40aexTOlhGQOZ/VBvyAXclPgZzUSZwAWqtYgnW+6rO6r1OaaR Zvg1mNrOeB1VB/pyimfDllCvDpvokLHZzhcW0B2S6pqg6VfnZMEEcfn6n9ACXQ== X-Gm-Gg: AYBFou1GAH6KAf5NfvD7y0uay5Gew8oeF+7tevSzzYyimP0ibDba6y0Y6O2H6LaOChK xW4rpTivyThjTILpBS0DO2K9kYJ2nqF8TxdnOgO/DpB66xW3zaiy/p6tPr4clOcon6G4aiLvvh4 qSYsPXbAtURipdg0zA8hZSJO9/wm0EKKgrn0ljT/IFv9ZVmv+OBJ9W25/7FhAz7HKc3J57OwsX2 bcTuBwbD7HcurEnfBVYhJf4A7G8VdqPJaKJJSypTQSPZO66ELut91j9bAJYeWYJsNe9uQRHQdtN 9F6f2yq7tiAzEqPsc/ZM8/zngAtD+dYmxREonIbBFzY58yHtLCRBVvQ27T5uQqqWqwAV6CLjLPo moGQnvIYCgUWcGcZmJZ5BFw9LNN272+BXbBSF9IsaNkh0QcSrisx7P5lWKandnWM5Nb6C50w5Bv PIL8xT3a0KspHJfrX5hl1a2U0Tye5VexJlIiTsO7y1uqPwup10t+ppwgP31U2xXXvsMsNK1n0g X-Received: by 2002:a17:90b:2ccb:b0:398:9be8:ea64 with SMTP id 98e67ed59e1d1-39b261d8533mr39005572a91.17.1788776612857; Mon, 07 Sep 2026 03:23:32 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:32 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 3/33] libssh: ignore CVE-2025-14821 Date: Mon, 7 Sep 2026 22:22:47 +1200 Message-ID: <20260907102318.2459883-3-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129815 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2025-14821 Signed-off-by: Ankur Tyagi --- meta-oe/recipes-support/libssh/libssh_0.11.5.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meta-oe/recipes-support/libssh/libssh_0.11.5.bb b/meta-oe/recipes-support/libssh/libssh_0.11.5.bb index c28a417244..612cfdbb19 100644 --- a/meta-oe/recipes-support/libssh/libssh_0.11.5.bb +++ b/meta-oe/recipes-support/libssh/libssh_0.11.5.bb @@ -47,3 +47,5 @@ do_install_ptest () { } BBCLASSEXTEND = "native nativesdk" + +CVE_STATUS[CVE-2025-14821] = "not-applicable-platform: issue only applies on Windows" From patchwork Mon Sep 7 10:22:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97468 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 9E54AC79F9E for ; Mon, 7 Sep 2026 10:23:38 +0000 (UTC) Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31907.1788776616412891076 for ; Mon, 07 Sep 2026 03:23:36 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=kO/bjvet; spf=pass (domain: gmail.com, ip: 209.85.214.176, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-2d71ae3455aso50354325ad.1 for ; Mon, 07 Sep 2026 03:23:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776616; x=1789381416; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=8DdMkGnyqawS0RXP20RuvauKKd61bndJCGo6LHadSd4=; b=kO/bjvetptaNQHUD2XutCbXJa3EMUET6d6hpJdBwscGk+GzRm0K2QUAmegJK+Z9e20 YcPX0csbyLaxVcTlu1i6HDFRbuQDWf5zO5CmUNSbYabHrfRGFyfy9lCutVALnTlByMRw eHdBJzsKBhD63wp6Z6S3lHlB6pkNg+t+EzR6c/P25AMveStScQXvG9FR9vUxFUSb4eTv 2P03EAeKqEQw7uCZaPW6UrEF0o9yHD7rZt0YATKXECwB9j5lvnoa8YR7OI95D54HX6sS q5t5Nl6nKXelAbp93dFBJFdqEvzAW0L5gKvR7Me6olk38SbT5AcwwYSnWxYrdclLjFVu IXGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776616; x=1789381416; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=8DdMkGnyqawS0RXP20RuvauKKd61bndJCGo6LHadSd4=; b=GNyH+2Sew12jcqxx1kpIp+XDuw8kZyV2+raSPbTZe19FsLznRNoAwDNvcEIAuVOjfB iQyrX0eVPjQEPSXBdcP0izebBEBszs0qUDWwgaea/XeFpokMm3ULhK5K+FZyLGybmzLL U7rBA1m8Eur/T21LxGsMtrVfpG39emLGF6YFBd8htDPKANKl0hqsz/H9EB6e47eP/7db iUQh4jA+FGDzCwYwjOsLmlG7VOK4dNbaPh/doop/AoyvD4/fbM+m3PSKLLy4FhaB+n/k ld6SiePTHx36X1mHlV7FcHM8W4XEbcCzqMiEDdnUBAw9WFspHSJm2SGgk4HcU6gZrajd O9sg== X-Gm-Message-State: AFuF++nQTouIwcfGpAc920VE3i8sG+ahtntm2F3MOey4MbOdxOHWrBjR KqGVlg9DOHa81J3XVOMVs+QD0m5EuIKQVYC97wDZI1+KQhaKlsGSSusp8RuBEusa X-Gm-Gg: AYBFou0RtUSnW7NHg+9ysBXahgxxyGsNN3HOsfwLJBKT/bd80r4voKrLMqYREMl2vF/ YiupugjFnz5UOiLFwbBMcaOALWNoH1G674FVunib6VoVcaywcK0cwQyiRoeN/HUthXH34JdY6Os 0/I+gr7XMMts/rbPZaffEPO6fXeKfxtpUIJ40PhUkGd+k+ASEf4ajns2oV8oAdOBj1gFhH2JCAk HI8J4HbmrrbQYo7ZyqM2zIP2JoIs+BOsF3lnMUUKFQmscBihbjPnciKLFy0+2ZRGhsPPFv0Uols QcfMdJRkc8DcR0Yw7gGR4l9btT5YD6gRTyKiawInZKzwPLpzw5zVYrJsrs2ywNm6ltRrRqtkP2L Q+osOMjsmXwA4LE6NyeLcFlwVpPuub0EMa3kwgG/TZUnXTZe71QtBEAJ/iCvNu1pJ2aUwlMedfC I9cLHSlTlKzjPaLnlDfw0HIYYwUz2gpIOc3t4s8f/NU77RN2HQnBi087u9STvZ3AxHgnRSF0T37 DEq4jX90HQ= X-Received: by 2002:a17:90b:3d48:b0:396:5f7f:52f5 with SMTP id 98e67ed59e1d1-39b260e13e0mr33443552a91.3.1788776615623; Mon, 07 Sep 2026 03:23:35 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:35 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 4/33] libssh: mark CVEs patched Date: Mon, 7 Sep 2026 22:22:48 +1200 Message-ID: <20260907102318.2459883-4-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129816 From: Ankur Tyagi Changelog[1] also confirms the fix. Details: https://nvd.nist.gov/vuln/detail/cve-2026-15370 https://nvd.nist.gov/vuln/detail/cve-2026-59843 https://nvd.nist.gov/vuln/detail/cve-2026-59844 https://nvd.nist.gov/vuln/detail/cve-2026-59845 https://nvd.nist.gov/vuln/detail/cve-2026-59846 https://nvd.nist.gov/vuln/detail/cve-2026-59847 https://nvd.nist.gov/vuln/detail/cve-2026-59848 https://nvd.nist.gov/vuln/detail/cve-2026-59849 https://nvd.nist.gov/vuln/detail/cve-2026-59850 [1]https://gitlab.com/libssh/libssh-mirror/-/blob/libssh-0.11.5/CHANGELOG?ref_type=tags Signed-off-by: Ankur Tyagi --- meta-oe/recipes-support/libssh/libssh_0.11.5.bb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/meta-oe/recipes-support/libssh/libssh_0.11.5.bb b/meta-oe/recipes-support/libssh/libssh_0.11.5.bb index 612cfdbb19..752bded528 100644 --- a/meta-oe/recipes-support/libssh/libssh_0.11.5.bb +++ b/meta-oe/recipes-support/libssh/libssh_0.11.5.bb @@ -49,3 +49,12 @@ do_install_ptest () { BBCLASSEXTEND = "native nativesdk" CVE_STATUS[CVE-2025-14821] = "not-applicable-platform: issue only applies on Windows" +CVE_STATUS[CVE-2026-15370] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2026-59843] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2026-59844] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2026-59845] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2026-59846] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2026-59847] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2026-59848] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2026-59849] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2026-59850] = "fixed-version: fixed in v0.11.5" From patchwork Mon Sep 7 10:22:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97474 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 DF22DC79F9F for ; Mon, 7 Sep 2026 10:23:48 +0000 (UTC) Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31909.1788776619220630044 for ; Mon, 07 Sep 2026 03:23:39 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=adnjHDqW; spf=pass (domain: gmail.com, ip: 209.85.216.42, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-39266382df6so2561489a91.3 for ; Mon, 07 Sep 2026 03:23:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776619; x=1789381419; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=BpGzoX4/8upCLpKsa5PYJYSs24+tyeyDiBTlLnY9Bec=; b=adnjHDqW47qQtSYpvoEMPXFQnP5zxRA2ItabEHaPAoCdxxcAai/+BHD3pg9/sCRSQ0 QE2hbE/2Fw9TIXINgyDDXzAVAQ7MGPsf3m1JGEY0dgZPbz8MFCTXv8EHu7h+LonDDJyw JdGaIht1/ro3QLH9GXelMgitZDcobx8NAvocgv9qNkw3lg4lZQlwEReuW4gOghkJokjX cQjmG+F40EaQ4OQjOyoWX59YUXOKjstaw5vK2DRBfe2JT7dBFxC9i5vfEJEuIoGdmjDr Y9MpdY5RBJoV5VS6ZG9D+Tslgx9wla9cUPP5K/sH4qJvREnWvQ7qghAAvPFb9KWFW0Lj feQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776619; x=1789381419; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=BpGzoX4/8upCLpKsa5PYJYSs24+tyeyDiBTlLnY9Bec=; b=g3VPa2PyVsvvSiKlDh1yVgIeYjBXsDOKKEbzm9WNwNWAL60frw2lPPJxnBkW4UXHF7 4yeRm35tXgMgfppOPNmj+Lw33IkNIPj7sfWT2/S57FZU2QGnh2MsgotdExuH+s0C8oFw LCODCwh3905HEVFMNeucIshH7MeSyoRBhjffykd3KO5B+SwhvWAGnvdcf+RY3+o9sMdh EYwOnGM5Gf1GNrPfAiNUkQC8S4U/X4BUUcDJz27VTHth7VcPH1hfb2sCk9Gm82E4MFx8 8d6n/asyGGq57sJC/v6ZYppUs3MngRq5yUab3J+iGek+14n/nGg5QFV+Qqn0lcoBxbMb d3qQ== X-Gm-Message-State: AFuF++m2zm9vYCi4IA1xYREAFBEAsqDikKrX2YXOVIaQbS2p9wggbOaN Ipzapd9J0y4pROlCkox+JwLPcKiIuyhP6ucABTqfFR9SwExv0jZRqYJMXD00y+sT X-Gm-Gg: AYBFou2DwVsMvfOUXS5KhMBQzhw2Yxf6AA2b62MNzRAEXcx3XefbpA5mF60NrZKtVT1 frPCdZVNh5hQ1Er6xCG7GpUyLXkEBcO7tt8Bj1l9vMVDfv+hXSQh/0vFDSvy7vHhATE+yMcDEQG SQLEONYILoH/n7ooieVPOgDpP7zcHWJ4vu3HQqJdExBkkN1ffANA04znKKV7gaF9/SlPpyQgsPe PopYwsbquFjNbEyV0ppUdG5ne0bG8te7svzh+ObjhQXhW/XzNVTggCJ5uDQVNnyWFIbiFLMFcRX DmSxvLnRH6xq4R18T/+gmxGQpx+UCvYkRGjyFSyT3eN14bX1Zgts6NjigIzCBLyWqMrk3wreIeq cV/MpM59eajde0DSTxHyhH4Si8UcDdYINv82CRFq9eSc5ooeF1cFXrLb3K6Ih0V/nTz4+5pPTB6 /kav5ctyQeC65H0EOSQIUZSzU7JKIW25OUTGZnPzAH7iAPJ0AvXVL0A7hl+UlqKslmn/LMomTbi /k87CFL7n8= X-Received: by 2002:a17:90b:56cf:b0:398:dcf6:d40e with SMTP id 98e67ed59e1d1-39b262aa580mr34248677a91.17.1788776618575; Mon, 07 Sep 2026 03:23:38 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:38 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 5/33] libssh: ignore CVE-2025-59842 Date: Mon, 7 Sep 2026 22:22:49 +1200 Message-ID: <20260907102318.2459883-5-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129817 From: Ankur Tyagi The vulnerability exists in GSSAPI key exchange introduced in v0.12.0[1] Also confirmed by libssh security advisory[2] Details: https://nvd.nist.gov/vuln/detail/cve-2026-59842 [1]https://gitlab.com/libssh/libssh-mirror/-/commit/88c2ea6752fab7b3da9cc4c51eaf632361a44080 [2]https://www.libssh.org/security/advisories/CVE-2026-59842.txt Signed-off-by: Ankur Tyagi --- meta-oe/recipes-support/libssh/libssh_0.11.5.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-oe/recipes-support/libssh/libssh_0.11.5.bb b/meta-oe/recipes-support/libssh/libssh_0.11.5.bb index 752bded528..5cc270477e 100644 --- a/meta-oe/recipes-support/libssh/libssh_0.11.5.bb +++ b/meta-oe/recipes-support/libssh/libssh_0.11.5.bb @@ -58,3 +58,4 @@ CVE_STATUS[CVE-2026-59847] = "fixed-version: fixed in v0.11.5" CVE_STATUS[CVE-2026-59848] = "fixed-version: fixed in v0.11.5" CVE_STATUS[CVE-2026-59849] = "fixed-version: fixed in v0.11.5" CVE_STATUS[CVE-2026-59850] = "fixed-version: fixed in v0.11.5" +CVE_STATUS[CVE-2025-59842] = "cpe-incorrect: the current version (0.11.5) is not affected" From patchwork Mon Sep 7 10:22:50 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97475 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 DB982C79F99 for ; Mon, 7 Sep 2026 10:23:48 +0000 (UTC) Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31686.1788776621997309922 for ; Mon, 07 Sep 2026 03:23:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=fjAsyMHU; spf=pass (domain: gmail.com, ip: 209.85.215.181, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-cc2276e6daeso2329088a12.0 for ; Mon, 07 Sep 2026 03:23:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776621; x=1789381421; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=bHQWEHzxAd/TDBXMxVPKwY5nCkfP6pqlaOGgP+LVR18=; b=fjAsyMHUVc5G9pI1lMxDvpqXC7DozhP4SCPtKnE66tcwydgVoELdIMZUb/J85H97qH 9DOTNts97VwiRCb+vJ0kn1WJd5aAGkXjfmAMy9100gcl8zRROaaZZGQARcplpmQSqltN 7YEmRbK87ZAcMoT9hPz/jvr/iGvQ6kLbmUVHV0l6Cik3CLEa7mu6gxtoUpQ8LoY7FU8N zDje3YaCdy72LWMtiRuLzIimo5ok0Ye2L70l+ZZvbKnD+T8Q4UQvP3caWT7EUMJzfAUN n3IKCfooILy40XNcu2AkEdy5+c0iDtACuDyft/wb75TwBXsx7G9zjtq+1zUgRgnf2djW 34OA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776621; x=1789381421; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=bHQWEHzxAd/TDBXMxVPKwY5nCkfP6pqlaOGgP+LVR18=; b=PdhIvSwf7xl1MogFo26Q2xHsJ+k7gAMlZqkLl+CUBv0eapoylj4+wIZc3gnn4ebpSn GvtSFOxeDl+PRkau1l6nZDtalFrva7s1m1ur+Z+LQVmg+EGTzTUf5723LRtxYgXnpH+V pZSEPYC69Dsbi1JTAYWLTIFg1yWAgVLqKjTrRMcTYVMtix2TKfzF5Grrt142STW+V2t8 RZjWgj5MEcntU0yFHpeEzrWkHDOYNPFrFW5YJ6uSWevkxXKOfZBIGuYwzbnkRjZfM57x 5ugFkuIbu5+55zwSM/+tYwaFb/0S3MvELDZbGzyVOm+o/S67lfD9g2DCOUznsCe4m5Td jHjA== X-Gm-Message-State: AFuF++nIS6Nt9f0VYqsoyKDRvQj+iHnalTfiuya9NEc5XJB6Y7kvO913 KGgCoFv3fgc4Lq+OXnF5Jq65X6CXuq9HcuutjCiBvIUjgd9XXqp616vWkMi222fh X-Gm-Gg: AYBFou3vHOwlgUpddgNcIlCPuCpGZZ1DE5JgoILiqpe3E02CuaJIXlWcEJiLliwBQYK h7+tkBibIcmQ4S3Lp9ML8yJF7Dt/1gEWkVI0N+ZVlZUZ3hrP5ERzs03WnC8SEpKbTPgRZoVKOwq pnQkvGWg/IKEfn44Pv3UqHRXF2gKoY8VvD/HNbd84aHWH+cW/XD8B2QD4jwen2UatoFm64wV/0L bp4P9b7fz7lLohtwNJWqvqwcrWgaxYhAoLSYS2s5+xJ0p4ZMdJPZW48TSraGl2hLkilLyVwKWKS dczIEqxR1y6xXVVeFsqTYezUgAUlVer2wMRp0LrXZBqCkzSqpoavF3RcHFgFa7PdMxjb5gjUNOx OeQSvj9UI4RPk1DKzd2bBVb/64Er1KGFBKAMihYg/pxTtqwd6PtuW7fb9wrjx8giEQ18NDm0CoU 7AExApxEYPq0PncZ+90pmdSnbGKjM+VKPwYHavk2qNiay5pCrs7KV5PFAFEpYnQeDfGEYk1OKo X-Received: by 2002:a05:6a21:7a91:b0:3d0:e034:a26f with SMTP id adf61e73a8af0-3da3a0a6f2fmr38361768637.17.1788776621244; Mon, 07 Sep 2026 03:23:41 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:40 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 6/33] miniupnpd: patch CVE-2026-5720 Date: Mon, 7 Sep 2026 22:22:50 +1200 Message-ID: <20260907102318.2459883-6-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129818 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-5720 Signed-off-by: Ankur Tyagi --- .../miniupnpd/files/CVE-2026-5720.patch | 35 +++++++++++++++++++ .../miniupnpd/miniupnpd_2.1.20191006.bb | 1 + 2 files changed, 36 insertions(+) create mode 100644 meta-networking/recipes-connectivity/miniupnpd/files/CVE-2026-5720.patch diff --git a/meta-networking/recipes-connectivity/miniupnpd/files/CVE-2026-5720.patch b/meta-networking/recipes-connectivity/miniupnpd/files/CVE-2026-5720.patch new file mode 100644 index 0000000000..902e8321a5 --- /dev/null +++ b/meta-networking/recipes-connectivity/miniupnpd/files/CVE-2026-5720.patch @@ -0,0 +1,35 @@ +From d1c82ab65fd685ceed28a1a0de29510df7c3c959 Mon Sep 17 00:00:00 2001 +From: Thomas Bernard +Date: Mon, 23 Mar 2026 02:37:02 +0100 +Subject: [PATCH] upnphttp.c: fix removal of quotes in ParseHttpHeaders() + +the length of the string including the quotes must be at +least 2 for the string to contain the 2 enclosing quotes ! + +(cherry picked from commit f56bd09b2f2650126b832c5f30a65a09e28167fa) + +CVE: CVE-2026-5720 +Upstream-Status: Backport [https://github.com/miniupnp/miniupnp/commit/f56bd09b2f2650126b832c5f30a65a09e28167fa] + +Signed-off-by: Ankur Tyagi +--- + upnphttp.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/upnphttp.c b/upnphttp.c +index fc8ccb6..2d9a2a6 100644 +--- a/upnphttp.c ++++ b/upnphttp.c +@@ -269,9 +269,10 @@ ParseHttpHeaders(struct upnphttp * h) + p++; + while(p[n]>=' ') + n++; +- if((p[0] == '"' && p[n-1] == '"') +- || (p[0] == '\'' && p[n-1] == '\'')) ++ if((n >= 2) && ((p[0] == '"' && p[n-1] == '"') ++ || (p[0] == '\'' && p[n-1] == '\''))) + { ++ /* remove the quotes */ + p++; n -= 2; + } + h->req_soapActionOff = p - h->req_buf; diff --git a/meta-networking/recipes-connectivity/miniupnpd/miniupnpd_2.1.20191006.bb b/meta-networking/recipes-connectivity/miniupnpd/miniupnpd_2.1.20191006.bb index b7ba37f290..0aadfe9cf6 100644 --- a/meta-networking/recipes-connectivity/miniupnpd/miniupnpd_2.1.20191006.bb +++ b/meta-networking/recipes-connectivity/miniupnpd/miniupnpd_2.1.20191006.bb @@ -14,6 +14,7 @@ DEPENDS += "iptables net-tools util-linux libmnl libnetfilter-conntrack openssl" SRC_URI = "http://miniupnp.tuxfamily.org/files/download.php?file=${BP}.tar.gz;downloadfilename=${BP}.tar.gz \ file://miniupnpd.service \ file://0001-Add-OpenEmbedded-cross-compile-case.patch \ + file://CVE-2026-5720.patch \ " SRC_URI[sha256sum] = "218fad7af31f3c22fb4c9db28a55a2a8b5067d41f5b38f52008a057a00d2206d" From patchwork Mon Sep 7 10:22:51 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97472 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 C566AC79F89 for ; Mon, 7 Sep 2026 10:23:48 +0000 (UTC) Received: from mail-pj1-f46.google.com (mail-pj1-f46.google.com [209.85.216.46]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31688.1788776624936434740 for ; Mon, 07 Sep 2026 03:23:44 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=SMHwAK6M; spf=pass (domain: gmail.com, ip: 209.85.216.46, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f46.google.com with SMTP id 98e67ed59e1d1-38ec1402b05so3087660a91.2 for ; Mon, 07 Sep 2026 03:23:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776624; x=1789381424; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+SZZmX/Y07RTmxtMCdwsSfpVUYohmSv02CXQWcQIvVo=; b=SMHwAK6MqXr2ryZdcplcsOkydWvdPH/azof3106FQGB0PTfKqrFjBEdjB72lk39tTH uG4MpzgfdlPpoQFSBBLGcoPA2Dset8bme29HiyY98/Ko3KVbJ0GCPHY14tBnpMxMxUW4 Fi8QHiI5yFllVGKyWG4B1J3fhncLqLTSS5ZH/Gsh6pUh1qRRFFnST2OTQpnSIaCBhVx5 jvty4e5QNZpsOhZfh9AklegvIglOGRmwJtcdy/2FNCgYSzjf9hhC34eGiiw60p/fjuEo 6L3PEhsgZLBMf784+HN18lVt9btPDfTh6bQUksd9hpmw2MSxxxIPnQhyciIwI4AYFHro GOWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776624; x=1789381424; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=+SZZmX/Y07RTmxtMCdwsSfpVUYohmSv02CXQWcQIvVo=; b=AuqSYAKrOtjvY9G0mUvRBPq85lbEroCd9PJoKCiN5VlvTM3WtsqqdtYb2XXUkmAEJn eBpzr2jlNc9/TByZNnGLeRycARtuktr98r7QgcDACh8e57T3HqZz/L9iGYP5/oUQdQk4 aiHy7jjE/QJhHKlmxafrgJrOSHvlQZE3VIDazMiV9gJ27TGT/ozJnGVbTiCbg8YeakDD NIqeSQ5BlCHbvbIld6on9SNRi696EvASySLdndk58HuxjZDABo8BZfGuIZaokVeejAUv OqAtscAgSwZwP3Y56m2bzy9YhXVA/e9mo2o0EgP8lAm5FUZBsl1QrxPiFiR3gTs5YP1P D5Fg== X-Gm-Message-State: AFuF++lZQyI+C5X+D6UA/2wR98gnUB9ErcYcOq60uhzmeYAkUyY/erWS GDcPNPftZ+krmeabVgB1UKkzwDw5+JBg/5taZyvqt5UE6DxnAADLHUuhcP9NJZDU X-Gm-Gg: AYBFou05nZEgO1sB9J8Ti+M16ktWecY36HWNpCJMO7sV9ZGmoisYrT8AIHIyCWcbY2t 4Aiv3WYl1mKGmHp0fGy0CkNTv6kCXFAbl5fdsP8BHEceduoSOxnpB8dxOkQMfgcv+7IHPLW7d0F ZD1NROukcrWTrNZGfkCebh5ZnQarBv4TzxZwq0xCGfWNo+Ih4HgyUcn0swOtdzluXgW9K8g8P50 cHqMQm0H6OVPCRiiVclVZqK3A62ampSsKGwSlTVbUgnUTgXjNqIk4Sgaptm+DfPSq0Lcg3qowdS 9GE3x1rSsZpLSVjAouDB/V2epJWzvOoCUCKhYuiCiUlltbeDJX1QjbJDo/vZCAi3QN4c8OkDBVM fDECPvDFIEL0BkEImDN2gpXUltsXZXYE4Brv3LFpuF/pYBDRTqE0v4uEbKrh5k0Dw7Qad+f3cR7 gDw+91hMKJfIPQVN8FwwqkmhbdHjyp1WRtD0ZKdJzyN4Um1sfJiL6CaBQn54xqRpdytvyGC/d6 X-Received: by 2002:a17:90b:5287:b0:38e:6a44:671b with SMTP id 98e67ed59e1d1-39b25eeeef9mr34959627a91.0.1788776623926; Mon, 07 Sep 2026 03:23:43 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:43 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][wrynose][PATCH 7/33] python3-zeroconf: patch CVE-2026-47180 Date: Mon, 7 Sep 2026 22:22:51 +1200 Message-ID: <20260907102318.2459883-7-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129819 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-47180 Signed-off-by: Ankur Tyagi --- .../python3-zeroconf/CVE-2026-47180.patch | 110 ++++++++++++++++++ .../python/python3-zeroconf_0.148.0.bb | 2 + 2 files changed, 112 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47180.patch diff --git a/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47180.patch b/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47180.patch new file mode 100644 index 0000000000..7d27066d6f --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47180.patch @@ -0,0 +1,110 @@ +From 7ffd3a90230cb99bcae4350fcb8498c48044f6a6 Mon Sep 17 00:00:00 2001 +From: "J. Nick Koston" +Date: Sun, 17 May 2026 19:48:44 -0700 +Subject: [PATCH] fix: bound DNS compression-pointer chain depth in DNSIncoming + (#1719) + +(cherry picked from commit f9e23592137f30fdf7ef710dba065da31c79b1cf) + +CVE: CVE-2026-47180 +Upstream-Status: Backport [https://github.com/python-zeroconf/python-zeroconf/commit/f9e23592137f30fdf7ef710dba065da31c79b1cf] +Signed-off-by: Ankur Tyagi +--- + src/zeroconf/_protocol/incoming.pxd | 2 +- + src/zeroconf/_protocol/incoming.py | 14 ++++++++++---- + tests/test_protocol.py | 22 ++++++++++++++++++++++ + 3 files changed, 33 insertions(+), 5 deletions(-) + +diff --git a/src/zeroconf/_protocol/incoming.pxd b/src/zeroconf/_protocol/incoming.pxd +index feaa2a0..eface8d 100644 +--- a/src/zeroconf/_protocol/incoming.pxd ++++ b/src/zeroconf/_protocol/incoming.pxd +@@ -83,7 +83,7 @@ cdef class DNSIncoming: + link_py_int=object, + linked_labels=cython.list + ) +- cdef unsigned int _decode_labels_at_offset(self, unsigned int off, cython.list labels, cython.set seen_pointers) ++ cdef unsigned int _decode_labels_at_offset(self, unsigned int off, cython.list labels, cython.set seen_pointers, unsigned int depth) + + @cython.locals(offset="unsigned int") + cdef void _read_header(self) +diff --git a/src/zeroconf/_protocol/incoming.py b/src/zeroconf/_protocol/incoming.py +index 2d977b6..d772f47 100644 +--- a/src/zeroconf/_protocol/incoming.py ++++ b/src/zeroconf/_protocol/incoming.py +@@ -60,7 +60,7 @@ DNS_COMPRESSION_POINTER_LEN = 2 + MAX_DNS_LABELS = 128 + MAX_NAME_LENGTH = 253 + +-DECODE_EXCEPTIONS = (IndexError, struct.error, IncomingDecodeError) ++DECODE_EXCEPTIONS = (IndexError, struct.error, IncomingDecodeError, RecursionError) + + + _seen_logs: dict[str, int | tuple] = {} +@@ -409,7 +409,7 @@ class DNSIncoming: + labels: list[str] = [] + seen_pointers: set[int] = set() + original_offset = self.offset +- self.offset = self._decode_labels_at_offset(original_offset, labels, seen_pointers) ++ self.offset = self._decode_labels_at_offset(original_offset, labels, seen_pointers, 0) + self._name_cache[original_offset] = labels + name = ".".join(labels) + "." + if len(name) > MAX_NAME_LENGTH: +@@ -418,8 +418,14 @@ class DNSIncoming: + ) + return name + +- def _decode_labels_at_offset(self, off: _int, labels: list[str], seen_pointers: set[int]) -> int: ++ def _decode_labels_at_offset( ++ self, off: _int, labels: list[str], seen_pointers: set[int], depth: _int ++ ) -> int: + # This is a tight loop that is called frequently, small optimizations can make a difference. ++ if depth > MAX_DNS_LABELS: ++ raise IncomingDecodeError( ++ f"DNS compression pointer chain exceeds {MAX_DNS_LABELS} at {off} from {self.source}" ++ ) + view = self.view + while off < self._data_len: + length = view[off] +@@ -457,7 +463,7 @@ class DNSIncoming: + if not linked_labels: + linked_labels = [] + seen_pointers.add(link_py_int) +- self._decode_labels_at_offset(link, linked_labels, seen_pointers) ++ self._decode_labels_at_offset(link, linked_labels, seen_pointers, depth + 1) + self._name_cache[link_py_int] = linked_labels + labels.extend(linked_labels) + if len(labels) > MAX_DNS_LABELS: +diff --git a/tests/test_protocol.py b/tests/test_protocol.py +index edd87c2..bac2b44 100644 +--- a/tests/test_protocol.py ++++ b/tests/test_protocol.py +@@ -1011,6 +1011,28 @@ def test_label_compression_attack(): + assert len(parsed.answers()) == 1 + + ++def test_dns_compression_pointer_chain_depth_attack() -> None: ++ """Test our wire parser rejects deeply chained compression pointers without recursing.""" ++ # Build a packet with one question whose name is a 1500-deep chain of forward ++ # compression pointers, ending in a root label. Each pointer is 2 bytes, ++ # so chain length easily exceeds CPython's default recursion limit. ++ header = b"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" ++ # Question at offset 12: pointer to offset 18 (past the question's type/class). ++ question_name = bytes([0xC0, 18]) ++ question_type_class = b"\x00\x01\x00\x01" ++ chain_depth = 1500 ++ chain = bytearray() ++ for i in range(chain_depth): ++ target = 18 + 2 * (i + 1) ++ chain.append(0xC0 | (target >> 8)) ++ chain.append(target & 0xFF) ++ chain.append(0x00) ++ packet = header + question_name + question_type_class + bytes(chain) ++ parsed = r.DNSIncoming(packet, ("1.2.3.4", 5353)) ++ assert parsed.valid is False ++ assert parsed.questions == [] ++ ++ + def test_dns_compression_loop_attack(): + """Test our wire parser does not loop forever when dns compression is in a loop.""" + packet = ( diff --git a/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb b/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb index fd083d6ee8..c405e83b8c 100644 --- a/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb +++ b/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb @@ -5,6 +5,8 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=9fe712b1bc27c5c4e9ecd7f31d208900" SRC_URI[sha256sum] = "03fcca123df3652e23d945112d683d2f605f313637611b7d4adf31056f681702" +SRC_URI += "file://CVE-2026-47180.patch" + inherit pypi python_poetry_core cython RDEPENDS:${PN} += " \ From patchwork Mon Sep 7 10:22:52 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97473 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 D2EA0C79F9E for ; Mon, 7 Sep 2026 10:23:48 +0000 (UTC) Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31689.1788776627622448095 for ; Mon, 07 Sep 2026 03:23:47 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=moTYZqgN; spf=pass (domain: gmail.com, ip: 209.85.215.181, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-cc1a4c62804so2579834a12.3 for ; Mon, 07 Sep 2026 03:23:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776627; x=1789381427; darn=lists.openembedded.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=E69uXQHOAPTZHlSvoWvWzP7KavP+3HVOqftn9f0txIc=; b=moTYZqgNDx8qND2AFaZu9DdLMAGFPoA+gsXqC0UCy9uxgaDtA/f+l1V5+v20zs6KqI ShuF2RsEtVleIBwhN9t+ZIVqK9JMKdM3CX8B9dKQ2cV48g568MbmIMYe2UfhS5D85g37 mwjS1b4DWDttUim+HhFkMrQEIrM6e/rEqi3P/TDIWFYuztD8pK3+NSA2ZLAEKX7vR9uA HmAVDT+EJZLHDHg+D8HFkQ7JkD+lDVZFCYoF4DEfyTIWsBxsOlPhOpiyX/69sFj28x+4 TpEKTVSFJlUf4xaJx6vV52SCyfnZdSGB689yvDG9SR8nHkNt0E4y/EiVlSUHLNKyH0hW OvDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776627; x=1789381427; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=E69uXQHOAPTZHlSvoWvWzP7KavP+3HVOqftn9f0txIc=; b=Ji3weKTPB64sVA+WYT4P1E4czgPQw8CHo2oAYHJUu9Ic/xT7MRFRlZCPBMXtEyF9JB 6uMzJDz++m4T/I4balKZu6zUxlv/AibPq5qSJZKLMj4nLCcU9x7O9JYwLj7JDc95OC4S FCZbQ1WZpS21DdmSKxCKlpooNEnTvIv24CwOlVVC9tsgNGBU7Yl7exDucPQ1BdiUDS7W zsK+2cv7lVl5k5E8hcuRVRSiwSTVAOX2GEORXBlYi3H4Uf5XHoZJWRGAUb2bTlgpu/iG P7svjpE6cRjxxWQqv+LrE0Z942kdknnag3oD5qSt2TKMptKM7qA2MXLiDV1meELgwmMo 0Ylw== X-Gm-Message-State: AFuF++lg9WGMy9JkDN70TP0Cifjc4FjVFRcOuM93kf4fMk/+yGacQdk6 okyyH2PxHXwhWT50J28ySlFT72sFl/YGGgNyv6EEKUHxDY1K2yzmteeji2vHHA== X-Gm-Gg: AYBFou3RJ1sD43D0xS1hb9zLGtv1y0c5cZVXhbtmKSLdzwSdgAnjFLonjoUDKVUa/wg f5c4j7om7/OvBRTWVQ9Jl/7E5FID8Kx1/DdibzAHw3dlvi/7Rp+vupeC0upyUv2Kb7cOj75cevB xC7EBgGUixcXE4AnmKLzAuthctEsH9uL+QaDOPXycR/ZJv32P760BWYg8t5haFfsydVAi1JYg/a FVMiprKUE9y8o/nccz6J06VzLfE3nrA1/1HsCUhqaK3q3QQknDVz1JrkrUQ6TFdDSWkbLrnbafA NHKUKzemUf4zY6q2+ZgA4fxac81yrCbxXOtY6yEgp+4Lk/C7WHx7l1AQf6jzL+lMut3/An0c/Wq zfI5sUoc4I+xxLhlC2opCnYG0f7yjNi66Tf88tZ4woCUBDgp3JBkMP57hpr+6fCtZP5u8zhw6+R 4EbXVxCZvK9v8466Anp6KVKvCMozUUDadXxEX01XGaEPgDKwWVzxwXYeItm6PT3xqhVsDT+QisY Mu2E3fKPGQ4 X-Received: by 2002:a17:90b:2687:b0:398:9c0c:7c71 with SMTP id 98e67ed59e1d1-39b26277b88mr32966558a91.24.1788776626830; Mon, 07 Sep 2026 03:23:46 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:46 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][wrynose][PATCH 8/33] python3-zeroconf: patch CVE-2026-47183 Date: Mon, 7 Sep 2026 22:22:52 +1200 Message-ID: <20260907102318.2459883-8-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129820 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-47183 Signed-off-by: Ankur Tyagi --- .../python3-zeroconf/CVE-2026-47183.patch | 401 ++++++++++++++++++ .../python/python3-zeroconf_0.148.0.bb | 4 +- 2 files changed, 404 insertions(+), 1 deletion(-) create mode 100644 meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47183.patch diff --git a/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47183.patch b/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47183.patch new file mode 100644 index 0000000000..a1ab4cbfe6 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47183.patch @@ -0,0 +1,401 @@ +From 831dda6b9d17d6abd6e9501b45ad8b3573a8fab5 Mon Sep 17 00:00:00 2001 +From: "J. Nick Koston" +Date: Sun, 17 May 2026 20:58:18 -0700 +Subject: [PATCH] fix: bound _seen_logs and stop retaining exc_info (#1717) + +(cherry picked from commit 95561e28b24922358f1991e38e3a86d70d72dcec) + +CVE: CVE-2026-47183 +Upstream-Status: Backport [https://github.com/python-zeroconf/python-zeroconf/commit/95561e28b24922358f1991e38e3a86d70d72dcec] + +Signed-off-by: Ankur Tyagi +--- + src/zeroconf/_logger.py | 89 +++++++++++++++++++----------- + src/zeroconf/_protocol/incoming.py | 12 +--- + tests/benchmarks/test_mark_seen.py | 39 +++++++++++++ + tests/test_logger.py | 87 +++++++++++++++++++++++++++-- + tests/test_protocol.py | 34 ++++++++++++ + 5 files changed, 214 insertions(+), 47 deletions(-) + create mode 100644 tests/benchmarks/test_mark_seen.py + +diff --git a/src/zeroconf/_logger.py b/src/zeroconf/_logger.py +index 0d734df..99990cf 100644 +--- a/src/zeroconf/_logger.py ++++ b/src/zeroconf/_logger.py +@@ -25,7 +25,7 @@ from __future__ import annotations + + import logging + import sys +-from typing import Any, ClassVar, cast ++from typing import Any + + log = logging.getLogger(__name__.split(".", maxsplit=1)[0]) + log.addHandler(logging.NullHandler()) +@@ -39,50 +39,73 @@ def set_logger_level_if_unset() -> None: + set_logger_level_if_unset() + + +-class QuietLogger: +- _seen_logs: ClassVar[dict[str, int | tuple]] = {} ++_MAX_SEEN_LOGS = 512 ++_seen_logs: dict[str, None] = {} ++ ++ ++def _evict_oldest(seen: dict[str, None]) -> bool: ++ """Pop the oldest entry from ``seen``; return False if it raced. ++ ++ Individual dict ops (``pop`` with a default, ``next``) are atomic ++ on the free-threaded build, but the compound ``iter`` → ``next`` ++ used to pick the FIFO victim can raise ``RuntimeError`` if ++ another thread mutates the dict between the two ops. The caller ++ breaks its drain loop on False so concurrent mutation can't make ++ it spin. ++ """ ++ try: ++ seen.pop(next(iter(seen)), None) ++ except (RuntimeError, StopIteration): ++ return False ++ return True ++ ++ ++def _mark_seen(seen: dict[str, None], key: str) -> bool: ++ """Record ``key`` in ``seen`` and return True if it was newly added. ++ ++ Bounds the dict so callers passing attacker-influenced keys (peer ++ addresses, packet offsets) cannot grow it without bound. Evicts ++ the oldest entries on overflow (dict preserves insertion order on ++ Python 3.7+), so ``_MAX_SEEN_LOGS`` is a recency window. ++ ++ The dict is shared across all ``Zeroconf`` instances in the ++ process; on the free-threaded build (3.14t) and under multi- ++ instance sync use, callers can race the ``len < cap`` check and ++ both insert, leaving the dict transiently above the cap. The ++ drain loop runs on every call (steady-state-at-cap hits are a ++ single ``len`` + compare past the membership check because the ++ helper short-circuits) so a contention burst is corrected by the ++ next caller regardless of whether it's a hit or a miss. ++ """ ++ inserting = key not in seen ++ # Hit (``inserting`` is False): drain only if drifted above cap. ++ # Miss (``inserting`` is True): drain to ``cap - 1`` to make room ++ # for the new key. Bool subtracts as 0/1 to pick the right limit. ++ while len(seen) > _MAX_SEEN_LOGS - inserting and _evict_oldest(seen): ++ pass ++ if inserting: ++ seen[key] = None ++ return inserting ++ + ++class QuietLogger: + @classmethod + def log_exception_warning(cls, *logger_data: Any) -> None: +- exc_info = sys.exc_info() +- exc_str = str(exc_info[1]) +- if exc_str not in cls._seen_logs: +- # log at warning level the first time this is seen +- cls._seen_logs[exc_str] = exc_info +- logger = log.warning +- else: +- logger = log.debug ++ first_time = _mark_seen(_seen_logs, str(sys.exc_info()[1])) ++ logger = log.warning if first_time else log.debug + logger(*(logger_data or ["Exception occurred"]), exc_info=True) + + @classmethod + def log_exception_debug(cls, *logger_data: Any) -> None: +- log_exc_info = False +- exc_info = sys.exc_info() +- exc_str = str(exc_info[1]) +- if exc_str not in cls._seen_logs: +- # log the trace only on the first time +- cls._seen_logs[exc_str] = exc_info +- log_exc_info = True +- log.debug(*(logger_data or ["Exception occurred"]), exc_info=log_exc_info) ++ first_time = _mark_seen(_seen_logs, str(sys.exc_info()[1])) ++ log.debug(*(logger_data or ["Exception occurred"]), exc_info=first_time) + + @classmethod + def log_warning_once(cls, *args: Any) -> None: +- msg_str = args[0] +- if msg_str not in cls._seen_logs: +- cls._seen_logs[msg_str] = 0 +- logger = log.warning +- else: +- logger = log.debug +- cls._seen_logs[msg_str] = cast(int, cls._seen_logs[msg_str]) + 1 ++ logger = log.warning if _mark_seen(_seen_logs, args[0]) else log.debug + logger(*args) + + @classmethod + def log_exception_once(cls, exc: Exception, *args: Any) -> None: +- msg_str = args[0] +- if msg_str not in cls._seen_logs: +- cls._seen_logs[msg_str] = 0 +- logger = log.warning +- else: +- logger = log.debug +- cls._seen_logs[msg_str] = cast(int, cls._seen_logs[msg_str]) + 1 ++ logger = log.warning if _mark_seen(_seen_logs, args[0]) else log.debug + logger(*args, exc_info=exc) +diff --git a/src/zeroconf/_protocol/incoming.py b/src/zeroconf/_protocol/incoming.py +index d772f47..ffbbb59 100644 +--- a/src/zeroconf/_protocol/incoming.py ++++ b/src/zeroconf/_protocol/incoming.py +@@ -37,7 +37,7 @@ from .._dns import ( + DNSText, + ) + from .._exceptions import IncomingDecodeError +-from .._logger import log ++from .._logger import _mark_seen, log + from .._utils.time import current_time_millis + from ..const import ( + _FLAGS_QR_MASK, +@@ -63,7 +63,7 @@ MAX_NAME_LENGTH = 253 + DECODE_EXCEPTIONS = (IndexError, struct.error, IncomingDecodeError, RecursionError) + + +-_seen_logs: dict[str, int | tuple] = {} ++_seen_logs: dict[str, None] = {} + _str = str + _int = int + +@@ -182,13 +182,7 @@ class DNSIncoming: + + @classmethod + def _log_exception_debug(cls, *logger_data: Any) -> None: +- log_exc_info = False +- exc_info = sys.exc_info() +- exc_str = str(exc_info[1]) +- if exc_str not in _seen_logs: +- # log the trace only on the first time +- _seen_logs[exc_str] = exc_info +- log_exc_info = True ++ log_exc_info = _mark_seen(_seen_logs, str(sys.exc_info()[1])) + log.debug(*(logger_data or ["Exception occurred"]), exc_info=log_exc_info) + + def answers(self) -> list[DNSRecord]: +diff --git a/tests/benchmarks/test_mark_seen.py b/tests/benchmarks/test_mark_seen.py +new file mode 100644 +index 0000000..4f82da8 +--- /dev/null ++++ b/tests/benchmarks/test_mark_seen.py +@@ -0,0 +1,39 @@ ++"""Benchmark for _logger._mark_seen.""" ++ ++from __future__ import annotations ++ ++from pytest_codspeed import BenchmarkFixture ++ ++from zeroconf._logger import _MAX_SEEN_LOGS, _mark_seen ++ ++ ++def test_mark_seen_hit(benchmark: BenchmarkFixture) -> None: ++ """Benchmark the cache-hit path (same key repeated).""" ++ seen: dict[str, None] = {"warm": None} ++ ++ @benchmark ++ def _hit() -> None: ++ for _ in range(1000): ++ _mark_seen(seen, "warm") ++ ++ ++def test_mark_seen_fill(benchmark: BenchmarkFixture) -> None: ++ """Benchmark filling from empty up to the cap (no evictions).""" ++ keys = [f"key-{i}" for i in range(_MAX_SEEN_LOGS)] ++ ++ @benchmark ++ def _fill() -> None: ++ seen: dict[str, None] = {} ++ for k in keys: ++ _mark_seen(seen, k) ++ ++ ++def test_mark_seen_churn(benchmark: BenchmarkFixture) -> None: ++ """Benchmark sustained eviction (every call past the cap drops oldest).""" ++ keys = [f"churn-{i}" for i in range(_MAX_SEEN_LOGS * 4)] ++ ++ @benchmark ++ def _churn() -> None: ++ seen: dict[str, None] = {} ++ for k in keys: ++ _mark_seen(seen, k) +diff --git a/tests/test_logger.py b/tests/test_logger.py +index 4e09aa3..8042e49 100644 +--- a/tests/test_logger.py ++++ b/tests/test_logger.py +@@ -5,7 +5,8 @@ from __future__ import annotations + import logging + from unittest.mock import call, patch + +-from zeroconf._logger import QuietLogger, set_logger_level_if_unset ++from zeroconf import _logger ++from zeroconf._logger import _MAX_SEEN_LOGS, QuietLogger, _mark_seen, set_logger_level_if_unset + + + def test_loading_logger(): +@@ -25,7 +26,7 @@ def test_loading_logger(): + + def test_log_warning_once(): + """Test we only log with warning level once.""" +- QuietLogger._seen_logs = {} ++ _logger._seen_logs.clear() + quiet_logger = QuietLogger() + with ( + patch("zeroconf._logger.log.warning") as mock_log_warning, +@@ -48,7 +49,7 @@ def test_log_warning_once(): + + def test_log_exception_warning(): + """Test we only log with warning level once.""" +- QuietLogger._seen_logs = {} ++ _logger._seen_logs.clear() + quiet_logger = QuietLogger() + with ( + patch("zeroconf._logger.log.warning") as mock_log_warning, +@@ -71,7 +72,7 @@ def test_log_exception_warning(): + + def test_llog_exception_debug(): + """Test we only log with a trace once.""" +- QuietLogger._seen_logs = {} ++ _logger._seen_logs.clear() + quiet_logger = QuietLogger() + with patch("zeroconf._logger.log.debug") as mock_log_debug: + quiet_logger.log_exception_debug("the exception") +@@ -84,9 +85,85 @@ def test_llog_exception_debug(): + assert mock_log_debug.mock_calls == [call("the exception", exc_info=False)] + + ++def test_mark_seen_absorbs_runtime_error_during_eviction() -> None: ++ """Concurrent mutation can make ``iter(seen)`` raise ``RuntimeError``. ++ ++ Free-threaded (3.14t) and multi-instance sync callers share ++ ``_seen_logs``; if another thread mutates it between ``iter()`` ++ and ``next()`` the iterator raises ``RuntimeError``. ++ ``_mark_seen`` must absorb that and still insert the new key. ++ """ ++ ++ class RacyDict(dict[str, None]): ++ def __iter__(self): # type: ignore[override] ++ raise RuntimeError("dictionary changed size during iteration") ++ ++ seen: dict[str, None] = RacyDict() ++ for i in range(_MAX_SEEN_LOGS): ++ seen[f"k-{i}"] = None ++ assert _mark_seen(seen, "new-key") is True ++ assert "new-key" in seen ++ ++ ++def test_mark_seen_drains_drift_above_cap() -> None: ++ """``_mark_seen`` drains a drifted-over-cap dict back to the cap. ++ ++ Concurrent inserts on the free-threaded build can leave the dict ++ transiently above ``_MAX_SEEN_LOGS`` (e.g. two threads both passed ++ the ``len < cap`` check and both inserted). The next non-racing ++ call must drain the accumulated overshoot, not just evict one ++ entry — otherwise the cap silently inflates with thread count. ++ """ ++ seen: dict[str, None] = {} ++ drift = 10 ++ for i in range(_MAX_SEEN_LOGS + drift): ++ seen[f"k-{i}"] = None ++ assert len(seen) == _MAX_SEEN_LOGS + drift ++ assert _mark_seen(seen, "new-key") is True ++ assert len(seen) == _MAX_SEEN_LOGS ++ assert "new-key" in seen ++ for i in range(drift + 1): ++ assert f"k-{i}" not in seen ++ ++ ++def test_mark_seen_drains_drift_on_hit_path() -> None: ++ """``_mark_seen`` drains drift even when ``key`` is already cached. ++ ++ A hit-heavy workload after a contention burst (e.g. the same ++ exception text deduplicated repeatedly) must still correct the ++ overshoot — otherwise the dict can sit permanently above the cap ++ until a miss happens to come along. ++ """ ++ seen: dict[str, None] = {} ++ drift = 10 ++ for i in range(_MAX_SEEN_LOGS + drift): ++ seen[f"k-{i}"] = None ++ # Hit on a non-oldest key — survives the drift drain. ++ hit_key = f"k-{_MAX_SEEN_LOGS}" ++ assert _mark_seen(seen, hit_key) is False ++ assert len(seen) == _MAX_SEEN_LOGS ++ assert hit_key in seen ++ for i in range(drift): ++ assert f"k-{i}" not in seen ++ ++ ++def test_seen_logs_is_bounded() -> None: ++ """``_seen_logs`` stays at the cap and evicts oldest-first (FIFO).""" ++ _logger._seen_logs.clear() ++ overflow = 5 ++ with patch("zeroconf._logger.log.warning"), patch("zeroconf._logger.log.debug"): ++ for i in range(_MAX_SEEN_LOGS + overflow): ++ QuietLogger.log_warning_once(f"warning-{i}") ++ assert len(_logger._seen_logs) == _MAX_SEEN_LOGS ++ for i in range(overflow): ++ assert f"warning-{i}" not in _logger._seen_logs ++ for i in range(_MAX_SEEN_LOGS, _MAX_SEEN_LOGS + overflow): ++ assert f"warning-{i}" in _logger._seen_logs ++ ++ + def test_log_exception_once(): + """Test we only log with warning level once.""" +- QuietLogger._seen_logs = {} ++ _logger._seen_logs.clear() + quiet_logger = QuietLogger() + exc = Exception() + with ( +diff --git a/tests/test_protocol.py b/tests/test_protocol.py +index bac2b44..782b77a 100644 +--- a/tests/test_protocol.py ++++ b/tests/test_protocol.py +@@ -14,6 +14,8 @@ import pytest + + import zeroconf as r + from zeroconf import DNSHinfo, DNSIncoming, DNSText, const, current_time_millis ++from zeroconf._logger import _MAX_SEEN_LOGS ++from zeroconf._protocol import incoming as _incoming_module + + from . import has_working_ipv6 + +@@ -962,6 +964,38 @@ def test_dns_compression_generic_failure(caplog): + assert "Received invalid packet from ('1.2.3.4', 5353)" in caplog.text + + ++def test_seen_logs_is_bounded(): ++ """Corrupt packets from varying peers fill ``_seen_logs`` exactly to the cap.""" ++ packet = ( ++ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06domain\x05local\x00\x00\x01" ++ b"\x80\x01\x00\x00\x00\x01\x00\x04\xc0\xa8\xd0\x05-\x0c\x00\x01\x80\x01\x00\x00" ++ b"\x00\x01\x00\x04\xc0\xa8\xd0\x06" ++ ) ++ overflow = 5 ++ _incoming_module._seen_logs.clear() ++ # Snapshot the actual key the parser inserted per port. This is whatever ++ # ``str(exc_info()[1])`` produces today — the test stays agnostic to the ++ # exception text format so a future normalization of the message (see ++ # the discussion on #1714) doesn't break the assertions, while still ++ # pinning that the parser exception path actually entered the dict. ++ keys_per_port: list[str] = [] ++ for port in range(_MAX_SEEN_LOGS + overflow): ++ r.DNSIncoming(packet, ("1.2.3.4", port)) ++ keys_per_port.append(next(reversed(_incoming_module._seen_logs))) ++ # Bound is hit exactly. ++ assert len(_incoming_module._seen_logs) == _MAX_SEEN_LOGS ++ # Each port produced a distinct dedup key — a regression that dropped ++ # the per-packet-varying component (e.g. self.source) from the exception ++ # text would collapse all 517 calls to one key and fail this. ++ assert len(set(keys_per_port)) == _MAX_SEEN_LOGS + overflow ++ # FIFO eviction by key identity (no substring matching on the message ++ # format): the earliest ports' keys are gone, the latest ports' remain. ++ for port in range(overflow): ++ assert keys_per_port[port] not in _incoming_module._seen_logs ++ for port in range(_MAX_SEEN_LOGS, _MAX_SEEN_LOGS + overflow): ++ assert keys_per_port[port] in _incoming_module._seen_logs ++ ++ + def test_label_length_attack(): + """Test our wire parser does not loop forever when the name exceeds 253 chars.""" + packet = ( diff --git a/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb b/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb index c405e83b8c..aa1bb11065 100644 --- a/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb +++ b/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb @@ -5,7 +5,9 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=9fe712b1bc27c5c4e9ecd7f31d208900" SRC_URI[sha256sum] = "03fcca123df3652e23d945112d683d2f605f313637611b7d4adf31056f681702" -SRC_URI += "file://CVE-2026-47180.patch" +SRC_URI += "file://CVE-2026-47180.patch \ + file://CVE-2026-47183.patch \ +" inherit pypi python_poetry_core cython From patchwork Mon Sep 7 10:22:53 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97479 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 25DDBC79FA7 for ; Mon, 7 Sep 2026 10:23:59 +0000 (UTC) Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31910.1788776630861871142 for ; Mon, 07 Sep 2026 03:23:50 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=b5jR0MS4; spf=pass (domain: gmail.com, ip: 209.85.210.171, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-85377c8bc96so3074281b3a.3 for ; Mon, 07 Sep 2026 03:23:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776630; x=1789381430; darn=lists.openembedded.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=pPZIVLW7sOO3e0HC8g4Jm/btV1zU+HjgjcuEoolkFHo=; b=b5jR0MS4b9tjeHTV72IJMZR4uQUA7d34S8yDZOFrlgjCZGrvhdzo15FIvcP82Axqlv CE4ltNUO1b2kXQIPR0IgCJEG7jy1aUU5H0ugSdqVL4K0PBeAjD97Kwpsi7S9VwUG4vTg P54n3/FrP5ek25WmhU9vMab3FLbiS8rHSfVtmOw9dzmposl6JJt8tR2AvCmVw18JvBcV vzEIPG3d7cRgG9u7e0BIfNQWvmcclLXvduDM7NOosGVNlYw5Ki9VNOA/Zk21NVsW6efJ +wzG9Os54f96pJAhA3j2vozBn1398CBv5VKcJJozZIzZw7zMop0EYdAjxrfOPTgqIzTr TtHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776630; x=1789381430; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=pPZIVLW7sOO3e0HC8g4Jm/btV1zU+HjgjcuEoolkFHo=; b=Ka3BVTVGibeLi5o1UtYLlqmRWr1wsFgf8SH9FeuON03MIML5W+HoJ3OluwY+vc+PIP giFczB1wxTFWYJJweDSSZIG7PWAvSBMAW5h1gtErjVR+oYT5coAD/QjEvtcsWTL9LhPQ t0P9BiTZCOq2twIU60mR+7sa6EiGHmEqPsXN/XxuxTu7oxXf12cUZ6pJEbj1tmZTgXNZ oOVMVXgxmD2338afVc1Rk+A0Z9DoVG+HgFHglpt5y0GvSPZovChRujI45P8Q7y8+m951 TGJ4o1bcH8EHU2HKUA+DfEp/yj+r2HqtNOe+siHxBFgCJpH6KvZ9NtSokTX5bBJ1Gja6 RAQg== X-Gm-Message-State: AFuF++k9lxqgq/TCRnt6HgBZnAc1/KkdUjZxWTg4ZVOn9V9gFPEkSFA1 FF3JUWKvL+S56KpbMyKWTTbWgo8j5h9WQDR3inr1q7MtBN6LGUqpyfvj54ovLXlg X-Gm-Gg: AYBFou0pKBwoHloRzGCLdXGBGjFhHQ2FZ6Y0vatx/3mTBQFHgTuigPE48m1X0l1XnwR NtZ9J/FlW3VRpXh9zUHvOQg5HVR41NcIuL2/SYVJrN4YSpBVRhuQGntUpOhO3bOHt8j95chzgqZ GFPGMqVu2Bhpqd8a/Coa5+/x44ErSTiHPBTQ5ESj+9OJ51ZDqEKNFSYk+1za7sp/6YudrOPus3m ObcFIZO8LENXw0Ufe6TvP+joeq9uQ5JhOgs4gvpBuRXBFIRMN9XZ/kAHCxnSK9QR6LizF8ZNhCN X1Ewj7q4P8wjpxazQe8zn/9KEVaqB2YghsXOxza4ixqrrumT+GqB0f/cqth4RS7/2NaGdY4ZdRq NAnzblXvZBPfiaphTeuscMqvpsHAUliiWtWqjhjbqozqqM8VioBWJ7BYPCYOev0qcjwggPbnXs2 Hv3ULjK/gkzy6wYztHmo0njMPvKid+ITl9KUKbCgaH9dvyIj1LH6kUui/V1T1imtGhEKAGcKOHz g== X-Received: by 2002:a05:6a20:244a:b0:3cd:9f0b:f788 with SMTP id adf61e73a8af0-3da39d12327mr31717504637.12.1788776629645; Mon, 07 Sep 2026 03:23:49 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:49 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][wrynose][PATCH 9/33] python3-zeroconf: patch CVE-2026-47184 Date: Mon, 7 Sep 2026 22:22:53 +1200 Message-ID: <20260907102318.2459883-9-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129821 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-47184 Signed-off-by: Ankur Tyagi --- .../python3-zeroconf/CVE-2026-47184.patch | 558 ++++++++++++++++++ .../python/python3-zeroconf_0.148.0.bb | 1 + 2 files changed, 559 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47184.patch diff --git a/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47184.patch b/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47184.patch new file mode 100644 index 0000000000..73d4c2bd9c --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-zeroconf/CVE-2026-47184.patch @@ -0,0 +1,558 @@ +From 61d9e147da48ffb5f660e639f6d457e5cda008d4 Mon Sep 17 00:00:00 2001 +From: "J. Nick Koston" +Date: Sun, 17 May 2026 21:48:40 -0700 +Subject: [PATCH] fix: bound DNSCache record count to prevent unbounded + LAN-driven growth (#1718) + +(cherry picked from commit 0ad3f37b5b852b8f614d322283d148efb2cef6e4) + +CVE: CVE-2026-47184 +Upstream-Status: Backport [https://github.com/python-zeroconf/python-zeroconf/commit/0ad3f37b5b852b8f614d322283d148efb2cef6e4] + +Signed-off-by: Ankur Tyagi +--- + src/zeroconf/_cache.pxd | 11 +- + src/zeroconf/_cache.py | 79 +++++---- + src/zeroconf/const.py | 6 + + tests/benchmarks/test_cache_bound.py | 68 ++++++++ + tests/test_cache.py | 241 ++++++++++++++++++++++++++- + 5 files changed, 374 insertions(+), 31 deletions(-) + create mode 100644 tests/benchmarks/test_cache_bound.py + +diff --git a/src/zeroconf/_cache.pxd b/src/zeroconf/_cache.pxd +index 05a40c0..023304b 100644 +--- a/src/zeroconf/_cache.pxd ++++ b/src/zeroconf/_cache.pxd +@@ -19,6 +19,7 @@ cdef object _UNIQUE_RECORD_TYPES + cdef unsigned int _TYPE_PTR + cdef cython.uint _ONE_SECOND + cdef unsigned int _MIN_SCHEDULED_RECORD_EXPIRATION ++cdef unsigned int _MAX_CACHE_RECORDS + + + @cython.locals(record_cache=dict) +@@ -31,6 +32,7 @@ cdef class DNSCache: + cdef public cython.dict service_cache + cdef public list _expire_heap + cdef public dict _expirations ++ cdef public unsigned int _total_records + + cpdef bint async_add_records(self, object entries) + +@@ -60,10 +62,17 @@ cdef class DNSCache: + service_store=cython.dict, + service_record=DNSService, + when=object, +- new=bint ++ new=bint, ++ is_new=bint + ) + cdef bint _async_add(self, DNSRecord record) + ++ @cython.locals(record=DNSRecord, when_record=tuple) ++ cdef void _async_evict_oldest(self) ++ ++ @cython.locals(expire_heap_len="unsigned int") ++ cdef void _maybe_rebuild_heap(self) ++ + @cython.locals(service_record=DNSService) + cdef void _async_remove(self, DNSRecord record) + +diff --git a/src/zeroconf/_cache.py b/src/zeroconf/_cache.py +index c7ca847..d323a6a 100644 +--- a/src/zeroconf/_cache.py ++++ b/src/zeroconf/_cache.py +@@ -37,7 +37,7 @@ from ._dns import ( + DNSText, + ) + from ._utils.time import current_time_millis +-from .const import _ONE_SECOND, _TYPE_PTR ++from .const import _MAX_CACHE_RECORDS, _ONE_SECOND, _TYPE_PTR + + _UNIQUE_RECORD_TYPES = (DNSAddress, DNSHinfo, DNSPointer, DNSText, DNSService) + _UniqueRecordsType = Union[DNSAddress, DNSHinfo, DNSPointer, DNSText, DNSService] +@@ -72,6 +72,7 @@ class DNSCache: + self._expire_heap: list[tuple[float, DNSRecord]] = [] + self._expirations: dict[DNSRecord, float] = {} + self.service_cache: _DNSRecordCacheType = {} ++ self._total_records: int = 0 + + # Functions prefixed with async_ are NOT threadsafe and must + # be run in the event loop. +@@ -89,15 +90,34 @@ class DNSCache: + # replaces any existing records that are __eq__ to each other which + # removes the risk that accessing the cache from the wrong + # direction would return the old incorrect entry. +- if (store := self.cache.get(record.key)) is None: ++ store = self.cache.get(record.key) ++ is_new = store is None or record not in store ++ # Bound total cache size; evict closest-to-expiration entry to ++ # make room before inserting a new record. Prevents a LAN-local ++ # flood of unique-name records from growing the cache without ++ # bound (RFC 6762 §10 advisory caching, defense-in-depth). ++ if is_new and self._total_records >= _MAX_CACHE_RECORDS: ++ self._async_evict_oldest() ++ # The victim may have been the last record under ++ # ``record.key``, in which case ``_remove_key`` deleted ++ # the bucket. Re-fetch before creating below. ++ store = self.cache.get(record.key) ++ if store is None: + store = self.cache[record.key] = {} +- new = record not in store and not isinstance(record, DNSNsec) ++ new = is_new and not isinstance(record, DNSNsec) ++ if is_new: ++ self._total_records += 1 + store[record] = record + when = record.created + (record.ttl * 1000) + if self._expirations.get(record) != when: +- # Avoid adding duplicates to the heap + heappush(self._expire_heap, (when, record)) + self._expirations[record] = when ++ # Re-adds of an existing record with a new TTL push a fresh ++ # entry but leave the prior tuple behind as stale, so a peer ++ # that just replays cached records can grow ``_expire_heap`` ++ # without ever tripping the cap. Rebuild when stale entries ++ # dominate. ++ self._maybe_rebuild_heap() + + if isinstance(record, DNSService): + service_record = record +@@ -106,6 +126,28 @@ class DNSCache: + service_store[service_record] = service_record + return new + ++ def _async_evict_oldest(self) -> None: ++ """Drop the closest-to-expiration record to make room for a new one.""" ++ while self._expire_heap: ++ when_record = heappop(self._expire_heap) ++ record = when_record[1] ++ if self._expirations.get(record) != when_record[0]: ++ continue ++ self._async_remove(record) ++ return ++ ++ def _maybe_rebuild_heap(self) -> None: ++ """Rebuild ``_expire_heap`` when stale entries dominate live ones.""" ++ expire_heap_len = len(self._expire_heap) ++ if ( ++ expire_heap_len > _MIN_SCHEDULED_RECORD_EXPIRATION ++ and expire_heap_len > len(self._expirations) * 2 ++ ): ++ self._expire_heap = [ ++ entry for entry in self._expire_heap if self._expirations.get(entry[1]) == entry[0] ++ ] ++ heapify(self._expire_heap) ++ + def async_add_records(self, entries: Iterable[DNSRecord]) -> bool: + """Add multiple records. + +@@ -129,6 +171,7 @@ class DNSCache: + _remove_key(self.service_cache, service_record.server_key, service_record) + _remove_key(self.cache, record.key, record) + self._expirations.pop(record, None) ++ self._total_records -= 1 + + def async_remove_records(self, entries: Iterable[DNSRecord]) -> None: + """Remove multiple records. +@@ -145,43 +188,23 @@ class DNSCache: + + :param now: The current time in milliseconds. + """ +- if not (expire_heap_len := len(self._expire_heap)): ++ if not self._expire_heap: + return [] + + expired: list[DNSRecord] = [] +- # Find any expired records and add them to the to-delete list + while self._expire_heap: + when_record = self._expire_heap[0] + when = when_record[0] + if when > now: + break + heappop(self._expire_heap) +- # Check if the record hasn't been re-added to the heap +- # with a different expiration time as it will be removed +- # later when it reaches the top of the heap and its +- # expiration time is met. ++ # Skip entries left behind by a TTL re-add; the live tuple is ++ # later in the heap and will be removed when it reaches the top. + record = when_record[1] + if self._expirations.get(record) == when: + expired.append(record) + +- # If the expiration heap grows larger than the number expirations +- # times two, we clean it up to avoid keeping expired entries in +- # the heap and consuming memory. We guard this with a minimum +- # threshold to avoid cleaning up the heap too often when there are +- # only a few scheduled expirations. +- if ( +- expire_heap_len > _MIN_SCHEDULED_RECORD_EXPIRATION +- and expire_heap_len > len(self._expirations) * 2 +- ): +- # Remove any expired entries from the expiration heap +- # that do not match the expiration time in the expirations +- # as it means the record has been re-added to the heap +- # with a different expiration time. +- self._expire_heap = [ +- entry for entry in self._expire_heap if self._expirations.get(entry[1]) == entry[0] +- ] +- heapify(self._expire_heap) +- ++ self._maybe_rebuild_heap() + self.async_remove_records(expired) + return expired + +diff --git a/src/zeroconf/const.py b/src/zeroconf/const.py +index 1db39a4..a17e468 100644 +--- a/src/zeroconf/const.py ++++ b/src/zeroconf/const.py +@@ -59,6 +59,12 @@ _DNS_OTHER_TTL = 4500 # 75 minutes for non-host records (PTR, TXT etc) as-per R + # level of rate limit and safe guards so we use 1/4 of the recommended value + _DNS_PTR_MIN_TTL = 1125 + ++# Upper bound on the number of records the DNSCache will hold before it ++# starts evicting the closest-to-expiration entry to make room for new ++# arrivals. Bounds the memory a malicious LAN peer can force the cache ++# to retain by multicasting many unique-name records. ++_MAX_CACHE_RECORDS = 10000 ++ + _DNS_PACKET_HEADER_LEN = 12 + + _MAX_MSG_TYPICAL = 1460 # unused +diff --git a/tests/benchmarks/test_cache_bound.py b/tests/benchmarks/test_cache_bound.py +new file mode 100644 +index 0000000..774129e +--- /dev/null ++++ b/tests/benchmarks/test_cache_bound.py +@@ -0,0 +1,68 @@ ++"""Benchmark for the DNSCache record-count bound + overflow eviction.""" ++ ++from __future__ import annotations ++ ++from collections.abc import Iterator ++from itertools import count ++ ++from pytest_codspeed import BenchmarkFixture ++ ++from zeroconf import DNSAddress, DNSCache, current_time_millis ++from zeroconf.const import _CLASS_IN, _MAX_CACHE_RECORDS, _TYPE_A ++ ++ ++def _make_records(count_: int, now: float, prefix: str = "bench") -> list[DNSAddress]: ++ return [ ++ DNSAddress( ++ f"{prefix}-{i}.local.", ++ _TYPE_A, ++ _CLASS_IN, ++ 120, ++ bytes(((i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF)), ++ created=now + i, ++ ) ++ for i in range(count_) ++ ] ++ ++ ++def _unbounded_records(now: float, prefix: str = "evict") -> Iterator[DNSAddress]: ++ """Unbounded generator of unique-name DNSAddress records.""" ++ for i in count(): ++ yield DNSAddress( ++ f"{prefix}-{i}.local.", ++ _TYPE_A, ++ _CLASS_IN, ++ 120, ++ bytes(((i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF)), ++ created=now + i, ++ ) ++ ++ ++def test_cache_add_below_cap(benchmark: BenchmarkFixture) -> None: ++ """Adding records while the cache is well below the cap (no eviction).""" ++ now = current_time_millis() ++ records = _make_records(1000, now) ++ ++ @benchmark ++ def _add() -> None: ++ cache = DNSCache() ++ cache.async_add_records(records) ++ ++ ++def test_cache_add_at_cap_evicts(benchmark: BenchmarkFixture) -> None: ++ """Steady-state add at the cap: every measured insert forces one eviction. ++ ++ Pre-fills the cache to ``_MAX_CACHE_RECORDS`` outside the timed body so ++ only the eviction-path adds are measured. Each benchmark iteration ++ pulls one fresh unique record from an unbounded generator, keeping the ++ cache permanently at the cap. The generator avoids the iteration-count ++ cap that a pre-built pool would impose for very fast operations. ++ """ ++ now = current_time_millis() ++ cache = DNSCache() ++ cache.async_add_records(_make_records(_MAX_CACHE_RECORDS, now, prefix="fill")) ++ pool = _unbounded_records(now + _MAX_CACHE_RECORDS) ++ ++ @benchmark ++ def _evict_one() -> None: ++ cache.async_add_records([next(pool)]) +diff --git a/tests/test_cache.py b/tests/test_cache.py +index 9d55435..aeb3a2a 100644 +--- a/tests/test_cache.py ++++ b/tests/test_cache.py +@@ -439,7 +439,9 @@ async def test_cache_heap_multi_name_cleanup() -> None: + ) + cache.async_add_records([record]) + +- assert len(cache._expire_heap) == min_records_to_cleanup + 5 ++ # ``_async_add`` rebuilds ``_expire_heap`` proactively when stale entries ++ # dominate (heap > 2x expirations), so the heap is already capped at ++ # ~one entry per unique record long before ``async_expire`` is called. + assert len(cache.async_entries_with_name(name)) == 1 + assert len(cache.async_entries_with_name(name2)) == 5 + +@@ -473,7 +475,8 @@ async def test_cache_heap_pops_order() -> None: + ) + cache.async_add_records([record]) + +- assert len(cache._expire_heap) == min_records_to_cleanup + 5 ++ # ``_async_add`` proactively rebuilds the heap when stale entries dominate, ++ # so the heap holds only one entry per unique record by this point. + assert len(cache.async_entries_with_name(name)) == 1 + assert len(cache.async_entries_with_name(name2)) == 5 + +@@ -482,3 +485,237 @@ async def test_cache_heap_pops_order() -> None: + ts, _ = heappop(cache._expire_heap) + assert ts >= start_ts + start_ts = ts ++ ++ ++def _addr(name: str, idx: int, *, ttl: int = 120, created: float | None = None) -> r.DNSAddress: ++ """Build a DNSAddress with idx-derived payload for the bound/eviction tests.""" ++ return r.DNSAddress( ++ name, ++ const._TYPE_A, ++ const._CLASS_IN, ++ ttl, ++ bytes((idx & 0xFF, (idx >> 8) & 0xFF, 0, 1)), ++ created=r.current_time_millis() if created is None else created, ++ ) ++ ++ ++def test_cache_size_is_bounded() -> None: ++ """A flood of unique-name records is capped at ``_MAX_CACHE_RECORDS``.""" ++ cache = r.DNSCache() ++ now = r.current_time_millis() ++ overflow = 1000 ++ flood_size = const._MAX_CACHE_RECORDS + overflow ++ ++ cache.async_add_records(_addr(f"flood-{i}.local.", i, created=now + i) for i in range(flood_size)) ++ ++ total = sum(len(store) for store in cache.cache.values()) ++ assert total == const._MAX_CACHE_RECORDS ++ assert cache._total_records == const._MAX_CACHE_RECORDS ++ # FIFO-ish: the earliest-created records (closest to expiration) get ++ # evicted first, so the names that remain are from the tail. ++ for i in range(overflow): ++ assert f"flood-{i}.local." not in cache.cache ++ for i in range(flood_size - overflow, flood_size): ++ assert f"flood-{i}.local." in cache.cache ++ ++ ++def test_cache_eviction_empty_heap_returns_without_evicting() -> None: ++ """Eviction tolerates an empty ``_expire_heap`` (invariant-violation safety net).""" ++ cache = r.DNSCache() ++ # By the cache invariant every record in ``_total_records`` has a heap ++ # entry, so eviction should never see an empty heap. Force the broken ++ # state directly to pin the defensive behaviour: ``_async_evict_oldest`` ++ # returns without raising and the subsequent insert still lands. Since ++ # eviction can't free space, the counter is allowed to drift past the ++ # cap by exactly one — pinned so a future change to the recovery ++ # semantics (e.g., refusing the add or clamping) fails this test. ++ cache._total_records = const._MAX_CACHE_RECORDS ++ cache._expire_heap = [] ++ cache.async_add_records([_addr("post-empty.local.", 0)]) ++ assert "post-empty.local." in cache.cache ++ assert cache._total_records == const._MAX_CACHE_RECORDS + 1 ++ ++ ++def test_cache_eviction_skips_stale_heap_entries() -> None: ++ """Eviction skips stale heap entries left by TTL re-adds.""" ++ cache = r.DNSCache() ++ now = r.current_time_millis() ++ cache.async_add_records( ++ _addr(f"stale-{i}.local.", i, created=now + i) for i in range(const._MAX_CACHE_RECORDS) ++ ) ++ assert cache._total_records == const._MAX_CACHE_RECORDS ++ ++ # Re-add the closest-to-expiration record with a longer TTL; the prior ++ # ``(when, record)`` tuple stays as stale, eviction must skip it. ++ victim_name = "stale-0.local." ++ cache.async_add_records([_addr(victim_name, 0, ttl=7200, created=now)]) ++ assert cache._total_records == const._MAX_CACHE_RECORDS ++ ++ cache.async_add_records([_addr("trigger.local.", 0xFFFF, created=now + const._MAX_CACHE_RECORDS)]) ++ assert cache._total_records == const._MAX_CACHE_RECORDS ++ assert victim_name in cache.cache ++ assert "stale-1.local." not in cache.cache ++ ++ ++def test_cache_eviction_victim_shares_key_with_new_record() -> None: ++ """Inserting a record whose key collides with the eviction victim keeps it reachable.""" ++ cache = r.DNSCache() ++ now = r.current_time_millis() ++ cache.async_add_records( ++ _addr(f"filler-{i}.local.", i, created=now + 1000 + i) for i in range(const._MAX_CACHE_RECORDS - 1) ++ ) ++ ++ # Insert at "shared.local." with the earliest expiration so eviction ++ # picks it. ``_remove_key`` then deletes ``cache["shared.local."]``. ++ shared_key = "shared.local." ++ cache.async_add_records([_addr(shared_key, 0x0102, created=now)]) ++ assert cache._total_records == const._MAX_CACHE_RECORDS ++ ++ # Adding a new record under the SAME key: a pre-eviction-captured ++ # ``store`` would write into an orphaned dict; the fix re-resolves. ++ new_shared = _addr(shared_key, 0x0506, created=now + 999) ++ cache.async_add_records([new_shared]) ++ ++ assert shared_key in cache.cache, "new record orphaned: cache bucket missing" ++ assert new_shared in cache.cache[shared_key] ++ assert cache.async_get_unique(new_shared) == new_shared ++ total = sum(len(store) for store in cache.cache.values()) ++ assert total == cache._total_records ++ ++ ++def test_cache_dnsnsec_at_cap_evicts_prior_record() -> None: ++ """A single DNSNsec arriving at the cap evicts one prior record and stays reachable.""" ++ cache = r.DNSCache() ++ now = r.current_time_millis() ++ cache.async_add_records( ++ _addr(f"fill-{i}.local.", i, created=now + i) for i in range(const._MAX_CACHE_RECORDS) ++ ) ++ assert cache._total_records == const._MAX_CACHE_RECORDS ++ ++ nsec = r.DNSNsec( ++ "nsec-arrival.local.", ++ const._TYPE_NSEC, ++ const._CLASS_IN, ++ 120, ++ "nsec-arrival.local.", ++ [const._TYPE_A], ++ ) ++ cache.async_add_records([nsec]) ++ ++ assert cache._total_records == const._MAX_CACHE_RECORDS ++ assert nsec in cache.cache[nsec.key] ++ # The earliest-created fill record is gone (FIFO-ish eviction). ++ assert "fill-0.local." not in cache.cache ++ ++ ++def test_cache_dnsnsec_flood_is_bounded() -> None: ++ """DNSNsec records honour ``_MAX_CACHE_RECORDS`` (no bypass via the ``new`` flag).""" ++ cache = r.DNSCache() ++ overflow = 100 ++ cache.async_add_records( ++ r.DNSNsec( ++ f"nsec-{i}.local.", ++ const._TYPE_NSEC, ++ const._CLASS_IN, ++ 120, ++ f"nsec-{i}.local.", ++ [const._TYPE_A], ++ ) ++ for i in range(const._MAX_CACHE_RECORDS + overflow) ++ ) ++ assert cache._total_records == const._MAX_CACHE_RECORDS ++ total = sum(len(store) for store in cache.cache.values()) ++ assert total == const._MAX_CACHE_RECORDS ++ ++ ++def test_cache_re_add_flood_does_not_grow_heap_unbounded() -> None: ++ """Replaying cached records with shifting TTLs cannot grow ``_expire_heap`` unbounded.""" ++ cache = r.DNSCache() ++ now = r.current_time_millis() ++ # Stay below the cache cap so eviction never fires; the attack here is ++ # heap growth via re-add, not cap saturation. Clear the ++ # ``_MIN_SCHEDULED_RECORD_EXPIRATION`` floor so the rebuild engages. ++ record_count = 200 ++ cache.async_add_records(_addr(f"flood-{i}.local.", i, created=now) for i in range(record_count)) ++ assert cache._total_records == record_count ++ ++ # 10 cycles x ``record_count`` stale pushes each. Without ++ # ``_maybe_rebuild_heap`` firing inside ``_async_add``, the heap would ++ # grow to ~11 x record_count. ++ for cycle in range(10): ++ cache.async_add_records( ++ _addr(f"flood-{i}.local.", i, ttl=7200 + cycle, created=now) for i in range(record_count) ++ ) ++ ++ # Heap is bounded near the rebuild threshold; ``+ record_count`` of slack ++ # to stay resilient to where in a re-add cycle the rebuild last fired. ++ assert len(cache._expire_heap) <= 2 * len(cache._expirations) + record_count ++ assert cache._total_records == record_count ++ ++ ++def test_cache_eviction_decrements_total_records() -> None: ++ """Natural removal (goodbyes, expirations) keeps ``_total_records`` in sync.""" ++ cache = r.DNSCache() ++ now = r.current_time_millis() ++ records = [_addr(f"sync-{i}.local.", i, created=now) for i in range(50)] ++ cache.async_add_records(records) ++ assert cache._total_records == 50 ++ ++ cache.async_remove_records(records[:20]) ++ assert cache._total_records == 30 ++ ++ cache.async_expire(now + (200 * 1000)) ++ assert cache._total_records == 0 ++ assert not cache.cache ++ ++ ++def test_cache_total_records_invariant_under_mixed_ops() -> None: ++ """``_total_records`` stays equal to the sum of bucket sizes across all touched paths.""" ++ cache = r.DNSCache() ++ now = r.current_time_millis() ++ ++ def actual() -> int: ++ return sum(len(store) for store in cache.cache.values()) ++ ++ addrs = [_addr(f"mix-{i}.local.", i, created=now + i) for i in range(20)] ++ cache.async_add_records(addrs) ++ assert cache._total_records == actual() == 20 ++ ++ # Re-add of an identical record: no increment. ++ cache.async_add_records([addrs[0]]) ++ assert cache._total_records == actual() == 20 ++ ++ # DNSService writes service_cache too — counter still matches cache size. ++ svc = r.DNSService("svc.local.", const._TYPE_SRV, const._CLASS_IN, 120, 0, 0, 80, "host.local.") ++ cache.async_add_records([svc]) ++ assert cache._total_records == actual() == 21 ++ cache.async_remove_records([svc]) ++ assert cache._total_records == actual() == 20 ++ ++ # DNSNsec is stored but excluded from the "new" return; counter tracks it anyway. ++ nsec = r.DNSNsec("nsec.local.", const._TYPE_NSEC, const._CLASS_IN, 120, "nsec.local.", [const._TYPE_A]) ++ cache.async_add_records([nsec]) ++ assert cache._total_records == actual() == 21 ++ cache.async_remove_records([nsec]) ++ assert cache._total_records == actual() == 20 ++ ++ # Shared-key insert/remove: emptying the bucket drops the cache key but ++ # counter decrements only by the records that left. ++ shared_a = _addr("shared.local.", 0x0101, created=now) ++ shared_b = _addr("shared.local.", 0x0202, created=now) ++ cache.async_add_records([shared_a, shared_b]) ++ assert cache._total_records == actual() == 22 ++ cache.async_remove_records([shared_a, shared_b]) ++ assert cache._total_records == actual() == 20 ++ assert "shared.local." not in cache.cache ++ ++ cache.async_expire(now + (200 * 1000)) ++ assert cache._total_records == actual() == 0 ++ assert not cache.cache ++ ++ # Full-cap eviction loop: counter never grows past the cap, never drifts. ++ cap_records = [_addr(f"cap-{i}.local.", i, created=now + i) for i in range(const._MAX_CACHE_RECORDS + 50)] ++ for rec in cap_records: ++ cache.async_add_records([rec]) ++ assert cache._total_records == actual() ++ assert cache._total_records == const._MAX_CACHE_RECORDS diff --git a/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb b/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb index aa1bb11065..cc68ffbf96 100644 --- a/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb +++ b/meta-python/recipes-devtools/python/python3-zeroconf_0.148.0.bb @@ -7,6 +7,7 @@ SRC_URI[sha256sum] = "03fcca123df3652e23d945112d683d2f605f313637611b7d4adf31056f SRC_URI += "file://CVE-2026-47180.patch \ file://CVE-2026-47183.patch \ + file://CVE-2026-47184.patch \ " inherit pypi python_poetry_core cython From patchwork Mon Sep 7 10:22:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97477 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 1D1E4C79F9E for ; Mon, 7 Sep 2026 10:23:59 +0000 (UTC) Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31690.1788776633233875255 for ; Mon, 07 Sep 2026 03:23:53 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=LyDJaOcU; spf=pass (domain: gmail.com, ip: 209.85.216.41, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-38511175ad3so2907412a91.2 for ; Mon, 07 Sep 2026 03:23:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776633; x=1789381433; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+1eY65BRFL/typ0boe1+sGWzXboUGH5kFbraUQfqnfM=; b=LyDJaOcUfxHttWNQfAWYzfnNOoeqVW1VG6KxM5r5ankloMLrMDJwtTFrLA+Bxpefly yF+heyEgl+ZT7Ewd6IuhlYIujlWlNFtrIIFdfG3I2IwzOgrIqNTcBV6zAMdX8PRv+bLV OzSzXnVkNcp/efAe2NB21Rc/W+/NDA9z1oLzclltDEYTy5EGJSAZ+2KrxVUfZDLYJ6HN VE9Z6Xf7trNWsuc1sp16AzFVL4ZM0CZbOCQylTqv+cm6Ok4hRIG0zjXzVgB0VUGrTXNj 8jBTOEbNsNiWlYRSF2f0PJPRU+hOADiYdq5xSPAoo9pIh16Og34jgJh4BETNXiRk1qSN deYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776633; x=1789381433; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=+1eY65BRFL/typ0boe1+sGWzXboUGH5kFbraUQfqnfM=; b=qa2Ttc8yNmUQP44Sew+j1axb5lpVP1iBJnPRYyszQZ8vph6tK1WCVzwYc0/XDV4qgq 28VzjgldcVXV1s/OvcI9YG6eTcIiZjksomG441qLX9s5GXK/3faHcDr8bT6EYAcM8A4b gh3AvFgMcPhKiJXg/yX4x7gGTcPLE+kJ9iAJ5NTc9ET5/QBERqHjnAcC7HmSVzwrtm0h EsFv9Xsmkw+SLRMH6qUinzaO9tCbqRBzU/oj9/VCe7tdkFOZKdqKdrUCYgNq32SQ2hRM mUcRT190v/ej93zmrWOFhBaaMb8mTbu7aOg0RFjLRT9fKonLtuW/NmYucYdDlH9z2uQE JCVg== X-Gm-Message-State: AFuF++li3B3nYQyVJ1wd++gCTzfE8RRiO7GwSzj7ES/GbTyCxb15M6OG wJs3uKd04PJt6ODk6pdYX9rrUDa+Rsbb5xtxZi5iuTRPMSARSf6LnXyTrPaTTUao X-Gm-Gg: AYBFou1CBDV3BaZJL2LAzJTQ7Q+YPkYafYLqXRCGZqvtzIOmq/mbpxQ4YhYYJ3lijQo J0y223DW4sLIWGxPqb49F+gO66GlvW7JCwShoixMmwzDaaZ5wVmsMM4VFMGiWt2Lb1EbMNCyJ80 mLm/67U1Vct8Fce2n0dS0OYxQQ3Fl3tRb2RxzDOnxCHlGnNCXngMtkerPOEJ3JCAB1B6W5bCYzq 5rMiUoJrKT5ffDj9WyHCT+dAF92/sK0oDzKZbdI5AXh765R2u7xt4IstMEneU6EbTkzKxR3pwsK SWjcOGaCFrcU6NqzQvenc08xaHMMucDztXjkLFafg7JJ/dbpbCBnwxaxpEve4NXC4nEGbQg5X/p vDDkxq3ECV6fpDq+SIpKnGkLi42yPF7q4eV2MyPuS9LBEkZuW0uroSWRYuyXMu5ZByBqbXpbCOt Igajz6Ra6wu91h7lWq3KTxgOTuaklTVXUmeWXF65POaSdzIeV6cYOwpaIK5FtCV/5C3/nlN4wT X-Received: by 2002:a17:90a:e703:b0:398:e969:87ef with SMTP id 98e67ed59e1d1-39b2629926dmr34456609a91.24.1788776632544; Mon, 07 Sep 2026 03:23:52 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:52 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 10/33] valkey: mark CVE-2026-56684 and CVE-2026-63639 patched Date: Mon, 7 Sep 2026 22:22:54 +1200 Message-ID: <20260907102318.2459883-10-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129822 From: Ankur Tyagi Also mentioned in the release notes[1] Details: https://nvd.nist.gov/vuln/detail/cve-2026-56684 https://nvd.nist.gov/vuln/detail/cve-2026-63639 [1]https://github.com/valkey-io/valkey/releases/tag/9.0.5 Signed-off-by: Ankur Tyagi --- meta-oe/recipes-extended/valkey/valkey_9.0.5.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meta-oe/recipes-extended/valkey/valkey_9.0.5.bb b/meta-oe/recipes-extended/valkey/valkey_9.0.5.bb index d57aa6e1b4..d7ce19ce72 100644 --- a/meta-oe/recipes-extended/valkey/valkey_9.0.5.bb +++ b/meta-oe/recipes-extended/valkey/valkey_9.0.5.bb @@ -74,3 +74,5 @@ INITSCRIPT_PARAMS = "defaults 87" SYSTEMD_SERVICE:${PN} = "valkey.service" CVE_STATUS[CVE-2022-3734] = "not-applicable-platform: CVE only applies for Windows." +CVE_STATUS[CVE-2026-56684] = "fixed-version: fixed in v9.0.5" +CVE_STATUS[CVE-2026-63639] = "fixed-version: fixed in v9.0.5" From patchwork Mon Sep 7 10:22:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97476 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 1826DC79F9F for ; Mon, 7 Sep 2026 10:23:59 +0000 (UTC) Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31911.1788776635861127037 for ; Mon, 07 Sep 2026 03:23:55 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=RBbhwI30; spf=pass (domain: gmail.com, ip: 209.85.216.42, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-38dfe7eb825so2721231a91.0 for ; Mon, 07 Sep 2026 03:23:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776635; x=1789381435; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=RTExCWgctRbw3bixxzGCd196Kf1waqFdVs8GfmPF4uI=; b=RBbhwI30/3IzGuy59eFd4aKs/aVIxE8aedM+TdghB+jI3ymIKHgRBsMlezWANVA4+A Qr5PdtuV+M722dNNAhuFU8yjaAJuequezfZIIoVvU46nWzz4AEvRKeMOENJuaLzZn9U5 Vmw6Q8zLtaPALYgZ7TyeNKHhkIkE3WDqGkmLYlHtTKz5AhrDXgnfq+mb+n1Hj80oYRGv yE8S4X6iIR0XXpuUIMsyXCiBCWsrYG0j7cEG5oQexnuW4KuOieU92pknp6RC4B3c5HBK qqxsDWXe2pA0McEo9uIHpSp1d96ta3XOh1cRTXefQXGOOMXseNFpBxfRaecU32MGKSUa 4JVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776635; x=1789381435; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=RTExCWgctRbw3bixxzGCd196Kf1waqFdVs8GfmPF4uI=; b=C8YSUlChYAwXBngF7q7eRHJZgwvaxDNplisMxlLjFlLFUFpv0rJxo1xx4uMmfKeUHE 5WmPSKIYMBZf/SqJffyb3+AZMPQbjd3+il62I5LY4X/4IbVHqGpGF+LgZQbVNk05PF99 7kM9texfc5XkNHQcjQl13EFdLXAxlhZ1SSqWQxKqy66kYMWDjO3aB9D115wLouRDDNdd NlmG4v0HUVr9o4d0hY6Mhg7EA0ohMjqrgc3vIlIBdVVs+LSaZU+aMDCEw+b6rA9Zd4dp JcXcUdfwcFJRxKZkh96CM5F+nFzuDoO9SmMPGsvs4Apdaa7xsCwN773EBPOB/Y7SUZf4 gIDA== X-Gm-Message-State: AFuF++lfLjxTpvz961xg7ZfJDugTSL5Ei20n9ZyjY4ff4GttcnSBVCMJ goRJAXjJUNYWFL+BbA68RFnTPrvDZ0gU3mTJeW/w4IQBJXqfltp/ASky5B31xQ== X-Gm-Gg: AYBFou3aHlYUW6lWir0ya02lS4J54Wf8tFy+YfoZi3vlFfN6r68Rzm4jETYn6eDaUvj 11foN/w7hJ666/FEvJElBmp4sB7UcM9kP7AGZOL5hbEFU7z1iesFwcT+DSBLqQgl1Ngh9TqyLNI 5B/aLArJJMjiQ8KHLEXIPKuIlAiEIBpoCDhAiJrhgpR+dd8555wSB3HGCA3osQ5DseF66aLdYdv l+ix6+JQFwUDMPq1/IDrTDzbmUEfOeoLg94pJhjo5Tg8zu0vJ59EFMYvhmI0TRDPReJe3Eg1Mj/ kxxrNbM5qah5M4d/HW6zlSx0UCRCQmPGY5sLo+5lytemDUKK4unu1kY9iNkl7ssTVcvsOf7cWtN oU1arpu8Lmj89tHRnR+96aVwyxBSdOcgbOpbie1LaUsgsdjcevifzU4N1m7X2WYFoIVdFZt9FOt gnNPqCr4Vxpu1jSGxDHe7I9xFV560+Y2b3SHa7E6VpVxIqadrxyNY/Tke2DHmCZBwJ8THEAMLd X-Received: by 2002:a17:90b:4cce:b0:38f:240d:b857 with SMTP id 98e67ed59e1d1-39b260dd4e9mr36012821a91.2.1788776635260; Mon, 07 Sep 2026 03:23:55 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:54 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 11/33] libyang: patch CVE-2026-41401 Date: Mon, 7 Sep 2026 22:22:55 +1200 Message-ID: <20260907102318.2459883-11-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129823 From: Ankur Tyagi Backport patch identified by Debian[1] Details: https://nvd.nist.gov/vuln/detail/cve-2026-41401 [1]https://security-tracker.debian.org/tracker/CVE-2026-41401 Signed-off-by: Ankur Tyagi --- .../libyang/libyang/CVE-2026-41401.patch | 43 +++++++++++++++++++ .../libyang/libyang_3.13.6.bb | 1 + 2 files changed, 44 insertions(+) create mode 100644 meta-oe/recipes-extended/libyang/libyang/CVE-2026-41401.patch diff --git a/meta-oe/recipes-extended/libyang/libyang/CVE-2026-41401.patch b/meta-oe/recipes-extended/libyang/libyang/CVE-2026-41401.patch new file mode 100644 index 0000000000..06537acbb8 --- /dev/null +++ b/meta-oe/recipes-extended/libyang/libyang/CVE-2026-41401.patch @@ -0,0 +1,43 @@ +From 34b2a26ee86716e2b593c44e51e38ee15d4e8434 Mon Sep 17 00:00:00 2001 +From: Michal Vasko +Date: Thu, 26 Mar 2026 08:33:44 +0100 +Subject: [PATCH] parser common BUGFIX invalid metadata removal + +(cherry picked from commit 54c3276d871023da266d4ed3ceaee7e8d71d0b04) + +CVE: CVE-2026-41401 +Upstream-Status: Backport [https://github.com/CESNET/libyang/commit/54c3276d871023da266d4ed3ceaee7e8d71d0b04] + +Signed-off-by: Ankur Tyagi +--- + src/parser_common.c | 4 ++-- + tests/fuzz/corpus/lyd_parse_mem_xml/advisory2026_03_26 | 5 +++++ + 2 files changed, 7 insertions(+), 2 deletions(-) + create mode 100644 tests/fuzz/corpus/lyd_parse_mem_xml/advisory2026_03_26 + +diff --git a/src/parser_common.c b/src/parser_common.c +index 0b221af72..fefe723eb 100644 +--- a/src/parser_common.c ++++ b/src/parser_common.c +@@ -413,8 +413,8 @@ lyd_parser_set_data_flags(struct lyd_node *node, struct lyd_meta **meta, struct + next_meta = meta2->next; + + /* delete the metadata */ +- if (meta != &node->meta) { +- *meta = (*meta)->next; ++ if ((meta != &node->meta) && (meta2 == *meta)) { ++ *meta = next_meta; + } + lyd_free_meta_single(meta2); + if (prev_meta) { +diff --git a/tests/fuzz/corpus/lyd_parse_mem_xml/advisory2026_03_26 b/tests/fuzz/corpus/lyd_parse_mem_xml/advisory2026_03_26 +new file mode 100644 +index 000000000..7e3b6c39e +--- /dev/null ++++ b/tests/fuzz/corpus/lyd_parse_mem_xml/advisory2026_03_26 +@@ -0,0 +1,5 @@ ++5 diff --git a/meta-oe/recipes-extended/libyang/libyang_3.13.6.bb b/meta-oe/recipes-extended/libyang/libyang_3.13.6.bb index 822c30ba24..7724b4c218 100644 --- a/meta-oe/recipes-extended/libyang/libyang_3.13.6.bb +++ b/meta-oe/recipes-extended/libyang/libyang_3.13.6.bb @@ -11,6 +11,7 @@ SRCREV = "c2ddd01b9b810a30d6a7d6749a3bc9adeb7b01fb" SRC_URI = "git://github.com/CESNET/libyang.git;branch=master;protocol=https;tag=v${PV} \ file://0001-test_context-skip-test-case-test_searchdirs.patch \ file://run-ptest \ + file://CVE-2026-41401.patch \ " From patchwork Mon Sep 7 10:22:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97478 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 18213C79F99 for ; Mon, 7 Sep 2026 10:23:59 +0000 (UTC) Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31914.1788776638556036055 for ; Mon, 07 Sep 2026 03:23:58 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=I714wWuB; spf=pass (domain: gmail.com, ip: 209.85.216.50, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-3964dfb5b9aso4258003a91.1 for ; Mon, 07 Sep 2026 03:23:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776638; x=1789381438; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=lAdyoMu/H3OjnKdKk4f27G21sov60c3DzNMh4HvghZ4=; b=I714wWuB+m57exQPaICGXSi33hE5pBymQjVOYuEXp9WOjjW5M2M34rqCzeXK11bi3t rvHNDbxdJQ/k0QefI5TZQXr0hf7xjDf6ieJHmpsZuOfWWjC+zAe6WHE2xuKhC2xZt1Uc +PoemAcnEiTeSvDVq8SMIMZ3s+QPjRDUS1D/1EmHEDiW3L+LgdqvxA+0talBaukDKNft 0V13viGZ2asjJijPrNE77KSIaENYilfU1nC2xfhQeXKITdGN+vXoOFLmgzz/iKCOq+wq X89TOQPo3q9VGN2bxjWPsXUAwXddad/fOytIc3wzEDgOCp7AB+5CTlfsKVyve9gffIYz YuBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776638; x=1789381438; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=lAdyoMu/H3OjnKdKk4f27G21sov60c3DzNMh4HvghZ4=; b=LcQRbuUeSqVDDY16G9C0fXUWbmB5bG9mRVnOV9uNIT6Z473bVXsdUvSJhEP3jGFo2l JC8dTcSFPa5Xe/yKBNX2k+vsFjH/LqUb3eF7jzZ/3qc0Y7xr1AsPAch9WqkMh/Lb+LHm s9EuN95Vz8z6cgoCbiqDYzKmbzm3Syh1dzQ0KL6augVsCVjzhr+zG522IzK93WwVpBts 67KXqoUat/wuGaphNbUOGAjqaV1XrNnWhGnl5d5qD+qCb4swVePM+/8O4c60fr9PpSKu QivzWbg2EwCz21QLedl6rSmICzf04Hi7HRD+VY4gDZe59BZAF3KkkO847iZS/vQ6+WrD t2xA== X-Gm-Message-State: AFuF++kv/v7W4RONrS1mJBOvN4sQQ9DJkAcoylsimxiiQLAa6sMKtmvL 41mMfmEuOUIjHeUqQsKXofXr3ZlHFWjQEyMWumalW/3k2uG3QRsQosk/2jv4Sw== X-Gm-Gg: AYBFou0IGljSF1Ct/SVw8bJk8WyuIx3+FQzR4GnBtFSml796u0Dro0X4AJsHH1O6Kr+ t/58B6DipkvzyU+XTgw8hhtGMjom7sL/aeSgyu3TEulidWYhrV/r1ob4vBYmfywnsym7Gjk3ic7 JVxRbrMWDcLiLSiYsEyFH+LkksTRprfAObihrTu+EyJzKMu4a2BWDf22r0ct2fDMPtxcHB4/ZaG K9AO6byJ0nopA/hCGq5q9nf1uHtvs4wORc0w9zE+MRkZUz/HeT3ETXinkyy1iicpbr+vllhCHmE ltMSxazZIbBESHBt8O2zt2/hDa8wEqoeseP9CYFKOwDKz+6iTZDU48/WAH65vZICZi/O40qvRfX IHRT7Uj8AhJsjw18Q4BprZyV1+DFLdPXSchVN5T2K+ME64IjvFW3pYRJSMqOziAlslFjeINGl4s h5xPqGJvUd8JTSMvTzO5qwcgR8/dV5wt5ltkQkJ1BXPsYxxUxdZpW//apTqV9N5p7Itb0e4X6l X-Received: by 2002:a17:90a:51c6:b0:39b:29ca:3d23 with SMTP id 98e67ed59e1d1-39b29ca41d5mr20571438a91.17.1788776637915; Mon, 07 Sep 2026 03:23:57 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:23:57 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 12/33] tinyproxy: patch CVE-2026-31842 Date: Mon, 7 Sep 2026 22:22:56 +1200 Message-ID: <20260907102318.2459883-12-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:23:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129824 From: Ankur Tyagi Backport commit identified by Debian[1] Details: https://nvd.nist.gov/vuln/detail/cve-2026-31842 [1]https://security-tracker.debian.org/tracker/CVE-2026-31842 Signed-off-by: Ankur Tyagi --- .../tinyproxy/tinyproxy/CVE-2026-31842.patch | 33 +++++++++++++++++++ .../tinyproxy/tinyproxy_1.11.3.bb | 1 + 2 files changed, 34 insertions(+) create mode 100644 meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-31842.patch diff --git a/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-31842.patch b/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-31842.patch new file mode 100644 index 0000000000..6b8c02d629 --- /dev/null +++ b/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-31842.patch @@ -0,0 +1,33 @@ +From ed5252d213a68546feaff68e2b40e401d2c2afd4 Mon Sep 17 00:00:00 2001 +From: rofl0r +Date: Fri, 3 Apr 2026 11:21:23 +0200 +Subject: [PATCH] reqs: fix case-sensitive matching of "chunked" (#605) + +the chunked transfer encoding needs to be matched in a case- +insensitive manner. + +closes #604 + +(cherry picked from commit 879bf844abffa0bf5fae6aff0c73179024dd9f98) + +CVE: CVE-2026-31842 +Upstream-Status: Backport [https://github.com/tinyproxy/tinyproxy/commit/879bf844abffa0bf5fae6aff0c73179024dd9f98] + +Signed-off-by: Ankur Tyagi +--- + src/reqs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/reqs.c b/src/reqs.c +index 7aacfd3..8b68538 100644 +--- a/src/reqs.c ++++ b/src/reqs.c +@@ -850,7 +850,7 @@ static int is_chunked_transfer (pseudomap *hashofheaders) + { + char *data; + data = pseudomap_find (hashofheaders, "transfer-encoding"); +- return data ? !strcmp (data, "chunked") : 0; ++ return data ? !strcasecmp (data, "chunked") : 0; + } + + /* diff --git a/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb b/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb index 56e3296066..4ce766b40b 100644 --- a/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb +++ b/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb @@ -9,6 +9,7 @@ SRC_URI = "https://github.com/${BPN}/${BPN}/releases/download/${PV}/${BP}.tar.gz file://run-ptest \ file://CVE-2026-3945-1.patch \ file://CVE-2026-3945-2.patch \ + file://CVE-2026-31842.patch \ " SRC_URI[sha256sum] = "9bcf46db1a2375ff3e3d27a41982f1efec4706cce8899ff9f33323a8218f7592" From patchwork Mon Sep 7 10:22:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97480 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 41401C79F9F for ; Mon, 7 Sep 2026 10:24:09 +0000 (UTC) Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.54]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31917.1788776644679346530 for ; Mon, 07 Sep 2026 03:24:04 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=FgHTrgos; spf=pass (domain: gmail.com, ip: 209.85.216.54, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f54.google.com with SMTP id 98e67ed59e1d1-398b3c37877so3082714a91.0 for ; Mon, 07 Sep 2026 03:24:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776644; x=1789381444; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=aFI8F9qA3BdlK1kvw0Ujwxue9TfOw8o+bdHfSOX9Q5Y=; b=FgHTrgosPLI9XQS1I80Ffu1dlIclnWq3nu078kLckWOVvH1oxg4laRtuq1Ou0VV91y IHHlKg3t5atFI3Nm7GvzG+S+JC4TkR9OQdaXwjpHoiixQsiqJ1ykoNanBrw4BfZxwenr 1790TBJrxfsDktMFf7Nr275c8j63jpiXO7+0d6QhJENHuQA2r6qP6kANSSKPB204IENI RF2aBCrlxR/r1Sh1PMa+X2+6XyEpn8OP/MxdgiMtlJl0qjo3EenJ/lWuiYwGO3A2+iVH Fqm2RWqRGSs1VD+0/T1YdAEJgKz5KkCw9TAD1OMzMdEdzbDX3MwWdW/YF0w7G0BaZMI5 4ZSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776644; x=1789381444; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=aFI8F9qA3BdlK1kvw0Ujwxue9TfOw8o+bdHfSOX9Q5Y=; b=miuqM6qZGcIzYNvQ2sFzJpLQ8/4OcA8mqt+qlZXCUF36qujUNvfug0oFLSjmvlot8i AkGznRxQUv5RHXE5MNj1U/8PFG2qdJ/AydfJcmjCR35o/CIFB8XAhbGo20qU/cezuTRG xzzgg5MzeP66mXBGZoFyuXgP3usSOOGJibe+dvlgGMl0KNxDGf8dlMuO6NCmZIKRj6es ybNzKpGPZbXasUTYYVerVuEY0gK3TuWEg2uj5HdRvaQUx9OzcmcgInUj44/chErT0eGw OW4D7rz6kkd63s1mV2LprCbssA3gIOV0ms5bFECwzxAD5blODhJF8ljA76pw1Rs6YwKR f3Ww== X-Gm-Message-State: AFuF++nP7zGYba9g0b7JMOAHIHVoeuhUmke6866CBmxoU8he8lC4wHg5 7HmK86pd6fk3beqOGcQwirnw0n1sagb3kX1IYdO/7Ogo26FZyJd8Sexbl1rKNTnu X-Gm-Gg: AYBFou1oBZPrz1J1jdDWQgYgmtMbmI9hog1kb5ca3+Ue1ueH94KdUR9U/NAk3roQwvw aAngJLUt4qGawTfeSOVMHKQE0nEOjNOHR1ntuLtFDehgO23588rqlHyvBs7Db7I5fdBTPdv29Y0 e/QM5zBwGkyDURkhYoUlt6mqly6IIy3+cNgBc95GY7gDgJjGir4r9Wxsq7H7mGTflPeo8RayEvN 42JmlKEjTBD26XkepoqMr6EmobiZiLoFIBMybzqNXrYcIZ7nvQbz6bUxU5I/bsoyOiR63LVZhDX l82YE94G3gDjCmJQBNe1qwMwk+MGbH9RQi3ZdtNwl45DcR7poENHzKDZWzRHf4ipC2UM8fQTk1M UIJ2eBBPU+MVMMZxFB2a41zNfFsBsxDOpruP6dvGfKtl0BaePnndw7oVveOU1R4HZn9/GSPqIGZ 4gMBOnm8V4paJNmMg6nJhreha9ckeXhV/mlD+KZco1YSgcOAIXrsfFGCni6QBHswS3T58oKnAQr JviNbvNrXw= X-Received: by 2002:a17:90b:2b4e:b0:38c:a59b:5189 with SMTP id 98e67ed59e1d1-39b261d0d8emr34214430a91.15.1788776640839; Mon, 07 Sep 2026 03:24:00 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.23.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:00 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 13/33] tinyproxy: patch CVE-2026-54387 Date: Mon, 7 Sep 2026 22:22:57 +1200 Message-ID: <20260907102318.2459883-13-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:09 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129825 From: Ankur Tyagi Backport commit identified by Debian[1] Details: https://nvd.nist.gov/vuln/detail/cve-2026-54387 [1]https://security-tracker.debian.org/tracker/CVE-2026-54387 Signed-off-by: Ankur Tyagi --- .../tinyproxy/tinyproxy/CVE-2026-54387.patch | 37 +++++++++++++++++++ .../tinyproxy/tinyproxy_1.11.3.bb | 1 + 2 files changed, 38 insertions(+) create mode 100644 meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-54387.patch diff --git a/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-54387.patch b/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-54387.patch new file mode 100644 index 0000000000..b12572f0ad --- /dev/null +++ b/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-54387.patch @@ -0,0 +1,37 @@ +From a9602e492cedd5d5d18dd3675d9be90e9b0d9e66 Mon Sep 17 00:00:00 2001 +From: rofl0r +Date: Thu, 7 May 2026 16:33:11 +0000 +Subject: [PATCH] reqs: prevent request smuggling via both content-length and + chunked + +addressing point 1 of #609 + +(cherry picked from commit 623bfc093df009296f0b85d40bc677ef9d5c09bb) + +CVE: CVE-2026-54387 +Upstream-Statys: Backport [https://github.com/tinyproxy/tinyproxy/commit/623bfc093df009296f0b85d40bc677ef9d5c09bb] + +Signed-off-by: Ankur Tyagi +--- + src/reqs.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/reqs.c b/src/reqs.c +index 8b68538..e3cfe76 100644 +--- a/src/reqs.c ++++ b/src/reqs.c +@@ -942,8 +942,13 @@ process_client_headers (struct conn_s *connptr, pseudomap *hashofheaders) + connptr->content_length.client = get_content_length (hashofheaders); + + /* Check whether client sends chunked data. */ +- if (connptr->content_length.client == -1 && is_chunked_transfer (hashofheaders)) ++ if (is_chunked_transfer (hashofheaders)) { ++ if (connptr->content_length.client != -1) ++ /* request smuggling, see GH issue #609 */ ++ pseudomap_remove (hashofheaders, "content-length"); ++ + connptr->content_length.client = -2; ++ } + + /* + * See if there is a "Connection" header. If so, we need to do a bit diff --git a/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb b/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb index 4ce766b40b..b8a508d8d4 100644 --- a/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb +++ b/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb @@ -10,6 +10,7 @@ SRC_URI = "https://github.com/${BPN}/${BPN}/releases/download/${PV}/${BP}.tar.gz file://CVE-2026-3945-1.patch \ file://CVE-2026-3945-2.patch \ file://CVE-2026-31842.patch \ + file://CVE-2026-54387.patch \ " SRC_URI[sha256sum] = "9bcf46db1a2375ff3e3d27a41982f1efec4706cce8899ff9f33323a8218f7592" From patchwork Mon Sep 7 10:22:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97481 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 3D206C79F99 for ; Mon, 7 Sep 2026 10:24:09 +0000 (UTC) Received: from mail-pg1-f176.google.com (mail-pg1-f176.google.com [209.85.215.176]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31919.1788776647104488116 for ; Mon, 07 Sep 2026 03:24:07 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=pNb55apF; spf=pass (domain: gmail.com, ip: 209.85.215.176, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f176.google.com with SMTP id 41be03b00d2f7-cbee846deecso4187658a12.1 for ; Mon, 07 Sep 2026 03:24:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776646; x=1789381446; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OoZWQ6ygMclgKLKRfspTV7c1jd5UDBOL1bIpZJulkDc=; b=pNb55apF/I+xeinsW3d7gCOiCGQgMencM7sIRBelH4nNyXlgqTl2Lq57hEmDVgAfYD HWCa1L3tO2bNJnM06wFmr4zxI5vqeJSe3hJuxgJvMPsalsaR9SUKJU330dNUY+x76zoE JJLevMHoaVja727TD6clerbJXVVwjTABltHKIjEl1WTmSn/kfYUDivVaz4+l1X/u//o0 swdGxXRJIRsyfQmW7Z2UXgfZyzlGRoO4kfG+xaz03Z9aEUqft9+MNgOkk8hwfKH9XtLq bPEvIFggVbcnTWGZ59PFT3BUHfRfiTWRxNSnMBlBYEXQNIb88q405revyDzRWZB+vu10 cwGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776646; x=1789381446; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OoZWQ6ygMclgKLKRfspTV7c1jd5UDBOL1bIpZJulkDc=; b=NPDKAtfFXe3gCOEvzFS4OPonZV/ebb/1yUISzytgZsv48MGsvLSw+aAZAdC1wwzXtZ AxYfewLCrF0L1VheYK8eGmUoXnljBlJ5caAjJI1RbpQ5wd3s9+0Xaa1WEH9J25htw/1H tLpTmZrIt2L6D4HaiAi8KH7fzeGqOswHxwU/xxNo2F+flhie7O1BOMVt6eqpLBQaUV9C IQbJJCDogWdTqoK0PbKRUQjTeafAw8GleEoGfjGw4C0645hlqw3RR2m1zXq+K/bQzNIl HOcvMMtX6LsgQ2qowjPZ7ZeJVpN2qMJiA0cmArzu2IoHR+pOArSaa03ABCj7R1RAUr6S cDYg== X-Gm-Message-State: AFuF++nhjVz6Y6uv3rl/q+7w4YqutMT40NEAGXY7dXUJzF95reGdj6zq 5jR80A6mxP349sbY2Xhu8RD1poKkqa1h54a7axP7vOW0iO2G8rzYsg0m++F1Iw== X-Gm-Gg: AYBFou0FNpoZPaSNTak7+gpJhdWRAT1n3lVDF6N1V7jWq2qRa1XCiRVSaA/Srl84dsu Yv6uMTR84tQrM1MDiYLeYSseP3LWx8z3Ra68Z5E0flybvECYMVw/ZyZ4PPrJmRYsA2skLvfFfNX TtiO7nwkSrXfDkysDXdcdl4uDmV0Z441yXvNF3iur1VaSbHvQgN/NbbdVuURFMIAUUFNeQq5dNj izu/OWXE05tYHLK6xqorbc/j+i/bnATWddHWN4c0uUnhh7xt0z7BBgaBv9BHAugjIRzpA4Uq3Xs OmT+OxDs6cK4R16EHKgGEuHTQyqoyBo97wajGBggxQPo/7O7ctbB7Ocfkq2Z6QnAKo3HmJM3GvP moEocMDs3werem0ghGE2RHvwqyCq9fAQ/8LMnHBmBj9iRPGRNnkvN6REg9u32N68sL85PLUh9+p bKWMVZuJKDf6TVw+kQXoF6k1WliTXkTGZdtQFuCEK5dt7t+Dp9S4e5j+MMe7GJ9r3DtebGP+Sz X-Received: by 2002:a17:90b:5344:b0:38e:4f41:83df with SMTP id 98e67ed59e1d1-39b261e0f14mr33729839a91.15.1788776646360; Mon, 07 Sep 2026 03:24:06 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:06 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 14/33] tinyproxy: patch CVE-2026-55202 Date: Mon, 7 Sep 2026 22:22:58 +1200 Message-ID: <20260907102318.2459883-14-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:09 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129826 From: Ankur Tyagi Backport commit identified by Debian[1] Details: https://nvd.nist.gov/vuln/detail/cve-2026-55202 [1]https://security-tracker.debian.org/tracker/CVE-2026-55202 Signed-off-by: Ankur Tyagi --- .../tinyproxy/tinyproxy/CVE-2026-55202.patch | 107 ++++++++++++++++++ .../tinyproxy/tinyproxy_1.11.3.bb | 1 + 2 files changed, 108 insertions(+) create mode 100644 meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-55202.patch diff --git a/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-55202.patch b/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-55202.patch new file mode 100644 index 0000000000..4e446542e2 --- /dev/null +++ b/meta-networking/recipes-support/tinyproxy/tinyproxy/CVE-2026-55202.patch @@ -0,0 +1,107 @@ +From 04b34f814076d790db26925d7df7c30798910c99 Mon Sep 17 00:00:00 2001 +From: rofl0r +Date: Sat, 18 Apr 2026 00:03:15 +0200 +Subject: [PATCH] reqs: improve stathost detection (#606) + +until now, only the basicauth code checked the host header, regular connections didn't. + +- add a new helper function to compare a hostname with optional + trailingcolon/port against the stathost. +- add stathost check via host header before transparent proxy check, + else stathost might be misdetected as a trans host request. +- refactor existing stathost checks to use the new helper + +this should make it easier to access the stathost, for example by +injecting a host header into a curl command line with -H: + + $ curl -H "Host: tinyproxy.stats" 127.0.0.1:8080 + +the stathost can also be specified as an ip address, e.g. +Stathost "127.0.0.10" + a separate Listen statement for that ip. +in such a case e.g. + + $ curl http://127.0.0.10:8080 + +would work too, even if curl didn't add a Host header (but it does anyway). + +(cherry picked from commit 09312a185ae25cc486b4ff5987638a7917a48bce) + +CVE: CVE-2026-55202 +Upstream-Status: Backport [https://github.com/tinyproxy/tinyproxy/commit/09312a185ae25cc486b4ff5987638a7917a48bce] + +Signed-off-by: Ankur Tyagi +--- + src/reqs.c | 37 +++++++++++++++++++++++++------------ + 1 file changed, 25 insertions(+), 12 deletions(-) + +diff --git a/src/reqs.c b/src/reqs.c +index e3cfe76..d5037cf 100644 +--- a/src/reqs.c ++++ b/src/reqs.c +@@ -316,6 +316,17 @@ static int send_connect_method_response (struct conn_s *connptr) + connptr->protocol.minor); + } + ++/* determine whether a hostname with optional trailing colon/port is the ++ stathost */ ++static int is_stathost (const char* host) ++{ ++ const char *p = config->stathost; ++ const char *q = host; ++ if (!p || !q) return 0; ++ while (*p && *(p++) == *(q++)); ++ return *p == 0 && (*q == 0 || *q == ':'); ++} ++ + /* + * Break the request line apart and figure out where to connect and + * build a new request line. Finally connect to the remote server. +@@ -384,6 +395,16 @@ BAD_REQUEST_ERROR: + goto fail; + } + ++ /* ++ * Check to see if they're requesting the stat host ++ */ ++ if (is_stathost (pseudomap_find (hashofheaders, "host"))) { ++got_stathost: ++ log_message (LOG_NOTICE, "Request for the stathost."); ++ connptr->show_stats = TRUE; ++ goto fail; ++ } ++ + #ifdef REVERSE_SUPPORT + if (config->reversepath_list != NULL) { + /* +@@ -497,19 +518,11 @@ BAD_REQUEST_ERROR: + } + } + #endif +- +- +- /* +- * Check to see if they're requesting the stat host +- */ +- if (config->stathost && strcmp (config->stathost, request->host) == 0) { +- log_message (LOG_NOTICE, "Request for the stathost."); +- connptr->show_stats = TRUE; +- goto fail; +- } ++ /* check whether hostname from url is the stathost */ ++ if (is_stathost (request->host)) ++ goto got_stathost; + + safefree (url); +- + return request; + + fail: +@@ -1688,7 +1701,7 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) + + if (!authstring && config->stathost) { + authstring = pseudomap_find (hashofheaders, "host"); +- if (authstring && !strncmp(authstring, config->stathost, strlen(config->stathost))) { ++ if (authstring && is_stathost(authstring)) { + authstring = pseudomap_find (hashofheaders, "authorization"); + stathost_connect = 1; + } else authstring = 0; diff --git a/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb b/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb index b8a508d8d4..f9d425b45a 100644 --- a/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb +++ b/meta-networking/recipes-support/tinyproxy/tinyproxy_1.11.3.bb @@ -11,6 +11,7 @@ SRC_URI = "https://github.com/${BPN}/${BPN}/releases/download/${PV}/${BP}.tar.gz file://CVE-2026-3945-2.patch \ file://CVE-2026-31842.patch \ file://CVE-2026-54387.patch \ + file://CVE-2026-55202.patch \ " SRC_URI[sha256sum] = "9bcf46db1a2375ff3e3d27a41982f1efec4706cce8899ff9f33323a8218f7592" From patchwork Mon Sep 7 10:22:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97483 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 57FF7C79F9F for ; Mon, 7 Sep 2026 10:24:19 +0000 (UTC) Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31697.1788776649787149827 for ; Mon, 07 Sep 2026 03:24:09 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=m6ML2/p7; spf=pass (domain: gmail.com, ip: 209.85.216.41, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-3966791a6eeso4072245a91.3 for ; Mon, 07 Sep 2026 03:24:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776649; x=1789381449; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Bt4eY8fQshVw62pK30BeLKIsvVrzho+5OK3tKZl7jhY=; b=m6ML2/p7w2qvmuxtkkVGhWvtBpuX7J9Wl5op1+O2tGDH7yZqqGPy6H7QLfTKbAmKoe uF1VDXzUc7U+ZjeUytEC5bCIZF7rvzn2frOHd0xFkZd0GG4+XU6/v/vMkQdqI4ICX5ob bWqCNuovo7ED0C8ln/tTpi6q/+Y4wafxjz5u6kI+/L1gMgpEiz9sVGgH0I6p0BDndzvF DoY2HJj9Igcal1UBIkgIv6hE3L7vwYlniSYgJPumuVq4TVZsBFk1Nq3fortg5EGf7Y0e HKDsqYq3Dh3GK9mjWVZ0XsyuDPuF/iKupjSk7ePMITlawWumvXL55PjmtF4nBzamaMu+ xgbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776649; x=1789381449; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Bt4eY8fQshVw62pK30BeLKIsvVrzho+5OK3tKZl7jhY=; b=KFB/4K5xhOBX8APNMPd3MAJ5KScjsVieb9PA/ju7yNVFLxsilb7Pcr9pfv14puoAZ4 BIEfA11YKq6dHGJo4VQJAIO62Imzw3CiEDVcws+0BIiFXKu41vmcS38QqamGF2kOp8s6 jV9ghr575Ck4Jlv6oEmpzAW3d329jFRi1LZvhReR0TMpOrGEzhcyKIkwQoeOaVfFvX/U Ar9VUdy6M6Zn215ocYMbvBqcEPvdx57kbWTp4ghXWKFxcz+Hju9bMLhJ177Yy9xqGjI6 UkGKccREhMvqlFbGF9LAkPlB+4XnBIMfPcEoqOBRnh7VGmkuaBfaCggenLDzKo+Fu6/m EfVw== X-Gm-Message-State: AFuF++m6uGz6r4+H8cifkNVueLGPdqY954KA0xhZfVZ8G5jxloIGa8Gc hEI1wTJEkzmqKBnUXCoVIf5WVmWbW+xrhgXaMRusDM7s9KTCtg/zI/XwLL43w0fu X-Gm-Gg: AYBFou3cGrV1/3jTOJEV7PZTySTTd0j9i3Wrklc2EMjRXe8T9TINIjkNXMiQy3cpSe6 yLxlFr08KuObRALSq2QNsf71kwrmHzGncP4q1gF6VcUdBVQ5YUyvnUo3mDMNpqqG67Ip5Tc9nlD dCokKc+V+T9l6/IuJfY7c/UYA+MZXkxNG7MFf3eqK1J/V6oUq21WKXXXXtWfobBROE+DL4N7P5g PyFBUqIAPDfqsh/NOGJ+fR5+DZGMXWj35S67DQR8VOoEGoFHyTXiwPAIFuPbzmBBMsZQNV+YEE4 5OP4JuEuYi2p4zhIm8gXwwoCKoM48GY/37D/AoXd9eD2e3uPWK3QatdNpFt1CrfoTrNxF7WZyrP tNb8q/Tq9ON4koO9TiChri1FrBR+danlw3Sh1FBIuAsTsAWbFhCJBtzMhDGEzyaYnMRfri3/xSY zdETrH6ZGaiwg1rfIpYgzO4BiBXW4UOZTe0cppVFMF1oGqJwDr043E2mRq2Ls7TNfGXTadse7S X-Received: by 2002:a17:90b:4a49:b0:392:ca3b:370a with SMTP id 98e67ed59e1d1-39b26100cd2mr32219360a91.2.1788776649113; Mon, 07 Sep 2026 03:24:09 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:08 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-webserver][wrynose][PATCH 15/33] nginx: mark CVE-2026-1642 patched Date: Mon, 7 Sep 2026 22:22:59 +1200 Message-ID: <20260907102318.2459883-15-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:19 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129827 From: Ankur Tyagi Debian[1] also identified the commit[2] Details: https://nvd.nist.gov/vuln/detail/cve-2026-1642 [1]https://security-tracker.debian.org/tracker/CVE-2026-1642 [2]https://github.com/nginx/nginx/commit/784fa05025cb8cd0c770f99bc79d2794b9f85b6e Signed-off-by: Ankur Tyagi --- meta-webserver/recipes-httpd/nginx/nginx_1.28.3.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-webserver/recipes-httpd/nginx/nginx_1.28.3.bb b/meta-webserver/recipes-httpd/nginx/nginx_1.28.3.bb index 9872a6de3b..f797f4a289 100644 --- a/meta-webserver/recipes-httpd/nginx/nginx_1.28.3.bb +++ b/meta-webserver/recipes-httpd/nginx/nginx_1.28.3.bb @@ -5,3 +5,4 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=3dc49537b08b14c8b66ad247bb4c4593" SRC_URI[sha256sum] = "2c96a946bfb0882a21744ed429770a2123ae1828c7c48665092993ddee91a918" CVE_STATUS[CVE-2025-53859] = "cpe-stable-backport: Fix is included in 1.28.1" +CVE_STATUS[CVE-2026-1642] = "fixed-version: fixed since v1.28.2" From patchwork Mon Sep 7 10:23:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97484 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 51BC4C79FA7 for ; Mon, 7 Sep 2026 10:24:19 +0000 (UTC) Received: from mail-ot1-f52.google.com (mail-ot1-f52.google.com [209.85.210.52]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31698.1788776653370998169 for ; Mon, 07 Sep 2026 03:24:13 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=p8d7sNhu; spf=pass (domain: gmail.com, ip: 209.85.210.52, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-ot1-f52.google.com with SMTP id 46e09a7af769-7f5934ba2a5so1549490a34.3 for ; Mon, 07 Sep 2026 03:24:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776652; x=1789381452; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=YzUPCJGl8VVhvS2IZ8pL5vSs7MKpPAZ+94Fe2R7yqSs=; b=p8d7sNhu1QN1Xug8ErSh0QjPZG4EpcoczdHHy5opm+7lAt92Up7eoJBrYuOYgktWLy yJTEaEYcSVYAPUCz2o9vYmRtYIXUZECXg92yIX6r1ncBM+OiO2nrJSAW1K0CLqonYrY8 clIVNQpHWHmxg++7KCQ+6xgJ5mBCe1Mwz9nIkaPWm3BFNb0vrnXG5o+cJCm52pbcPrzM i6zz3pNrg+LQCR4X3lA9StwthwY/U++XZoUScwOUzOyERaUJ4sMWQraDi+xtGJaxnpGQ lDz6s7NLIlAiik/DBFlHRyXFiCoC855rh/4T+J5SVbzJhmvGLMZhWoy8ozMq2SW+FRxg NFRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776652; x=1789381452; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=YzUPCJGl8VVhvS2IZ8pL5vSs7MKpPAZ+94Fe2R7yqSs=; b=tBtJBE2RNU2QPWprJDmEG2wsWtEe8zwVc4e+90rswA2T4Hk54rHduBpA1bPqwY4VlJ s3OWzff16ZQ28ifK2rGVBhlJeWCOEltw/zlgtXNJPnnJXkUufipsHj/UQWvhEjck/4w6 XA6QH0FD1uZtltkbwDZKDT7MCq0u6ML8692OUmJ3xmPX9q6fyjnSAkFLG4pCREpMjS+7 8OMXrqunG6hZAqDMI87yxznckRCaQk9+b+8DoaPMLvdKYllcXRyTbXFGQJEhp0iuvk7W OP+wgfBeYS5yij/KkBx+iu5r448AsaZdD28nss95sBnWKo+nXQ+uOfJAfH20Sdon6l0N YnRA== X-Gm-Message-State: AFuF++mQgcdl3Bahtfw5rsIgiBXNy8utq54/pqsHgOHPWcS4NKh+rL2h qALUbzia38d4BwRodKru37fGeOySh6bSAYrtCov+1cO80818pdDuNyWTzRWNqB5Y X-Gm-Gg: AYBFou0cc8Fd2kE2NBMYWs7r7lL6jPIMzstJkmRSnHbhuiZ48abT2UCLDv0dyKX6dw4 Vkhe1NU1MiS5I1FkStXRUJnqtV0Ku4q8kpdwJTCqiLg/9jfLulxVe2JM9Zzy/XAuhLklMoahtN6 HqZ3uTQqpe4U32CS+t66GrfFI6IMGLdasIrKZjgs4plktgbYLug0mypcxWQgmss9ZD3K9Y6UvLe GvefeD9GTn/pQWlu97zVNeHKX6Sqv2YlmhnFPJwotyGNjPsn1RpiB+lUBiJ3BjeoUcOXlHWkBbW netyuSnn5YgcJ64ATdITlsbW2sYOZybFncmr3xrMWeUYSGEYO22py4/xfNEtlIi1P8FdeKffv6E txWmJdXVmWjRHitnLAmI4SvIedOLp7nFozB5QT1hbEZZdyp0MSzfhS41q8UQwHPNCXiudielPqX 8fR470QmC8lS0RoGYBr0z1k8Bue4Sb278qOA4UkiLnN8diRpktAnay94eUfzwca1mMLu0eiUqX X-Received: by 2002:a05:6820:184a:b0:6b7:8396:f3d7 with SMTP id 006d021491bc7-6b78396f903mr8970748eaf.57.1788776652109; Mon, 07 Sep 2026 03:24:12 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:11 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 16/33] open62541: patch CVE-2026-11946 Date: Mon, 7 Sep 2026 22:23:00 +1200 Message-ID: <20260907102318.2459883-16-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:19 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129828 From: Ankur Tyagi Backport commit identified by Debian[1] Details: https://nvd.nist.gov/vuln/detail/cve-2026-11946 [1]https://security-tracker.debian.org/tracker/CVE-2026-11946 Signed-off-by: Ankur Tyagi --- .../opcua/open62541/CVE-2026-11946.patch | 48 +++++++++++++++++++ .../opcua/open62541_1.4.16.bb | 1 + 2 files changed, 49 insertions(+) create mode 100644 meta-networking/recipes-protocols/opcua/open62541/CVE-2026-11946.patch diff --git a/meta-networking/recipes-protocols/opcua/open62541/CVE-2026-11946.patch b/meta-networking/recipes-protocols/opcua/open62541/CVE-2026-11946.patch new file mode 100644 index 0000000000..36c9c83af1 --- /dev/null +++ b/meta-networking/recipes-protocols/opcua/open62541/CVE-2026-11946.patch @@ -0,0 +1,48 @@ +From 47df558c02eef86bec125a54284b78563d1928b8 Mon Sep 17 00:00:00 2001 +From: Niels Beier +Date: Thu, 7 May 2026 15:25:30 +0200 +Subject: [PATCH] fix(server): Enforce default message and chunk size limits to + prevent DoS + +When tcpMaxMsgSize or tcpMaxChunks are configured as 0, the server treats the +limit as truly unbounded. A remote attacker can exploit this by sending +arbitrarily large messages or an unbounded number of chunks, exhausting server +memory and causing a denial of service. + +Set safe defaults (512 MB per message, 16384 chunks) whenever the configured +value is zero, mirroring the existing behaviour for recv/sendBufferSize. + +This commit mitigates a vulnerability reported by Lorenzo Cannella. + +Internal Vulnerability Advisory: open62541-SA-2026-0002 + +(cherry picked from commit c9563e8ea4a8db2f64059c8ff7efe0b49a35bea3) + +CVE: CVE-2026-11946 +Upstream-Status: Backport [https://github.com/open62541/open62541/commit/c9563e8ea4a8db2f64059c8ff7efe0b49a35bea3] + +Signed-off-by: Ankur Tyagi +--- + src/server/ua_server_binary.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/server/ua_server_binary.c b/src/server/ua_server_binary.c +index b2de3b271..13859ce56 100644 +--- a/src/server/ua_server_binary.c ++++ b/src/server/ua_server_binary.c +@@ -1114,6 +1114,15 @@ createServerSecureChannel(UA_BinaryProtocolManager *bpm, UA_ConnectionManager *c + if(connConfig.sendBufferSize == 0) + connConfig.sendBufferSize = 1 << 16; /* 64kB */ + ++ if(connConfig.localMaxMessageSize == 0) ++ connConfig.localMaxMessageSize = 1 << 29; /* 512 MB */ ++ if(connConfig.remoteMaxMessageSize == 0) ++ connConfig.remoteMaxMessageSize = 1 << 29; /* 512 MB */ ++ if(connConfig.localMaxChunkCount == 0) ++ connConfig.localMaxChunkCount = 1 << 14; /* 16384 */ ++ if(connConfig.remoteMaxChunkCount == 0) ++ connConfig.remoteMaxChunkCount = 1 << 14; /* 16384 */ ++ + /* Set up the new SecureChannel */ + UA_SecureChannel_init(&entry->channel); + entry->channel.config = connConfig; diff --git a/meta-networking/recipes-protocols/opcua/open62541_1.4.16.bb b/meta-networking/recipes-protocols/opcua/open62541_1.4.16.bb index 32f7148f4b..b9edc5fe30 100644 --- a/meta-networking/recipes-protocols/opcua/open62541_1.4.16.bb +++ b/meta-networking/recipes-protocols/opcua/open62541_1.4.16.bb @@ -18,6 +18,7 @@ SRC_URI = " \ git://github.com/Pro/mdnsd.git;name=mdnsd;protocol=https;branch=master;destsuffix=${BB_GIT_DEFAULT_DESTSUFFIX}/deps/mdnsd \ git://github.com/OPCFoundation/UA-Nodeset;name=ua-nodeset;protocol=https;branch=latest;destsuffix=${BB_GIT_DEFAULT_DESTSUFFIX}/deps/ua-nodeset \ git://github.com/LiamBindle/MQTT-C.git;name=mqtt-c;protocol=https;branch=master;destsuffix=${BB_GIT_DEFAULT_DESTSUFFIX}/deps/mqtt-c \ + file://CVE-2026-11946.patch \ " From patchwork Mon Sep 7 10:23:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97482 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 3F8FDC79F9E for ; Mon, 7 Sep 2026 10:24:19 +0000 (UTC) Received: from mail-oo1-f53.google.com (mail-oo1-f53.google.com [209.85.161.53]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31922.1788776655748392840 for ; Mon, 07 Sep 2026 03:24:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=AVoCAOpq; spf=pass (domain: gmail.com, ip: 209.85.161.53, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-oo1-f53.google.com with SMTP id 006d021491bc7-6b8ef7de4bdso645341eaf.1 for ; Mon, 07 Sep 2026 03:24:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776655; x=1789381455; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=QvZ3KPmnIjghgdLR/tfGlDwOykvlEnyivhXa/nkEc5M=; b=AVoCAOpqCe3r2iEtNhOy6tWqnOZbGl+FbM5o1YzS3N2HVcF3+g+I72ESKe43auNWaM gCYzgJcNtTRocsOzGb/zJya7QR0TP+yYU2sOJWiG01grubuj/Y/MKw/cRexVOP53PM+l GcqFowcINPfooSt0qDjhajtOEmqVAJC/EZPUR0tOAtjkIXwqVvndyOx01zv2R965307O dqq9vyPmDCNCFMB+DOmZgjj7y6Z4wqd/wNhIqUxk3XulEeWhR32PpzlLD0Fw5w8jRojn tFKPWpQBawYdm0rlbUxUIAY84H4EVg5cgRT3xrzHD9wOS9Txm9iZdZLpNuczIdPo7iZ9 84og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776655; x=1789381455; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=QvZ3KPmnIjghgdLR/tfGlDwOykvlEnyivhXa/nkEc5M=; b=VqA/NOzHWh0YaKDTl/2PVqB8tp3eDiNwcc9VZIYNVdtzEcuDWjdjgWA76nhJnPnLRi +8wfgSUdaY2DlFx6VyjP6ziVrmTN0KY657m1FN3GPJ8OG4dSn4qlbZqNq3U8pV5AJG9r 11CUN6HTG6elTNliP/Lu9XWviObl02vGmV4GqmaVw9/qwe/uWQ7szMXFWkyghchR8mOE lIBh43GF9jyiaaepmZBlqxdaOpo11fwNT8yKO+HUIcVCYlfe7dbI3FRuWpPQxglniV59 Bh169TiB+NqDNv2XxTXcr/VrBQn7laXdV7ofTscHZZNcDI6mzn4gCby9LuDZdy52/WRt rgPw== X-Gm-Message-State: AFuF++n+tyF/8+HMLzcRZIHC98bN/RNFnJELdoCFyAvN7tbnnNwVkLMW PDB5yl9n9YOq25eSWzmQ6AtHxl4siHYlmLCA+PIRWqR8cEirRNN6+4AHfT1j7lBS X-Gm-Gg: AYBFou1ZMoKPNWzHBUysLFrUDs0KMlgnr2WaJwUKB9FxvpT6aRm122IbX/LwEy3mIkr KWngr3XY4dFedtXpSJgvOFMnlaU/yCd21uxsLuQTKS34ObMDPTnUSteq9CBxbnyOHhHjcjfTRoy KsIBxGx8TG8CHv6OHt0MzjhGBt5lbzTVJb1NZTJUVEhHTzx4e9bDW+EK8i8Gy0FQmo5O4DQY3QZ NWsWsSWKxpYSg89nWWUZCSFI9tTnKOzUWdl57K3JsvsqBHw9+wCVlhL3A++hvbjFpuDNTfl9i2P oNK+oAb9tyP7TMaXHulk2Ayv0di4zyiAqLKn6B+ChEpSi++Gy3AQGDX1LgAGJbXzF+YepXGXSVi esXdEhgXAUbhdrB15m/qTeJm2+nx/bbEKkG3j7f8+yrXTJNrL6ieB4jgeJSuoRoYrvoNXp9bCGm 6TpWrFl8YiSUJrBAWJv0ao/Gl5DOGypsX2xFMCCjoxAwOv3YiFPHrXfTeMx5yPKGpFDPmd9r0A X-Received: by 2002:a05:6820:f02c:b0:6b7:8396:f3c4 with SMTP id 006d021491bc7-6b78396f8b9mr12562022eaf.38.1788776654824; Mon, 07 Sep 2026 03:24:14 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:14 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 17/33] smarty: mark CVEs patched Date: Mon, 7 Sep 2026 22:23:01 +1200 Message-ID: <20260907102318.2459883-17-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:19 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129829 From: Ankur Tyagi CVE-2024-35226[1], CVE-2026-62992[2], CVE-2026-62996[3] are patched in current version. Details: https://nvd.nist.gov/vuln/detail/cve-2024-35226 https://nvd.nist.gov/vuln/detail/cve-2026-62992 https://nvd.nist.gov/vuln/detail/cve-2026-62996 [1]https://github.com/smarty-php/smarty/commit/0be92bc8a6fb83e6e0d883946f7e7c09ba4e857a [2]https://github.com/smarty-php/smarty/commit/99c048ce7a590c519b79fbd38ad0143a08183a1f [3]https://github.com/smarty-php/smarty/commit/3c9f77a2e06ce319ae0092496af32cc8f3adc52e Signed-off-by: Ankur Tyagi --- meta-oe/recipes-support/smarty/smarty_5.8.4.bb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/meta-oe/recipes-support/smarty/smarty_5.8.4.bb b/meta-oe/recipes-support/smarty/smarty_5.8.4.bb index dcb7c85a80..cf6c42345c 100644 --- a/meta-oe/recipes-support/smarty/smarty_5.8.4.bb +++ b/meta-oe/recipes-support/smarty/smarty_5.8.4.bb @@ -35,3 +35,7 @@ FILES:${PN} += "${datadir}/php/smarty3/" RDEPENDS:${PN} = "php" CVE_PRODUCT = "smarty:smarty smarty-php:smarty" + +CVE_STATUS[CVE-2024-35226] = "fixed-version: fixed since v5.2.0" +CVE_STATUS[CVE-2026-62992] = "fixed-version: fixed since v5.8.2" +CVE_STATUS[CVE-2024-62996] = "fixed-version: fixed in v5.8.4" From patchwork Mon Sep 7 10:23:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97485 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 4BD50C79F99 for ; Mon, 7 Sep 2026 10:24:19 +0000 (UTC) Received: from mail-pg1-f174.google.com (mail-pg1-f174.google.com [209.85.215.174]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31700.1788776658299365231 for ; Mon, 07 Sep 2026 03:24:18 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=apu3d/xi; spf=pass (domain: gmail.com, ip: 209.85.215.174, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f174.google.com with SMTP id 41be03b00d2f7-cc2276e6daeso2329449a12.0 for ; Mon, 07 Sep 2026 03:24:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776658; x=1789381458; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OVnFNtCOS9B40OlgnM4yEkvNJOe61AEqjSRmrLNtUME=; b=apu3d/xiFxeAtVBGG/JoelDih16rvEAqFJhXs0UcK8i9pINU6JE9D9wGD6w4ddGM5m u+5wCTwxbuQ+7DBP7Ywcq0T96H+hBDLcvMu1iTTk8H+vvxm9H4cspzmDNDocR8eGt7vJ hd/pKLk9JhzIYVqKf9PZs+/UzWFKMLA6EeS46sBQtcgSJ4u6yICeSQdhw8fXvZV6TV4O cH55jT/uL0s5ybssOc1ob31mqCfj1kOJ9CJkydlhXe3rRetTS5j/NfLxaG3ABrlBUy5g By53wPS8d1/PUHu8L2MgrfQiOSO0eDweYKwgBR/UdAd10oivn9/NirhIBCgceaei7ziB FTwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776658; x=1789381458; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OVnFNtCOS9B40OlgnM4yEkvNJOe61AEqjSRmrLNtUME=; b=SAzi+PDTW+6dl7EaPNJAcz70vg4ZSSW9yLJ4Ecz8Lu86WbGshEDCPUnWabscuJNIXt 3m9i9lXzl+OsAuCPlPA8KsVD+1zIZUkd4kDK037UVhksyiVSDWcFNc32KW4AJ7hvZ5KZ zk4qziJxQlGGVlrk8+j1rPDt3jLk+8ctF7t6rE7EyPvlNKzh/BDBEFdiNMjhcOzQXZ+e TJOGH+94rSjnkkRDPBxhSB6k+KezxYrEgH1cvtnIO+m6F7fp53zS/f5xLi3ens+BNVuz aHvenZzs5yfFq+T/LllNUF6qxjcKXI0iA1ZsafWcB+HYaNUJOMaO7cxj6oTY61JQyh4F lmWg== X-Gm-Message-State: AFuF++linxxU2NvCEHQfAZXhebxMmlvtTCRcBRImxGwPtM4+JRhYuZ+t Ru7JHoZr2P24epH4WFJgIpu3Jgd+7hXduTIX54VuNwVPQqncV7WZYGtGwD8pHekk X-Gm-Gg: AYBFou38DgQYtVL0YIlFybZRvMridnL7lOSsXZ5bpxkqmhyCfnSFxgiKnrNzskT4End bFPuBMmCYbZOvKuOSJJEDAIsMoAjUtwRKtMT9E3F5wG6GWfMhg+6ydxL7MIEQQN+Thxyg9kxYRc TwNSV3DzSZ/z2N44sA4wCYT5mRTM6ELo5PKKIOqiruwNlcgMiyo7GCad7/oMxYFoPoqzgxHLTEs OPzT0Y8NW6YjQz1uNcGcS8DZi0I+vAJM6TFmcO5N+UY6uIFIAgxiTA/q+m2gezaJRHGPZeIvf03 4Un5mJoEuRp7KIZ3RnCPltkE8oZWP3WIb1ycpLtxnHHhaJCtyXyDGD4sju9ouYzIp378Qu97wxC cj3/POcYZVLuqCGC1btxMV6FsabDi/dUec8uiN7JqDlHYVxWMegX9XvBfxlmEnq+xCXJKvtZn3r kUH/gqODGTlSMrT5+RFLHw+yYbCqyuBUJ0TuyLhRQJkhOtnofFV7+CYjhnxKwtfxSbKgDFP61Y X-Received: by 2002:a05:6a20:c91c:b0:3d0:8cbb:8c2d with SMTP id adf61e73a8af0-3da39d18686mr36498510637.4.1788776657643; Mon, 07 Sep 2026 03:24:17 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:17 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 18/33] tesseract: patch CVE-2026-73066 Date: Mon, 7 Sep 2026 22:23:02 +1200 Message-ID: <20260907102318.2459883-18-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:19 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129830 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-73066 Signed-off-by: Ankur Tyagi --- .../tesseract/tesseract/CVE-2026-73066.patch | 152 ++++++++++++++++++ .../tesseract/tesseract_5.5.2.bb | 4 +- 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73066.patch diff --git a/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73066.patch b/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73066.patch new file mode 100644 index 0000000000..fc762ba8ca --- /dev/null +++ b/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73066.patch @@ -0,0 +1,152 @@ +From f66bfcc45d1acd3e3c98f81e1edc8ddf49786555 Mon Sep 17 00:00:00 2001 +From: Stefan Weil +Date: Thu, 23 Jul 2026 18:05:39 +0200 +Subject: [PATCH] Fix integer overflow in LSTM Convolve and Reconfig + deserialization (#4588) + +Add range and overflow validation in Convolve::DeSerialize and +Reconfig::DeSerialize to prevent a crafted .traineddata file from +triggering a heap out-of-bounds write via unchecked signed integer +multiplication when computing the output-channel count. + +Validate ni/no/num_weights in Network::CreateFromFile. + +Add defense-in-depth bounds assertions in NetworkIO::Randomize and +NetworkIO::CopyTimeStepGeneral. + +Reported-by: Eunho Kim +Signed-off-by: Stefan Weil +Assisted-by: OpenCode / big-pickle (opencode) +Tested-by: Eunho Kim +(cherry picked from commit 2f4d2f4bf45c363785d7bf1da29b6628f8939a72) + +CVE: CVE-2026-73066 +Upstream-Status: Backport [https://github.com/tesseract-ocr/tesseract/commit/2f4d2f4bf45c363785d7bf1da29b6628f8939a72] + +Signed-off-by: Ankur Tyagi +--- + src/lstm/convolve.cpp | 24 +++++++++++++++++++++++- + src/lstm/network.cpp | 6 ++++++ + src/lstm/networkio.cpp | 2 ++ + src/lstm/reconfig.cpp | 20 +++++++++++++++++++- + 4 files changed, 50 insertions(+), 2 deletions(-) + +diff --git a/src/lstm/convolve.cpp b/src/lstm/convolve.cpp +index 6cfaa06e..d20a991c 100644 +--- a/src/lstm/convolve.cpp ++++ b/src/lstm/convolve.cpp +@@ -23,8 +23,11 @@ + + #include "convolve.h" + ++#include ++ + #include "networkscratch.h" + #include "serialis.h" ++#include "tprintf.h" + + namespace tesseract { + +@@ -46,7 +49,26 @@ bool Convolve::DeSerialize(TFile *fp) { + if (!fp->DeSerialize(&half_y_)) { + return false; + } +- no_ = ni_ * (2 * half_x_ + 1) * (2 * half_y_ + 1); ++ if (half_x_ < 0 || half_y_ < 0 || ni_ <= 0) { ++ tprintf("Error: invalid Convolve parameters: ni=%d half_x=%d half_y=%d\n", ni_, half_x_, ++ half_y_); ++ return false; ++ } ++ int64_t kx = 2LL * half_x_ + 1; ++ int64_t ky = 2LL * half_y_ + 1; ++ // Stepwise overflow check: ni_ * kx * ky must fit in int. ++ if (kx > INT_MAX / ky) { ++ tprintf("Error: Convolve output-channel count overflows: ni=%d half_x=%d half_y=%d\n", ni_, ++ half_x_, half_y_); ++ return false; ++ } ++ int64_t kxky = kx * ky; ++ if (static_cast(ni_) > INT_MAX / kxky) { ++ tprintf("Error: Convolve output-channel count overflows: ni=%d half_x=%d half_y=%d\n", ni_, ++ half_x_, half_y_); ++ return false; ++ } ++ no_ = static_cast(static_cast(ni_) * kxky); + return true; + } + +diff --git a/src/lstm/network.cpp b/src/lstm/network.cpp +index cfddbfd4..8230992a 100644 +--- a/src/lstm/network.cpp ++++ b/src/lstm/network.cpp +@@ -247,6 +247,12 @@ Network *Network::CreateFromFile(TFile *fp) { + return nullptr; + } + ++ if (ni < 0 || no < 0 || num_weights < 0) { ++ tprintf("Error: invalid network layer parameters: type=%d ni=%d no=%d num_weights=%d\n", type, ++ ni, no, num_weights); ++ return nullptr; ++ } ++ + switch (type) { + case NT_CONVOLVE: + network = new Convolve(name, ni, 0, 0); +diff --git a/src/lstm/networkio.cpp b/src/lstm/networkio.cpp +index 3cb068c6..8636075b 100644 +--- a/src/lstm/networkio.cpp ++++ b/src/lstm/networkio.cpp +@@ -405,6 +405,7 @@ void NetworkIO::CopyTimeStepFrom(int dest_t, const NetworkIO &src, int src_t) { + void NetworkIO::CopyTimeStepGeneral(int dest_t, int dest_offset, int num_features, + const NetworkIO &src, int src_t, int src_offset) { + ASSERT_HOST(int_mode_ == src.int_mode_); ++ ASSERT_HOST(dest_offset + num_features <= NumFeatures()); + if (int_mode_) { + memcpy(i_[dest_t] + dest_offset, src.i_[src_t] + src_offset, num_features * sizeof(i_[0][0])); + } else { +@@ -414,6 +415,7 @@ void NetworkIO::CopyTimeStepGeneral(int dest_t, int dest_offset, int num_feature + + // Sets the given range to random values. + void NetworkIO::Randomize(int t, int offset, int num_features, TRand *randomizer) { ++ ASSERT_HOST(offset + num_features <= NumFeatures()); + if (int_mode_) { + int8_t *line = i_[t] + offset; + for (int i = 0; i < num_features; ++i) { +diff --git a/src/lstm/reconfig.cpp b/src/lstm/reconfig.cpp +index 2f49d63e..a4e99497 100644 +--- a/src/lstm/reconfig.cpp ++++ b/src/lstm/reconfig.cpp +@@ -18,6 +18,10 @@ + + #include "reconfig.h" + ++#include ++ ++#include "tprintf.h" ++ + namespace tesseract { + + Reconfig::Reconfig(const std::string &name, int ni, int x_scale, int y_scale) +@@ -60,7 +64,21 @@ bool Reconfig::DeSerialize(TFile *fp) { + if (!fp->DeSerialize(&y_scale_)) { + return false; + } +- no_ = ni_ * x_scale_ * y_scale_; ++ if (x_scale_ <= 0 || y_scale_ <= 0 || ni_ <= 0) { ++ tprintf("Error: invalid Reconfig parameters: ni=%d x_scale=%d y_scale=%d\n", ni_, x_scale_, ++ y_scale_); ++ return false; ++ } ++ int64_t xs = x_scale_; ++ int64_t ys = y_scale_; ++ // Stepwise overflow check: ni_ * x_scale_ * y_scale_ must fit in int. ++ int64_t xsys = xs * ys; ++ if (static_cast(ni_) > INT_MAX / xsys) { ++ tprintf("Error: Reconfig output-channel count overflows: ni=%d x_scale=%d y_scale=%d\n", ni_, ++ x_scale_, y_scale_); ++ return false; ++ } ++ no_ = static_cast(static_cast(ni_) * xsys); + return true; + } + diff --git a/meta-oe/recipes-graphics/tesseract/tesseract_5.5.2.bb b/meta-oe/recipes-graphics/tesseract/tesseract_5.5.2.bb index 46b789cbc4..1b5a5fe2df 100644 --- a/meta-oe/recipes-graphics/tesseract/tesseract_5.5.2.bb +++ b/meta-oe/recipes-graphics/tesseract/tesseract_5.5.2.bb @@ -6,7 +6,9 @@ LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" SRCREV = "6e1d56a847e697de07b38619356550e5cf4e8633" -SRC_URI = "git://github.com/${BPN}-ocr/${BPN}.git;branch=main;protocol=https;tag=${PV}" +SRC_URI = "git://github.com/${BPN}-ocr/${BPN}.git;branch=main;protocol=https;tag=${PV} \ + file://CVE-2026-73066.patch \ +" DEPENDS = "leptonica" From patchwork Mon Sep 7 10:23:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97488 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 7127FC79FA7 for ; Mon, 7 Sep 2026 10:24:29 +0000 (UTC) Received: from mail-oo1-f52.google.com (mail-oo1-f52.google.com [209.85.161.52]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31924.1788776661668999151 for ; Mon, 07 Sep 2026 03:24:21 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=jmLYtWdV; spf=pass (domain: gmail.com, ip: 209.85.161.52, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-oo1-f52.google.com with SMTP id 006d021491bc7-6b145a9623fso1558911eaf.3 for ; Mon, 07 Sep 2026 03:24:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776661; x=1789381461; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=8U4dnXA0L2t0AJS602QpK+TT+qumjXIhGnhFU3JtyoY=; b=jmLYtWdVjU7h4QRjibtxfGRIvKCEwpJpdlTYlJ1RU+Z7QWnxmIRhTZpmx9NqoLIoot d6qmem64Mdh89NdlSzwNeAvYK404A01Q51NqKl180qKN+0mk3weX88HTnerKF0ZNEkL7 45U5b/29h4kbDcz6B9082nm16NOtOci0xn9J32D/OXnfZfv5rLXae7FC7MHDvkj3igAr 9ZAJpCiDHXvsdqHUjhAVMSoimlYPh8qrDKrEqDu7y5F1FPQ3Bq5t5THf9NDjw81C3u+S LhUZkJOykyfSkkFMjK3X68TKeXfRbM/XWxMeYOPJTch+GRh2JVCwtTBpu8NdW7jmfqYq rbFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776661; x=1789381461; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=8U4dnXA0L2t0AJS602QpK+TT+qumjXIhGnhFU3JtyoY=; b=MBmVKig+tD23E+CCdmzaOHPrJCqn25egW5QpGLzR2DfZFsgbJQXiVVOykDX5wO8nTk VQki/8ZTE+mYu8piRCVDGTH0KAw97CPII4nYOMAbaUpvYdAiqPHuzvh1G0FZXRzD6dEG guvPhmjUPqRQUNRQFcqWQ/IH4Hob44zsZLkYsE26ETqmLgI/8OJNG9mp7H0eBUJ/srAr lf3xA5kauEUnAntfq8M2/YMeNvmgE9X+lY3ps+mh/8BiHIM5u/vvnZLR8CnCHp470Reg Q7hwkrLKS2PvqvcczPOrmF5CXZ3TysEAxVejEIXSw4yB4CmG68JXzhcUu+0SMpn8mtnU y7Tw== X-Gm-Message-State: AFuF++lCdjVHR+sTebLeK1+WcLxRSz4bBeG/zxFpSwvWS0q3/lFGE1Uv lP68nP9xzjnOwEEXLjRHSw7HOrtugKpBGFS9XnAWfMzJtqE/hWZ4KWkLAH3OaHKu X-Gm-Gg: AYBFou3G0r5EoeNWmJE9R85eHwCzq65Is8nxISguNOu1UaGVq+OFJM3EFK8DGEPK0oE 0fLPJq77V9pcAab6LoyxNOS0pIkVFcw93HtC+yxxEsIYm3V3ezYyabg+4syEjqDoFvLntmOHF3c mD+5dbWGXCvT3Th6Fwz0GjV7GZ24SXZnWKLtYB9QZctmdLh5QlOFnoBdcKauQQtfsyiS+QCtxGe Dms+PdvPdiUrE+UcG+rvfALWvQcIdikTzacq+Hm5jwJY9NmkX9KoFh1j03dPGjn49JXwgX+WctU x+MvTJpEaYvKewEI2TMOvaok2Zmx0ZehZ7O/4NZt0E4/3A+CV2zg81V+JduUjcVlNpRAL3pN44H 7j1mln/kCEb25ptc/tIbEkfeUd0HTBwOh2Zu2Xolih0UqclKm0UGdXE4QrwkvWIMxJfwebmX0pO JTE06r3VgyXVXzTKLK4MAdNX3Z5q+naXOikyUldyoW0dNClWFBTIkkMSMJsKCVF3xHv5/BmzE+H Fh/AGaZl1g= X-Received: by 2002:a05:6820:2906:b0:6a3:8738:4106 with SMTP id 006d021491bc7-6b6fdbbfe7fmr13023943eaf.26.1788776660613; Mon, 07 Sep 2026 03:24:20 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:20 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-oe][wrynose][PATCH 19/33] tesseract: patch CVE-2026-73067 Date: Mon, 7 Sep 2026 22:23:03 +1200 Message-ID: <20260907102318.2459883-19-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:29 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129831 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-73067 Signed-off-by: Ankur Tyagi --- .../tesseract/CVE-2026-73067-1.patch | 423 ++++++++++++++++++ .../tesseract/CVE-2026-73067-2.patch | 96 ++++ .../tesseract/tesseract_5.5.2.bb | 2 + 3 files changed, 521 insertions(+) create mode 100644 meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73067-1.patch create mode 100644 meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73067-2.patch diff --git a/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73067-1.patch b/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73067-1.patch new file mode 100644 index 0000000000..95fd102ebf --- /dev/null +++ b/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73067-1.patch @@ -0,0 +1,423 @@ +From 9d83107c2511e7e2a7dc649c7bb1633da746669f Mon Sep 17 00:00:00 2001 +From: Stefan Weil +Date: Sun, 12 Jul 2026 13:49:46 +0200 +Subject: [PATCH] Fix memory-safety issues in .traineddata deserialization + +Add bounds checking on count/length fields read from untrusted +.traineddata files before they are used to size allocations or index +arrays. Use unsigned types where negative values make no sense. + +Key changes: +- serialis.cpp: overflow check in DeSerializeSkip, size limits for + DeSerialize(string) and DeSerialize(vector) +- unicharcompress.h: validate RecodedCharID length before reading + into fixed-size code array (buffer overflow fix), change length_ + to uint32_t, use unsigned types for Set() index and length() +- dawg.cpp/h: use uint32_t for num_edges_, add bounds checks on all + edge traversal loops, replace no-op ASSERT_HOST with proper errors +- fontinfo.cpp: bounds check font name size to prevent integer + overflow in size+1, use uint32_t for spacing vector size +- tessdatamanager.cpp: validate offsets are within file bounds +- bitvector.cpp, weightmatrix.cpp, plumbing.cpp: add size limits + +Assisted-by: OpenCode / big-pickle (opencode) +Signed-off-by: Stefan Weil +(cherry picked from commit 82727cc11c34eaf1249af002d69f6bbae70993b9) + +CVE: CVE-2026-73067 +Upstream-Status: Backport [https://github.com/tesseract-ocr/tesseract/commit/82727cc11c34eaf1249af002d69f6bbae70993b9] + +Signed-off-by: Ankur Tyagi +--- + src/ccstruct/fontinfo.cpp | 10 ++++++--- + src/ccstruct/fontinfo.h | 2 +- + src/ccutil/bitvector.cpp | 4 ++++ + src/ccutil/serialis.cpp | 10 +++++++++ + src/ccutil/tessdatamanager.cpp | 9 ++++++++ + src/ccutil/unicharcompress.h | 19 ++++++++++------ + src/dict/dawg.cpp | 40 ++++++++++++++++++++++++++-------- + src/dict/dawg.h | 16 +++++++++----- + src/lstm/plumbing.cpp | 4 ++++ + src/lstm/weightmatrix.cpp | 4 ++++ + 10 files changed, 92 insertions(+), 26 deletions(-) + +diff --git a/src/ccstruct/fontinfo.cpp b/src/ccstruct/fontinfo.cpp +index 65d4d032..9984469f 100644 +--- a/src/ccstruct/fontinfo.cpp ++++ b/src/ccstruct/fontinfo.cpp +@@ -145,6 +145,10 @@ bool read_info(TFile *f, FontInfo *fi) { + if (!f->DeSerialize(&size)) { + return false; + } ++ // Reject unreasonably large font names to prevent overflow in size + 1. ++ if (size > 100000) { ++ return false; ++ } + char *font_name = new char[size + 1]; + fi->name = font_name; + if (!f->DeSerialize(font_name, size)) { +@@ -161,16 +165,16 @@ bool write_info(FILE *f, const FontInfo &fi) { + } + + bool read_spacing_info(TFile *f, FontInfo *fi) { +- int32_t vec_size, kern_size; ++ uint32_t vec_size; ++ int32_t kern_size; + if (!f->DeSerialize(&vec_size)) { + return false; + } +- ASSERT_HOST(vec_size >= 0); + if (vec_size == 0) { + return true; + } + fi->init_spacing(vec_size); +- for (int i = 0; i < vec_size; ++i) { ++ for (uint32_t i = 0; i < vec_size; ++i) { + auto *fs = new FontSpacingInfo(); + if (!f->DeSerialize(&fs->x_gap_before) || !f->DeSerialize(&fs->x_gap_after) || + !f->DeSerialize(&kern_size)) { +diff --git a/src/ccstruct/fontinfo.h b/src/ccstruct/fontinfo.h +index 1a84a567..cfb19e06 100644 +--- a/src/ccstruct/fontinfo.h ++++ b/src/ccstruct/fontinfo.h +@@ -76,7 +76,7 @@ struct FontInfo { + bool DeSerialize(TFile *fp); + + // Reserves unicharset_size spots in spacing_vec. +- void init_spacing(int unicharset_size) { ++ void init_spacing(uint32_t unicharset_size) { + spacing_vec = new std::vector(unicharset_size); + } + // Adds the given pointer to FontSpacingInfo to spacing_vec member +diff --git a/src/ccutil/bitvector.cpp b/src/ccutil/bitvector.cpp +index a02781a8..2b8b7f00 100644 +--- a/src/ccutil/bitvector.cpp ++++ b/src/ccutil/bitvector.cpp +@@ -102,6 +102,10 @@ bool BitVector::DeSerialize(bool swap, FILE *fp) { + if (swap) { + ReverseN(&new_bit_size, sizeof(new_bit_size)); + } ++ // Reject unreasonably large bit vectors. ++ if (new_bit_size > 500000000) { ++ return false; ++ } + Alloc(new_bit_size); + int wordlen = WordLength(); + if (!tesseract::DeSerialize(fp, &array_[0], wordlen)) { +diff --git a/src/ccutil/serialis.cpp b/src/ccutil/serialis.cpp +index d9c9a8d4..cb663094 100644 +--- a/src/ccutil/serialis.cpp ++++ b/src/ccutil/serialis.cpp +@@ -88,6 +88,10 @@ bool TFile::DeSerializeSkip(size_t size) { + if (!DeSerialize(&len)) { + return false; + } ++ // Check for overflow: len * size must not overflow size_t. ++ if (size != 0 && len > SIZE_MAX / size) { ++ return false; ++ } + return Skip(len * size); + } + +@@ -95,6 +99,9 @@ bool TFile::DeSerialize(std::string &data) { + uint32_t size; + if (!DeSerialize(&size)) { + return false; ++ } else if (size > 50000000) { ++ // Arbitrarily limit the size to protect against bad data. ++ return false; + } else if (size > 0) { + // TODO: optimize. + data.resize(size); +@@ -113,6 +120,9 @@ bool TFile::DeSerialize(std::vector &data) { + uint32_t size; + if (!DeSerialize(&size)) { + return false; ++ } else if (size > 50000000) { ++ // Arbitrarily limit the size to protect against bad data. ++ return false; + } else if (size > 0) { + // TODO: optimize. + data.resize(size); +diff --git a/src/ccutil/tessdatamanager.cpp b/src/ccutil/tessdatamanager.cpp +index 8ab26506..67e86dc0 100644 +--- a/src/ccutil/tessdatamanager.cpp ++++ b/src/ccutil/tessdatamanager.cpp +@@ -132,14 +132,23 @@ bool TessdataManager::LoadMemBuffer(const char *name, const char *data, int size + } + for (unsigned i = 0; i < num_entries && i < TESSDATA_NUM_ENTRIES; ++i) { + if (offset_table[i] >= 0) { ++ if (offset_table[i] > size) { ++ return false; ++ } + int64_t entry_size = size - offset_table[i]; + unsigned j = i + 1; + while (j < num_entries && offset_table[j] == -1) { + ++j; + } + if (j < num_entries) { ++ if (offset_table[j] < 0 || offset_table[j] > size) { ++ return false; ++ } + entry_size = offset_table[j] - offset_table[i]; + } ++ if (entry_size < 0) { ++ return false; ++ } + entries_[i].resize(entry_size); + if (!fp.DeSerialize(&entries_[i][0], entry_size)) { + return false; +diff --git a/src/ccutil/unicharcompress.h b/src/ccutil/unicharcompress.h +index 2e81bbde..67a441e8 100644 +--- a/src/ccutil/unicharcompress.h ++++ b/src/ccutil/unicharcompress.h +@@ -41,7 +41,7 @@ public: + length_ = length; + } + // Sets the code value at the given index in the code. +- void Set(int index, int value) { ++ void Set(uint32_t index, int value) { + code_[index] = value; + if (length_ <= index) { + length_ = index + 1; +@@ -59,7 +59,7 @@ public: + return length_ == 0; + } + // Accessors +- int length() const { ++ uint32_t length() const { + return length_; + } + int operator()(int index) const { +@@ -73,14 +73,19 @@ public: + } + // Reads from the given file. Returns false in case of error. + bool DeSerialize(TFile *fp) { +- return fp->DeSerialize(&self_normalized_) && fp->DeSerialize(&length_) && +- fp->DeSerialize(&code_[0], length_); ++ if (!fp->DeSerialize(&self_normalized_) || !fp->DeSerialize(&length_)) { ++ return false; ++ } ++ if (length_ > kMaxCodeLen) { ++ return false; ++ } ++ return fp->DeSerialize(&code_[0], length_); + } + bool operator==(const RecodedCharID &other) const { + if (length_ != other.length_) { + return false; + } +- for (int i = 0; i < length_; ++i) { ++ for (uint32_t i = 0; i < length_; ++i) { + if (code_[i] != other.code_[i]) { + return false; + } +@@ -91,7 +96,7 @@ public: + struct RecodedCharIDHash { + uint64_t operator()(const RecodedCharID &code) const { + uint64_t result = 0; +- for (int i = 0; i < code.length_; ++i) { ++ for (uint32_t i = 0; i < code.length_; ++i) { + result ^= static_cast(code(i)) << (7 * i); + } + return result; +@@ -103,7 +108,7 @@ private: + // that map to the same code. Has boolean value, but int8_t for serialization. + int8_t self_normalized_; + // The number of elements in use in code_; +- int32_t length_; ++ uint32_t length_; + // The re-encoded form of the unichar-id to which this RecodedCharID relates. + int32_t code_[kMaxCodeLen]; + }; +diff --git a/src/dict/dawg.cpp b/src/dict/dawg.cpp +index af45176f..dab4dfc2 100644 +--- a/src/dict/dawg.cpp ++++ b/src/dict/dawg.cpp +@@ -221,7 +221,11 @@ EDGE_REF SquishedDawg::edge_char_of(NODE_REF node, UNICHAR_ID unichar_id, + (!word_end || end_of_word_from_edge_rec(edges_[edge]))) { + return (edge); + } +- } while (!last_edge(edge++)); ++ if (last_edge(edge)) { ++ break; ++ } ++ ++edge; ++ } while (edge < num_edges_); + } + } + return (NO_EDGE); // not found +@@ -234,7 +238,11 @@ int32_t SquishedDawg::num_forward_edges(NODE_REF node) const { + if (forward_edge(edge)) { + do { + num++; +- } while (!last_edge(edge++)); ++ if (last_edge(edge)) { ++ break; ++ } ++ ++edge; ++ } while (edge < num_edges_); + } + + return (num); +@@ -274,7 +282,11 @@ void SquishedDawg::print_node(NODE_REF node, int max_num_edges) const { + if (edge - node > max_num_edges) { + return; + } +- } while (!last_edge(edge++)); ++ if (last_edge(edge)) { ++ break; ++ } ++ ++edge; ++ } while (edge < num_edges_); + + if (edge < num_edges_ && edge_occupied(edge) && backward_edge(edge)) { + do { +@@ -290,7 +302,11 @@ void SquishedDawg::print_node(NODE_REF node, int max_num_edges) const { + if (edge - node > MAX_NODE_EDGES_DISPLAY) { + return; + } +- } while (!last_edge(edge++)); ++ if (last_edge(edge)) { ++ break; ++ } ++ ++edge; ++ } while (edge < num_edges_); + } + } else { + tprintf(REFFORMAT " : no edges in this node\n", node); +@@ -326,14 +342,17 @@ bool SquishedDawg::read_squished_dawg(TFile *file) { + return false; + } + +- int32_t unicharset_size; ++ uint32_t unicharset_size; + if (!file->DeSerialize(&unicharset_size)) { + return false; + } + if (!file->DeSerialize(&num_edges_)) { + return false; + } +- ASSERT_HOST(num_edges_ > 0); // DAWG should not be empty ++ if (num_edges_ == 0) { ++ tprintf("Empty dawg: num_edges is 0\n"); ++ return false; ++ } + Dawg::init(unicharset_size); + + edges_ = new EDGE_RECORD[num_edges_]; +@@ -341,7 +360,7 @@ bool SquishedDawg::read_squished_dawg(TFile *file) { + return false; + } + if (debug_level_ > 2) { +- tprintf("type: %d lang: %s perm: %d unicharset_size: %d num_edges: %d\n", ++ tprintf("type: %d lang: %s perm: %d unicharset_size: %d num_edges: %" PRIu32 "\n", + type_, lang_.c_str(), perm_, unicharset_size_, num_edges_); + for (EDGE_REF edge = 0; edge < num_edges_; ++edge) { + print_edge(edge); +@@ -378,8 +397,11 @@ std::unique_ptr SquishedDawg::build_node_map( + break; + } + if (backward_edge(edge)) { +- while (!last_edge(edge++)) { +- ; ++ while (edge < num_edges_ && !last_edge(edge)) { ++ ++edge; ++ } ++ if (edge < num_edges_) { ++ ++edge; // Skip past the last backward edge. + } + } + edge--; +diff --git a/src/dict/dawg.h b/src/dict/dawg.h +index b87b3880..d0f412c3 100644 +--- a/src/dict/dawg.h ++++ b/src/dict/dawg.h +@@ -418,7 +418,7 @@ public: + ASSERT_HOST(read_squished_dawg(&file)); + num_forward_edges_in_node0 = num_forward_edges(0); + } +- SquishedDawg(EDGE_ARRAY edges, int num_edges, DawgType type, ++ SquishedDawg(EDGE_ARRAY edges, uint32_t num_edges, DawgType type, + const std::string &lang, PermuterType perm, int unicharset_size, + int debug_level) + : Dawg(type, lang, perm, debug_level), +@@ -441,7 +441,7 @@ public: + return true; + } + +- int NumEdges() { ++ uint32_t NumEdges() const { + return num_edges_; + } + +@@ -462,7 +462,11 @@ public: + if (!word_end || end_of_word_from_edge_rec(edges_[edge])) { + vec->push_back(NodeChild(unichar_id_from_edge_rec(edges_[edge]), edge)); + } +- } while (!last_edge(edge++)); ++ if (last_edge(edge)) { ++ break; ++ } ++ ++edge; ++ } while (edge < num_edges_); + } + + /// Returns the next node visited by following the edge +@@ -516,7 +520,7 @@ private: + } + /// Goes through all the edges and clears each one out. + inline void clear_all_edges() { +- for (int edge = 0; edge < num_edges_; edge++) { ++ for (uint32_t edge = 0; edge < num_edges_; edge++) { + set_empty_edge(edge); + } + } +@@ -555,7 +559,7 @@ private: + /// Prints the contents of the SquishedDawg. + void print_all(const char *msg) { + tprintf("\n__________________________\n%s\n", msg); +- for (int i = 0; i < num_edges_; ++i) { ++ for (uint32_t i = 0; i < num_edges_; ++i) { + print_edge(i); + } + tprintf("__________________________\n"); +@@ -565,7 +569,7 @@ private: + + // Member variables. + EDGE_ARRAY edges_ = nullptr; +- int32_t num_edges_ = 0; ++ uint32_t num_edges_ = 0; + int num_forward_edges_in_node0 = 0; + }; + +diff --git a/src/lstm/plumbing.cpp b/src/lstm/plumbing.cpp +index ebb6612e..f0133148 100644 +--- a/src/lstm/plumbing.cpp ++++ b/src/lstm/plumbing.cpp +@@ -222,6 +222,10 @@ bool Plumbing::DeSerialize(TFile *fp) { + if (!fp->DeSerialize(&size)) { + return false; + } ++ // Reject unreasonably large network stacks. ++ if (size > 10000) { ++ return false; ++ } + for (uint32_t i = 0; i < size; ++i) { + Network *network = CreateFromFile(fp); + if (network == nullptr) { +diff --git a/src/lstm/weightmatrix.cpp b/src/lstm/weightmatrix.cpp +index 86255266..d40e9373 100644 +--- a/src/lstm/weightmatrix.cpp ++++ b/src/lstm/weightmatrix.cpp +@@ -295,6 +295,10 @@ bool WeightMatrix::DeSerialize(bool training, TFile *fp) { + if (!fp->DeSerialize(&size)) { + return false; + } ++ // Reject unreasonably large scale vectors. ++ if (size > 100000000) { ++ return false; ++ } + #ifdef FAST_FLOAT + scales_.reserve(size); + for (auto n = size; n > 0; n--) { diff --git a/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73067-2.patch b/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73067-2.patch new file mode 100644 index 0000000000..04d1db2dc5 --- /dev/null +++ b/meta-oe/recipes-graphics/tesseract/tesseract/CVE-2026-73067-2.patch @@ -0,0 +1,96 @@ +From 364a1a76ed19fd2f975f267405f8e36f521e7175 Mon Sep 17 00:00:00 2001 +From: Stefan Weil +Date: Sun, 12 Jul 2026 18:04:46 +0200 +Subject: [PATCH] Fix unbounded allocation and validate DAWG edge structure + +Bound num_edges_ against remaining component bytes before allocating +the edges_ array in read_squished_dawg. This prevents a crafted +num_edges_ = 0x7FFFFFFF from requesting ~17 GB and aborting via +uncaught std::bad_alloc. + +After loading, validate the edge structure: +- Reject edges whose next_node value exceeds num_edges_ (wild-index + read during dictionary lookup). +- Reject unterminated forward edge runs (the original heap OOB read). + +Also add TFile::RemainingBytes() to query how many bytes are left to +read from the current position. + +Assisted-by: OpenCode / big-pickle (opencode) +Reported-by: GitHub Copilot +Signed-off-by: Stefan Weil +(cherry picked from commit 55287a94b8044c05ce3fd10f5aca6ebbd238e518) + +CVE: CVE-2026-73067 +Upstream-Status: Backport [https://github.com/tesseract-ocr/tesseract/commit/55287a94b8044c05ce3fd10f5aca6ebbd238e518] + +Signed-off-by: Ankur Tyagi +--- + src/ccutil/serialis.h | 4 ++++ + src/dict/dawg.cpp | 32 ++++++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+) + +diff --git a/src/ccutil/serialis.h b/src/ccutil/serialis.h +index d6e4a996..59a4e1f1 100644 +--- a/src/ccutil/serialis.h ++++ b/src/ccutil/serialis.h +@@ -75,6 +75,10 @@ public: + void set_swap(bool value) { + swap_ = value; + } ++ // Returns the number of bytes remaining to be read. ++ size_t RemainingBytes() const { ++ return data_ != nullptr && offset_ < data_->size() ? data_->size() - offset_ : 0; ++ } + + // Deserialize data. + bool DeSerializeSize(int32_t *data); +diff --git a/src/dict/dawg.cpp b/src/dict/dawg.cpp +index dab4dfc2..75cb9a1f 100644 +--- a/src/dict/dawg.cpp ++++ b/src/dict/dawg.cpp +@@ -353,12 +353,44 @@ bool SquishedDawg::read_squished_dawg(TFile *file) { + tprintf("Empty dawg: num_edges is 0\n"); + return false; + } ++ // Reject if the declared edge count exceeds the remaining component bytes. ++ if (num_edges_ > file->RemainingBytes() / sizeof(EDGE_RECORD)) { ++ tprintf("Dawg num_edges %u exceeds remaining data\n", num_edges_); ++ return false; ++ } + Dawg::init(unicharset_size); + + edges_ = new EDGE_RECORD[num_edges_]; + if (!file->DeSerialize(&edges_[0], num_edges_)) { + return false; + } ++ // Validate the loaded edge structure: check that next_node values are in ++ // bounds and that forward edge runs are properly terminated. ++ for (uint32_t i = 0; i < num_edges_; ++i) { ++ if (edges_[i] == next_node_mask_) { ++ continue; // Empty slot. ++ } ++ NODE_REF next = next_node_from_edge_rec(edges_[i]); ++ if (next != 0 && static_cast(next) >= num_edges_) { ++ tprintf("Dawg edge %u has out-of-bounds next_node\n", i); ++ return false; ++ } ++ if (forward_edge(i)) { ++ uint32_t j = i; ++ bool terminated = false; ++ do { ++ if (last_edge(j)) { ++ terminated = true; ++ break; ++ } ++ ++j; ++ } while (j < num_edges_); ++ if (!terminated) { ++ tprintf("Dawg forward edge run starting at %u is not terminated\n", i); ++ return false; ++ } ++ } ++ } + if (debug_level_ > 2) { + tprintf("type: %d lang: %s perm: %d unicharset_size: %d num_edges: %" PRIu32 "\n", + type_, lang_.c_str(), perm_, unicharset_size_, num_edges_); diff --git a/meta-oe/recipes-graphics/tesseract/tesseract_5.5.2.bb b/meta-oe/recipes-graphics/tesseract/tesseract_5.5.2.bb index 1b5a5fe2df..f26d2f36a1 100644 --- a/meta-oe/recipes-graphics/tesseract/tesseract_5.5.2.bb +++ b/meta-oe/recipes-graphics/tesseract/tesseract_5.5.2.bb @@ -8,6 +8,8 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" SRCREV = "6e1d56a847e697de07b38619356550e5cf4e8633" SRC_URI = "git://github.com/${BPN}-ocr/${BPN}.git;branch=main;protocol=https;tag=${PV} \ file://CVE-2026-73066.patch \ + file://CVE-2026-73067-1.patch \ + file://CVE-2026-73067-2.patch \ " From patchwork Mon Sep 7 10:23:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97486 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 64B34C79F9E for ; Mon, 7 Sep 2026 10:24:29 +0000 (UTC) Received: from mail-pj1-f44.google.com (mail-pj1-f44.google.com [209.85.216.44]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31703.1788776664072562844 for ; Mon, 07 Sep 2026 03:24:24 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=LboeHzt5; spf=pass (domain: gmail.com, ip: 209.85.216.44, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f44.google.com with SMTP id 98e67ed59e1d1-3856d6fbcb3so2681635a91.2 for ; Mon, 07 Sep 2026 03:24:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776663; x=1789381463; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Zh3VldVVWs3fsInDJtlX5zVLvn81jvikUkZ/QTExdW0=; b=LboeHzt5LseQkWgQIRR6fc64A+ilnZnSvsYoRbJG3NZpM8XmxLT/4+eMgDHoCnl630 Du5Z2BxeNh3VsLv2kSwL16lq+kF3cmh5PjJMGLpC+3Nv3QSKzmKshOYc/M9eN3B8J/4H oMnKBcnopncGGGoDJ5+GvGi/wbiHLIl8WFBGdKZ+Mw5HbYUmhXBPQNLGzK1OxZS4A6HA XkmZoWJE69WhmNVyV0/To+mbYqozK0tSMYro71jbfaeTdfCcqZWmIGTtdtzrTDhyhGkA oeKxaiCrpFlxkBsLEouKfpriwrpLtIJyuNTm+ro0Pf5L9GgqT3JBX25MfaXKU4BNPArh 6/TQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776663; x=1789381463; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Zh3VldVVWs3fsInDJtlX5zVLvn81jvikUkZ/QTExdW0=; b=DdB3iQyAl2A4uNK5OU54wFEWoGgS1PRYN/AU5zAQMV02bvBcrnp1jwm1Ae6ZDR7a2L JeHEk5BQvVp0AZ1+Z4u1qLmIhfg+zJ90WAtYeFBzk3GMBE55hBbmoz2OrDEYJH/k7m5l eCTXKkungPqJD8b1VivlhspCZkfjIzFdEn+0o8/95gOG70E9kxuOWAZjau8/m6cZQuYE 8LinxvWXjmq7loh8Z/vy7DGPsoeFTJlK1I7x2oKsmqlTwbTr3+6C1gP5yYzSaG1H6mVi 6WXAPaAPx8xgQ09UVI0I+V7dq3GjBOrFlmOEgY6oal2kDgymMZ0XhoD4yQVm4dC3DDdW BWRA== X-Gm-Message-State: AFuF++lgWV3+fY4pPHjeLEfwJGdFqfPh1YyxGMT0+nL8zvmCPT6pNjTV cT9CPeuMXNRQjZzrNLTb9nFDaxfqz+bFoOO5dq0K4Zt2UHmKrNV+gvO2uwa2BKuM X-Gm-Gg: AYBFou1oMhfXUASnGjQOvH5Zug76A2ViS8DNU+8+JeIPR7rCZ0UzRfJJUG6c8lx//2a tfTOg4e5i6DbukiOUTwxu+6+CLlUa/i8scE3RRQnpfgRAsLFKL//8YWDMSnLzG7nNH5Q1kEPybU 8nHF19ykxmfvRfSO/Vjf8Le2gQpOw/mFfNw+X8LOg7VQlDSWQYIDAyJZUcKj0z04664+EwPyiT4 g8BqY29TeWtUZIl1rrtM7wRv76ZkYJY590LQBjvAYAAs21cBQkHUoUXs1Pfu/24GfFZUkp5ssIW yC8Dw5jUhJTCVnx6PrUg2dajAQMVfZ0SHFch3yZqGcY9X6P7IZ3orKhjXtRuaq9ruoHwFv18JrS 9JQcmvJxJxaPnx6uyOE/OavnXe0Hp0jYiYm+zuJOcjTTX3Qt01ERfdQ9KOWtp9Y6yYxZw2rLUef wpcllRuXY1qRYqmAu3zze46ezCKGZnxx/AEg4nTLhGeNHYVZjRQlpUqa9i3T4e/bFL1tu0CNMl X-Received: by 2002:a17:90b:5826:b0:38e:7168:281 with SMTP id 98e67ed59e1d1-39b261b07b6mr34858412a91.10.1788776663387; Mon, 07 Sep 2026 03:24:23 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:23 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 20/33] wolfssl: mark CVEs patched Date: Mon, 7 Sep 2026 22:23:04 +1200 Message-ID: <20260907102318.2459883-20-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:29 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129832 From: Ankur Tyagi CVE-2023-6937[1] and CVE-2024-5814[2] are patched in current version. Details: https://nvd.nist.gov/vuln/detail/cve-2023-6937 https://nvd.nist.gov/vuln/detail/cve-2024-5814 [1]https://github.com/wolfSSL/wolfssl/blob/v5.6.6-stable/ChangeLog.md#vulnerabilities [2]https://github.com/wolfSSL/wolfssl/blob/v5.7.2-stable/ChangeLog.md#vulnerabilities Signed-off-by: Ankur Tyagi --- meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 2978ff1cc1..295029246c 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -69,3 +69,5 @@ CVE_STATUS[CVE-2026-5504] = "fixed-version: fixed in 5.9.1" CVE_STATUS[CVE-2026-5507] = "fixed-version: fixed in 5.9.1" CVE_STATUS[CVE-2026-5772] = "fixed-version: fixed in 5.9.1" CVE_STATUS[CVE-2026-5778] = "fixed-version: fixed in 5.9.1" +CVE_STATUS[CVE-2023-6937] = "fixed-version: fixed since v5.6.6" +CVE_STATUS[CVE-2024-5814] = "fixed-version: fixed since v5.7.2" From patchwork Mon Sep 7 10:23:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97487 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 59EE1C79F99 for ; Mon, 7 Sep 2026 10:24:29 +0000 (UTC) Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31925.1788776667248683172 for ; Mon, 07 Sep 2026 03:24:27 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=rws8gEzq; spf=pass (domain: gmail.com, ip: 209.85.215.180, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f180.google.com with SMTP id 41be03b00d2f7-c9e7391839cso3528052a12.0 for ; Mon, 07 Sep 2026 03:24:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776667; x=1789381467; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3ZpoZYRb+PI+XuevsLNMuvxoN3s9INh+91e/35w6yKE=; b=rws8gEzqgsfHXA4RJc92v8MyOj4AYcRCi9vDcGQ2/zwejVRJEHfsBB/r6TPjMdmlpE HYVraXkh87msZcG0YraHJez0FEr4bkbDNhr6DOpm+a8NTfsA6EfHsELhZf2sH9qW+cdh 7B/Uxj7PogXDrvZyZGGizZp6ahBponPhQhGaAVUhN1nC224UEDWjw6sJQYit+7SctY+k jN6qvbO8uK/oN2eg2t6TleP+LnV3uFPRs1JhgmVKVf6KtDmBX9OcFaGgUmM3OkZV8bRh hTlIqimAWf1kTbAorRMditbDopa7THr1/HD6wVpr39NQ+Qcfdys171Micyl6T3Mx0cm8 wP/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776667; x=1789381467; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=3ZpoZYRb+PI+XuevsLNMuvxoN3s9INh+91e/35w6yKE=; b=ARJaSmiMXPjksgOXRvT+fY99w94zanVypm9hKuRFA3IbOseEtkujca+VcEWnQbGvUX 0xMezZy99kuyDgvNl4N91PgCevVeCbLup6yIO0iK3nbt1Y5TVcRARwGXXXHIgAXjBj7w s+QXU2SqNU4A0w1xg2O1RHIZgCaBnHkSAOD0QOYIlI+xj4vRatTiFeuW9YujAzTFrdgK ytjd9TGMnb/hI8d6VTK5rmD9uijvOhUdnEVybyfoeO7OgxgL+mcVOmmu+odZVEdo+zx2 xm9U+QXNNy+7KhVvhMx63ZddDaPsE8s71fKcs46Q9WPuuxoREahpXSD39CcKpeMPuqSK DiWw== X-Gm-Message-State: AFuF++n5H5OdTcTX9DflGCqMIEwXsKgLtNMbu1/3bKVE2RwLRZVOh1tP +7VOJxtaQXZPgp23ER3MSDKf6KH1wx+UtMetQzkr8vwGhyyXyMVQF2/7eQtYBw== X-Gm-Gg: AYBFou37fvzloTCDNvwKMDjvcGQA38WiKxT6VSSqhKxttGTYiUCtgFK6v2EMV+HVSCl uv/rm5hb3F/yUFIYzaPn3DObqnQQfOcjhPNXaridxvxYRr2f5v6o0tgJO78sgIrFt8uXEGV/BM8 e/k4cZtFx0bR9xNOKosQqTYlAseVZXa3VjLLoJk/2XdlAtMF5nJQf/V5E694Hj0Y5iDFgQn90G1 MGY1yk5blgGKdOH6c16WjUGsNavTgUSYvOY9t4GQNGMHvxayqfYGb63P4qXPcmcL0FoAKrHOic5 XUz+rnCeZjQEM6NhIY+tZ6onCC9OFLydrkdAmFJLlqm575FqZ7+GXeaHCpNiOxQgC6XgkbjJTh5 cBb6CJ1CxG+f4ixhaeK9WAD07Mu9Ekusm1Ph2orVOKkI78jVhiONhsbpB7xWx2dy4iYelbWSVWm 9e1BMszT0yOllNLBY7i9399yqZiWJ1FtTZEkXKugDGEhuAsOgudvcOotj8bQkFBdTHCx6hbwXi X-Received: by 2002:a17:90b:3943:b0:398:d8eb:cb2a with SMTP id 98e67ed59e1d1-39b26273e31mr36401170a91.23.1788776666367; Mon, 07 Sep 2026 03:24:26 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:25 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 21/33] wolfssl: patch CVE-2026-10098 Date: Mon, 7 Sep 2026 22:23:05 +1200 Message-ID: <20260907102318.2459883-21-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:29 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129833 From: Ankur Tyagi CVE-2026-10098-1.patch is needed to cherry-pick the commit mentioned in the PR[1] Details: https://nvd.nist.gov/vuln/detail/cve-2026-10098 [1]https://github.com/wolfSSL/wolfssl/pull/10554/commits Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-10098-1.patch | 368 ++++++++++++++++++ .../wolfssl/files/CVE-2026-10098-2.patch | 126 ++++++ .../wolfssl/wolfssl_5.9.1.bb | 2 + 3 files changed, 496 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10098-1.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10098-2.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10098-1.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10098-1.patch new file mode 100644 index 0000000000..86f1c8a9a0 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10098-1.patch @@ -0,0 +1,368 @@ +From d2dca1bdcb6dc5f6fb02c44a042130cd11d27cd0 Mon Sep 17 00:00:00 2001 +From: Colton Willey +Date: Mon, 13 Apr 2026 20:29:50 -0700 +Subject: [PATCH] Fix NULL derefs, buffer overflow, and i2d contract in + EVP/OCSP/X509 + +Harden OpenSSL compatibility layer against NULL pointers, negative lengths, +and buffer overflows across EVP, OCSP, and X509 APIs. Fix DSA SignFinal +write-before-check overflow, add missing i2d_OCSP_RESPONSE allocation path, +and fix unaligned keyUsage access. + +(cherry picked from commit 58a27848a800aadca91f606dc4fe5234b9971011) + +CVE: CVE-2026-10098 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/58a27848a800aadca91f606dc4fe5234b9971011] + +Signed-off-by: Ankur Tyagi +--- + src/ocsp.c | 39 +++++++++++++++++++++++++------ + src/ssl.c | 8 ++++++- + src/x509.c | 12 ++++++++-- + tests/api.c | 2 +- + wolfcrypt/src/evp.c | 50 ++++++++++++++++++++++++++++++++-------- + wolfcrypt/src/pwdbased.c | 3 +++ + 6 files changed, 94 insertions(+), 20 deletions(-) + +diff --git a/src/ocsp.c b/src/ocsp.c +index 2fff7ced5..9de23cb9e 100644 +--- a/src/ocsp.c ++++ b/src/ocsp.c +@@ -749,7 +749,9 @@ int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs, + + single = bs->single; + while (single != NULL) { +- if ((XMEMCMP(single->status->serial, id->status->serial, (size_t)single->status->serialSz) == 0) ++ if (single->status != NULL && id->status != NULL && ++ (XMEMCMP(single->status->serial, id->status->serial, ++ (size_t)single->status->serialSz) == 0) + && (XMEMCMP(single->issuerHash, id->issuerHash, OCSP_DIGEST_SIZE) == 0) + && (XMEMCMP(single->issuerKeyHash, id->issuerKeyHash, OCSP_DIGEST_SIZE) == 0)) { + break; +@@ -757,7 +759,7 @@ int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs, + single = single->next; + } + +- if (single == NULL) ++ if (single == NULL || single->status == NULL) + return WOLFSSL_FAILURE; + + if (status != NULL) +@@ -1108,6 +1110,9 @@ int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP* bs, + int embedded; + DecodedCert *cert = NULL; + ++ if (bs == NULL) ++ return WOLFSSL_FAILURE; ++ + ret = OcspFindSigner(bs, certs, &cert, &embedded, flags); + if (ret != 0) { + WOLFSSL_MSG("OCSP no signer found"); +@@ -1300,15 +1305,31 @@ int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response, + if (response == NULL) + return BAD_FUNC_ARG; + ++ if (response->source == NULL) ++ return BAD_FUNC_ARG; ++ + if (data == NULL) + return (int)response->maxIdx; + +- XMEMCPY(*data, response->source, response->maxIdx); ++ if (*data == NULL) { ++ *data = (unsigned char*)XMALLOC(response->maxIdx, NULL, ++ DYNAMIC_TYPE_OPENSSL); ++ if (*data == NULL) ++ return -1; ++ XMEMCPY(*data, response->source, response->maxIdx); ++ } ++ else { ++ XMEMCPY(*data, response->source, response->maxIdx); ++ *data += response->maxIdx; ++ } ++ + return (int)response->maxIdx; + } + + int wolfSSL_OCSP_response_status(OcspResponse *response) + { ++ if (response == NULL) ++ return -1; + return response->responseStatus; + } + +@@ -1335,8 +1356,12 @@ const char *wolfSSL_OCSP_response_status_str(long s) + WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response) + { + WOLFSSL_OCSP_BASICRESP* bs; +- const unsigned char *ptr = response->source; ++ const unsigned char *ptr; + ++ if (response == NULL || response->source == NULL) ++ return NULL; ++ ++ ptr = response->source; + bs = wolfSSL_d2i_OCSP_RESPONSE(NULL, &ptr, response->maxIdx); + return bs; + } +@@ -1637,8 +1662,8 @@ int wolfSSL_OCSP_single_get0_status(WOLFSSL_OCSP_SINGLERESP *single, + WOLFSSL_ASN1_TIME **thisupd, + WOLFSSL_ASN1_TIME **nextupd) + { +- if (single == NULL) +- return WOLFSSL_FAILURE; ++ if (single == NULL || single->status == NULL) ++ return -1; + + #ifdef WOLFSSL_OCSP_PARSE_STATUS + if (thisupd != NULL) +@@ -1784,7 +1809,7 @@ int wolfSSL_OCSP_REQ_CTX_add1_header(WOLFSSL_OCSP_REQ_CTX *ctx, + { + WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_add1_header"); + +- if (name == NULL) { ++ if (ctx == NULL || name == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } +diff --git a/src/ssl.c b/src/ssl.c +index 58cd6701c..7d6ca462b 100644 +--- a/src/ssl.c ++++ b/src/ssl.c +@@ -11699,13 +11699,19 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, + int wolfSSL_OCSP_parse_url(const char* url, char** host, char** port, + char** path, int* ssl) + { +- const char* u = url; ++ const char* u; + const char* upath; /* path in u */ + const char* uport; /* port in u */ + const char* hostEnd; + + WOLFSSL_ENTER("OCSP_parse_url"); + ++ if (url == NULL || host == NULL || port == NULL || path == NULL || ++ ssl == NULL) { ++ return WOLFSSL_FAILURE; ++ } ++ ++ u = url; + *host = NULL; + *port = NULL; + *path = NULL; +diff --git a/src/x509.c b/src/x509.c +index 46dfd38ed..b92f7d735 100644 +--- a/src/x509.c ++++ b/src/x509.c +@@ -1317,7 +1317,9 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, + if (ext && ext->value.data) { + if (ext->value.length == sizeof(word16)) { + /* if ext->value is already word16, set directly */ +- x509->keyUsage = *(word16*)ext->value.data; ++ word16 ku; ++ XMEMCPY(&ku, ext->value.data, sizeof(word16)); ++ x509->keyUsage = ku; + #ifdef BIG_ENDIAN_ORDER + x509->keyUsage = rotlFixed16(x509->keyUsage, 8U); + #endif +@@ -10998,6 +11000,11 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509) + if (x509->serialNumber != NULL) + return x509->serialNumber; + ++ if (x509->serialSz < 0) { ++ WOLFSSL_MSG("Invalid serial number size"); ++ return NULL; ++ } ++ + a = wolfSSL_ASN1_INTEGER_new(); + if (a == NULL) + return NULL; +@@ -16120,7 +16127,8 @@ int wolfSSL_X509_set1_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t) + int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s) + { + WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber"); +- if (x509 == NULL || s == NULL || s->length >= EXTERNAL_SERIAL_SIZE) ++ if (x509 == NULL || s == NULL || s->data == NULL || ++ s->length >= EXTERNAL_SERIAL_SIZE) + return WOLFSSL_FAILURE; + + /* WOLFSSL_ASN1_INTEGER has type | size | data +diff --git a/tests/api.c b/tests/api.c +index 5eca4071a..919b951b3 100644 +--- a/tests/api.c ++++ b/tests/api.c +@@ -20274,7 +20274,7 @@ static int test_wolfSSL_OCSP_single_get0_status(void) + ExpectPtrEq(nextDate, &certStatus.nextDateParsed); + + ExpectIntEQ(wolfSSL_OCSP_single_get0_status(NULL, NULL, NULL, NULL, NULL), +- CERT_GOOD); ++ -1); + ExpectIntEQ(wolfSSL_OCSP_single_get0_status(&single, NULL, NULL, NULL, + NULL), CERT_GOOD); + #endif +diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c +index 05e406883..996f31f86 100644 +--- a/wolfcrypt/src/evp.c ++++ b/wolfcrypt/src/evp.c +@@ -1314,7 +1314,11 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, + #ifndef WOLFSSL_AESGCM_STREAM + if ((ctx->authBuffer && ctx->authBufferLen > 0) + || (ctx->authBufferLen == 0)) { +- if (ctx->enc) ++ if (ctx->authBufferLen > 0 && out == NULL) { ++ ret = WOLFSSL_FAILURE; ++ *outl = 0; ++ } ++ else if (ctx->enc) + ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out, + ctx->authBuffer, ctx->authBufferLen, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, +@@ -1397,7 +1401,11 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, + case WC_AES_256_CCM_TYPE: + if ((ctx->authBuffer && ctx->authBufferLen > 0) + || (ctx->authBufferLen == 0)) { +- if (ctx->enc) { ++ if (ctx->authBufferLen > 0 && out == NULL) { ++ ret = WOLFSSL_FAILURE; ++ *outl = 0; ++ } ++ else if (ctx->enc) { + ret = wc_AesCcmEncrypt(&ctx->cipher.aes, out, + ctx->authBuffer, (word32)ctx->authBufferLen, + ctx->iv, (word32)ctx->ivSz, ctx->authTag, +@@ -4309,16 +4317,19 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, + #ifndef NO_DSA + case WC_EVP_PKEY_DSA: { + int bytes; +- ret = wolfSSL_DSA_do_sign(md, sigret, pkey->dsa); ++ unsigned char tmpSig[DSA_MAX_SIG_SIZE]; ++ ret = wolfSSL_DSA_do_sign(md, tmpSig, pkey->dsa); + /* wolfSSL_DSA_do_sign() can return WOLFSSL_FATAL_ERROR */ + if (ret != WOLFSSL_SUCCESS) + return ret; + bytes = wolfSSL_BN_num_bytes(pkey->dsa->q); + if (bytes == WC_NO_ERR_TRACE(WOLFSSL_FAILURE) || +- (int)*siglen < bytes * 2) ++ bytes > DSA_MAX_HALF_SIZE || ++ bytes * 2 > (int)*siglen) + { + return WOLFSSL_FAILURE; + } ++ XMEMCPY(sigret, tmpSig, bytes * 2); + *siglen = (unsigned int)(bytes * 2); + return WOLFSSL_SUCCESS; + } +@@ -4398,7 +4409,8 @@ int wolfSSL_EVP_VerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, + unsigned char md[WC_MAX_DIGEST_SIZE]; + unsigned int mdsize; + +- if (ctx == NULL) return WOLFSSL_FAILURE; ++ if (ctx == NULL || pkey == NULL || sig == NULL) ++ return WOLFSSL_FAILURE; + WOLFSSL_ENTER("EVP_VerifyFinal"); + ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize); + if (ret <= 0) +@@ -4459,6 +4471,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, WOLFSSL_ENGINE* e, + if (type != WC_EVP_PKEY_HMAC || (key == NULL && keylen != 0)) + return NULL; + ++ if (keylen < 0) ++ return NULL; ++ + pkey = wolfSSL_EVP_PKEY_new(); + if (pkey != NULL) { + pkey->pkey.ptr = (char*)XMALLOC((size_t)keylen, NULL, +@@ -4870,6 +4885,9 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, + return WOLFSSL_SUCCESS; + } + } ++ else if (ctx->pctx == NULL || ctx->pctx->pkey == NULL) { ++ return WOLFSSL_FAILURE; ++ } + #ifndef NO_RSA + else if (ctx->pctx->pkey->type == WC_EVP_PKEY_RSA) { + if (sig == NULL) { +@@ -5007,6 +5025,8 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, + return WOLFSSL_FAILURE; + } + else { ++ if (ctx->pctx == NULL || ctx->pctx->pkey == NULL) ++ return WOLFSSL_FAILURE; + /* Verify the signature with the digest. */ + switch (ctx->pctx->pkey->type) { + #if !defined(NO_RSA) +@@ -10232,6 +10252,9 @@ int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out, + return WOLFSSL_FAILURE; + } + ++ if (inSz < 0) ++ return WOLFSSL_FAILURE; ++ + err = wolfSSL_EVP_get_hashinfo(evp, &hashType, &hashSz); + if (err != WOLFSSL_SUCCESS) + return err; +@@ -11279,6 +11302,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) + enum wc_HashType macType; + + WOLFSSL_ENTER("wolfSSL_EVP_DigestFinal"); ++ + macType = EvpMd2MacType(wolfSSL_EVP_MD_CTX_md(ctx)); + switch (macType) { + case WC_HASH_TYPE_MD4: +@@ -11304,16 +11328,18 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) + + case WC_HASH_TYPE_SHAKE128: + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) +- *s = 16; /* if mixing up XOF with plain digest 128 bit is +- * default for SHAKE128 */ ++ if (s != NULL) ++ *s = 16; /* if mixing up XOF with plain digest 128 bit is ++ * default for SHAKE128 */ + #else + return WOLFSSL_FAILURE; + #endif + break; + case WC_HASH_TYPE_SHAKE256: + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) +- *s = 32; /* if mixing up XOF with plain digest 256 bit is +- * default for SHAKE256 */ ++ if (s != NULL) ++ *s = 32; /* if mixing up XOF with plain digest 256 bit is ++ * default for SHAKE256 */ + #else + return WOLFSSL_FAILURE; + #endif +@@ -12881,6 +12907,9 @@ int wolfSSL_EVP_EncodeBlock(unsigned char *out, const unsigned char *in, + if (out == NULL || in == NULL) + return WOLFSSL_FATAL_ERROR; + ++ if (inLen < 0) ++ return WOLFSSL_FATAL_ERROR; ++ + if (Base64_Encode_NoNl(in, (word32)inLen, out, &ret) == 0) + return (int)ret; + else +@@ -12897,6 +12926,9 @@ int wolfSSL_EVP_DecodeBlock(unsigned char *out, const unsigned char *in, + if (out == NULL || in == NULL) + return WOLFSSL_FATAL_ERROR; + ++ if (inLen < 0) ++ return WOLFSSL_FATAL_ERROR; ++ + if (Base64_Decode(in, (word32)inLen, out, &ret) == 0) + return (int)ret; + else +diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c +index c2ed5c042..4b9502a8c 100644 +--- a/wolfcrypt/src/pwdbased.c ++++ b/wolfcrypt/src/pwdbased.c +@@ -76,6 +76,9 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen, + return BAD_FUNC_ARG; + } + ++ if (keyLen > INT_MAX - ivLen) ++ return BAD_FUNC_ARG; ++ + if (iterations <= 0) + iterations = 1; + diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10098-2.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10098-2.patch new file mode 100644 index 0000000000..0c28dbbba0 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10098-2.patch @@ -0,0 +1,126 @@ +From 1260ee5fe45c6e4c0aeb62c26a04db5faec6ff08 Mon Sep 17 00:00:00 2001 +From: Reda Chouk +Date: Fri, 29 May 2026 05:10:21 -0700 +Subject: [PATCH] Require equal serial lengths before comparing serial bytes so + a response serial that is only a prefix of the requested serial is not + treated as a match + +(cherry picked from commit 53e1db478b62f40ad6ce9b1a1d65d593a9d3d9fb) + +CVE: CVE-2026-10098 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/53e1db478b62f40ad6ce9b1a1d65d593a9d3d9fb] + +Signed-off-by: Ankur Tyagi +--- + src/ocsp.c | 3 ++- + tests/api.c | 1 + + tests/api/test_ocsp.c | 57 +++++++++++++++++++++++++++++++++++++++++++ + tests/api/test_ocsp.h | 1 + + 4 files changed, 61 insertions(+), 1 deletion(-) + +diff --git a/src/ocsp.c b/src/ocsp.c +index 9de23cb9e..b8352ee72 100644 +--- a/src/ocsp.c ++++ b/src/ocsp.c +@@ -750,7 +750,8 @@ int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs, + single = bs->single; + while (single != NULL) { + if (single->status != NULL && id->status != NULL && +- (XMEMCMP(single->status->serial, id->status->serial, ++ (single->status->serialSz == id->status->serialSz) ++ && (XMEMCMP(single->status->serial, id->status->serial, + (size_t)single->status->serialSz) == 0) + && (XMEMCMP(single->issuerHash, id->issuerHash, OCSP_DIGEST_SIZE) == 0) + && (XMEMCMP(single->issuerKeyHash, id->issuerKeyHash, OCSP_DIGEST_SIZE) == 0)) { +diff --git a/tests/api.c b/tests/api.c +index 919b951b3..ad5f84573 100644 +--- a/tests/api.c ++++ b/tests/api.c +@@ -35924,6 +35924,7 @@ TEST_CASE testCases[] = { + TEST_DECL(test_ocsp_response_parsing), + TEST_DECL(test_ocsp_certid_enc_dec), + TEST_DECL(test_ocsp_certid_dup), ++ TEST_DECL(test_ocsp_resp_find_status_serial_prefix), + TEST_DECL(test_ocsp_tls_cert_cb), + TEST_DECL(test_ocsp_cert_unknown_crl_fallback), + TEST_DECL(test_ocsp_cert_unknown_crl_fallback_nonleaf), +diff --git a/tests/api/test_ocsp.c b/tests/api/test_ocsp.c +index 02938adfd..1f1055fc6 100644 +--- a/tests/api/test_ocsp.c ++++ b/tests/api/test_ocsp.c +@@ -723,6 +723,63 @@ int test_ocsp_certid_dup(void) + } + #endif + ++int test_ocsp_resp_find_status_serial_prefix(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA) && !defined(NO_SHA) ++ OcspResponse response; ++ OcspEntry single; ++ CertStatus responseStatus; ++ OcspEntry requestedId; ++ CertStatus requestedStatus; ++ int status; ++ ++ XMEMSET(&response, 0, sizeof(response)); ++ XMEMSET(&single, 0, sizeof(single)); ++ XMEMSET(&responseStatus, 0, sizeof(responseStatus)); ++ XMEMSET(&requestedId, 0, sizeof(requestedId)); ++ XMEMSET(&requestedStatus, 0, sizeof(requestedStatus)); ++ ++ single.status = &responseStatus; ++ requestedId.status = &requestedStatus; ++ response.single = &single; ++ ++ /* Matching issuer name and key hashes on both sides. */ ++ XMEMSET(single.issuerHash, 0x41, OCSP_DIGEST_SIZE); ++ XMEMSET(single.issuerKeyHash, 0x42, OCSP_DIGEST_SIZE); ++ XMEMCPY(requestedId.issuerHash, single.issuerHash, OCSP_DIGEST_SIZE); ++ XMEMCPY(requestedId.issuerKeyHash, single.issuerKeyHash, OCSP_DIGEST_SIZE); ++ ++ /* Response carries a CERT_GOOD status for serial 01:02 (2 bytes). */ ++ responseStatus.serial[0] = 0x01; ++ responseStatus.serial[1] = 0x02; ++ responseStatus.serialSz = 2; ++ responseStatus.status = CERT_GOOD; ++ ++ /* Sanity check: an exact serial match must be found and report CERT_GOOD. */ ++ requestedStatus.serial[0] = 0x01; ++ requestedStatus.serial[1] = 0x02; ++ requestedStatus.serialSz = 2; ++ status = -1; ++ ExpectIntEQ(wolfSSL_OCSP_resp_find_status(&response, &requestedId, &status, ++ NULL, NULL, NULL, NULL), WOLFSSL_SUCCESS); ++ ExpectIntEQ(status, CERT_GOOD); ++ ++ /* Request serial 01:02:03 (3 bytes) shares the 01:02 prefix of the ++ * response serial. ++ * The lookup must not bind the good response to this longer and ++ * differing serial. */ ++ requestedStatus.serial[0] = 0x01; ++ requestedStatus.serial[1] = 0x02; ++ requestedStatus.serial[2] = 0x03; ++ requestedStatus.serialSz = 3; ++ status = -1; ++ ExpectIntEQ(wolfSSL_OCSP_resp_find_status(&response, &requestedId, &status, ++ NULL, NULL, NULL, NULL), WOLFSSL_FAILURE); ++#endif ++ return EXPECT_RESULT(); ++} ++ + #if defined(HAVE_OCSP) && defined(WOLFSSL_CERT_SETUP_CB) && \ + defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_RSA) && \ + (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ +diff --git a/tests/api/test_ocsp.h b/tests/api/test_ocsp.h +index 6df114b87..2ad56ce55 100644 +--- a/tests/api/test_ocsp.h ++++ b/tests/api/test_ocsp.h +@@ -24,6 +24,7 @@ + + int test_ocsp_certid_enc_dec(void); + int test_ocsp_certid_dup(void); ++int test_ocsp_resp_find_status_serial_prefix(void); + int test_ocsp_status_callback(void); + int test_ocsp_basic_verify(void); + int test_ocsp_response_parsing(void); diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 295029246c..094bf8d78b 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -15,6 +15,8 @@ RPROVIDES:${PN} = "cyassl" SRC_URI = " \ git://github.com/wolfSSL/wolfssl.git;protocol=https;branch=master;tag=v${PV}-stable \ file://run-ptest \ + file://CVE-2026-10098-1.patch \ + file://CVE-2026-10098-2.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97491 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 A5CC4C79F9F for ; Mon, 7 Sep 2026 10:24:39 +0000 (UTC) Received: from mail-pg1-f182.google.com (mail-pg1-f182.google.com [209.85.215.182]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31704.1788776669737572920 for ; Mon, 07 Sep 2026 03:24:29 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=XzRWZGOx; spf=pass (domain: gmail.com, ip: 209.85.215.182, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f182.google.com with SMTP id 41be03b00d2f7-cc147d86bebso3023412a12.0 for ; Mon, 07 Sep 2026 03:24:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776669; x=1789381469; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=2sGyBIyPYuTH5WoWwO42Oy42NHP4EK9G7eiQnILPsLU=; b=XzRWZGOxdfsgjm4Gf298wgVVJxBtZJLgcF02rF7GJ1MObYABNw42GD2z+spvVhq4Os dHi25jfuV3UGaNmyV8NbN33Pk6IOq6JdJqUdcIYMVENXDIe9A7+vVEp08a9l+KyINixE JsDcN4t8Q8OIUqCkMm1RYuPe5cZpkOijm4eo/RHoR1vJaj3OpyotFSn8MHryh/YyTkyQ bj1PTulnBosVyABy5kuozwBbIT+SBDDugqM37yip3YzrFBFoZXjTFK3xjx0BRU0dc1uZ XpWDz7DWo2gyy8w+r0TptAmD9MvAL1ptE1qzs3ObCux3OU3TTzccTEjpgW2cWyq0wSv5 XS/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776669; x=1789381469; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=2sGyBIyPYuTH5WoWwO42Oy42NHP4EK9G7eiQnILPsLU=; b=TNEM3EpXyh8DRzXoyD/kk/Zw1s/GriDGusFUjdRc6ovreXitxCj3diRcDZeDsC7nx3 k7ez6wFt4YGKdVN4HYHCtBS42ow1x3TVYWSjjeiGazA+8dYm8CHrB7qCg2vEwUIBlSL0 h8L8KdJHxfwnVDlqb5IdOseTRIggTszuHrGR1vlOaB75MzDIYc8koZnxy+t9MvZPBhIA fwadQBf3s4YIjV2r2XWDSvqHAnDug2t4Zhz/QD0c4MqYaYvtV9bY336xRfI/yrc/9cGY 3VQb9hzqCKps5K+XCFrIv7gF1MUEor6tQEdlFeomgXer79KkVxjsPcRAMbgDK88QnaN/ 6GoA== X-Gm-Message-State: AFuF++mD+ciVkUHCYkEF7cM2wfba8N0hcKMTMzJUsEFZ19NYsAnlKxmF ir6V2dyxXcFhzDr1x+nbg0cOZULENcSBrJFKs8xs/wjgXA2xjBkrTY33bAfvWyzm X-Gm-Gg: AYBFou3cvdf9+5rt7nnSlfk/juIf3XBi2amEZyGI9d8eOCCil5kpoux4GNL3KHl/8S6 VHRIANRyhagcl7wKOG0QNVk7dm7/3UJXvwkVlHU5NKnIffRZ1uBzL3/uV7+Q/UGszXdbuMG80FF 3/lCLLsKz0G5SWKfbyBJONYijrm5OZHSn3Myi1n/8+shaFg0s6FyrSfaz0yM8dV0vA1lxbA/x6S F3TY56PCg2voR9WzXH4sUD+liptiekG+auUHFEYzANAXqxvBgeKDCnNCprnGEIKMX12ASgI+DiQ 37sSLI1E1SKaCHegthjw0oSVT4R9eNInuzdABgetw/nGnd8ZYK91UDNly7pImN9tdQyvqzUr0oT S2Oo6tQmJae8uWcBlruW3TxNhTCRPGGgMuE1sYcPsY0wtmN+z5jwlEhleAKO/0nGlc/nsFOn5D4 w8dfZaRMbNQLm6LMHshUXL7oKeKrAFs/zrIvHOiDkjguUoTYmwtl+//feLYt7ugBW0/X2VG4kPV A== X-Received: by 2002:a05:6a20:cf83:b0:3d2:ee7a:eba9 with SMTP id adf61e73a8af0-3da213cae76mr31665053637.4.1788776669061; Mon, 07 Sep 2026 03:24:29 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:28 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 22/33] wolfssl: patch CVE-2026-10512 Date: Mon, 7 Sep 2026 22:23:06 +1200 Message-ID: <20260907102318.2459883-22-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129834 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-10512 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-10512.patch | 182 ++++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 1 + 2 files changed, 183 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10512.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10512.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10512.patch new file mode 100644 index 0000000000..74288c28f9 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-10512.patch @@ -0,0 +1,182 @@ +From 8c3f7b9c7f7efb9e8539c2d98fe52e116f3402eb Mon Sep 17 00:00:00 2001 +From: Sean Parkinson +Date: Wed, 27 May 2026 12:16:06 +1000 +Subject: [PATCH] X25519 x64 ASM: fix full reduction + +The last add was overflowing into the top bit. +Must mask the last word to clear top bit. + +Add test vectors from Wycheproof. + +(cherry picked from commit 14b55a0bc42c4f2d2fa0a06af53a603ed619c9b0) + +CVE: CVE-2026-10512 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/14b55a0bc42c4f2d2fa0a06af53a603ed619c9b0] + +Signed-off-by: Ankur Tyagi +--- + tests/api/test_curve25519.c | 93 +++++++++++++++++++++++++++++++++++ + tests/api/test_curve25519.h | 2 + + wolfcrypt/src/fe_x25519_asm.S | 4 ++ + 3 files changed, 99 insertions(+) + +diff --git a/tests/api/test_curve25519.c b/tests/api/test_curve25519.c +index 36cf643f2..36c8e58af 100644 +--- a/tests/api/test_curve25519.c ++++ b/tests/api/test_curve25519.c +@@ -353,6 +353,99 @@ int test_wc_curve25519_shared_secret_ex(void) + return EXPECT_RESULT(); + } /* END test_wc_curve25519_shared_secret_ex */ + ++/* ++ * Known-answer tests for wc_curve25519_shared_secret_ex. ++ * ++ * Both vectors share one private scalar and produce a shared secret that is a ++ * small canonical value (9 and 16, little-endian). Because the result is close ++ * to a multiple of the field prime, these exercise the final modular reduction ++ * of the X25519 computation: a result that was only reduced mod 2^256 (or left ++ * in [p, 2^255)) instead of fully reduced mod 2^255-19 would not match. ++ * All values are 32-byte little-endian encodings per RFC 7748. ++ */ ++int test_wc_curve25519_shared_secret_ex_kat(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT) ++ /* Private scalar shared by both vectors. */ ++ static const byte kPriv[CURVE25519_KEYSIZE] = { ++ 0x60, 0xa3, 0xa4, 0xf1, 0x30, 0xb9, 0x8a, 0x5b, ++ 0xe4, 0xb1, 0xce, 0xdb, 0x7c, 0xb8, 0x55, 0x84, ++ 0xa3, 0x52, 0x0e, 0x14, 0x2d, 0x47, 0x4d, 0xc9, ++ 0xcc, 0xb9, 0x09, 0xa0, 0x73, 0xa9, 0x76, 0x7f ++ }; ++ /* Vector 1 public value, expected shared secret == 9. */ ++ static const byte kPub1[CURVE25519_KEYSIZE] = { ++ 0x3b, 0x18, 0xdf, 0x1e, 0x50, 0xb8, 0x99, 0xeb, ++ 0xd5, 0x88, 0xc3, 0x16, 0x1c, 0xbd, 0x3b, 0xf9, ++ 0x8e, 0xbc, 0xc2, 0xc1, 0xf7, 0xdf, 0x53, 0xb8, ++ 0x11, 0xbd, 0x0e, 0x91, 0xb4, 0xd5, 0x15, 0x3d ++ }; ++ static const byte kExpected1[CURVE25519_KEYSIZE] = { ++ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ }; ++ /* Vector 2 public value, expected shared secret == 16. */ ++ static const byte kPub2[CURVE25519_KEYSIZE] = { ++ 0xca, 0xb6, 0xf9, 0xe7, 0xd8, 0xce, 0x00, 0xdf, ++ 0xce, 0xa9, 0xbb, 0xd8, 0xf0, 0x69, 0xef, 0x7f, ++ 0xb2, 0xac, 0x50, 0x4a, 0xbf, 0x83, 0xb8, 0x7d, ++ 0xb6, 0x01, 0xb5, 0xae, 0x0a, 0x7f, 0x76, 0x15 ++ }; ++ static const byte kExpected2[CURVE25519_KEYSIZE] = { ++ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ }; ++ /* Table-driven so both vectors run through the identical code path. */ ++ struct { ++ const byte* pub; ++ const byte* expected; ++ } vec[2]; ++ curve25519_key private_key; ++ curve25519_key public_key; ++ WC_RNG rng; ++ byte out[CURVE25519_KEYSIZE]; ++ word32 outLen; ++ int i; ++ ++ vec[0].pub = kPub1; vec[0].expected = kExpected1; ++ vec[1].pub = kPub2; vec[1].expected = kExpected2; ++ ++ XMEMSET(&rng, 0, sizeof(WC_RNG)); ++ ExpectIntEQ(wc_InitRng(&rng), 0); ++ ++ for (i = 0; i < 2; i++) { ++ XMEMSET(&private_key, 0, sizeof(private_key)); ++ XMEMSET(&public_key, 0, sizeof(public_key)); ++ ExpectIntEQ(wc_curve25519_init(&private_key), 0); ++ ExpectIntEQ(wc_curve25519_init(&public_key), 0); ++ #ifdef WOLFSSL_CURVE25519_BLINDING ++ ExpectIntEQ(wc_curve25519_set_rng(&private_key, &rng), 0); ++ #endif ++ ExpectIntEQ(wc_curve25519_import_private_ex(kPriv, sizeof(kPriv), ++ &private_key, EC25519_LITTLE_ENDIAN), 0); ++ ExpectIntEQ(wc_curve25519_import_public_ex(vec[i].pub, ++ CURVE25519_KEYSIZE, &public_key, EC25519_LITTLE_ENDIAN), 0); ++ ++ outLen = sizeof(out); ++ ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, ++ out, &outLen, EC25519_LITTLE_ENDIAN), 0); ++ ExpectIntEQ(outLen, CURVE25519_KEYSIZE); ++ ExpectIntEQ(XMEMCMP(out, vec[i].expected, CURVE25519_KEYSIZE), 0); ++ ++ wc_curve25519_free(&private_key); ++ wc_curve25519_free(&public_key); ++ } ++ ++ DoExpectIntEQ(wc_FreeRng(&rng), 0); ++#endif ++ return EXPECT_RESULT(); ++} /* END test_wc_curve25519_shared_secret_ex_kat */ ++ + /* + * Testing wc_curve25519_make_pub + */ +diff --git a/tests/api/test_curve25519.h b/tests/api/test_curve25519.h +index 0e0e65287..770b509af 100644 +--- a/tests/api/test_curve25519.h ++++ b/tests/api/test_curve25519.h +@@ -30,6 +30,7 @@ int test_wc_curve25519_export_key_raw(void); + int test_wc_curve25519_export_key_raw_ex(void); + int test_wc_curve25519_make_key(void); + int test_wc_curve25519_shared_secret_ex(void); ++int test_wc_curve25519_shared_secret_ex_kat(void); + int test_wc_curve25519_make_pub(void); + int test_wc_curve25519_export_public_ex(void); + int test_wc_curve25519_export_private_raw_ex(void); +@@ -43,6 +44,7 @@ int test_wc_curve25519_import_private(void); + TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_key_raw_ex), \ + TEST_DECL_GROUP("curve25519", test_wc_curve25519_make_key), \ + TEST_DECL_GROUP("curve25519", test_wc_curve25519_shared_secret_ex), \ ++ TEST_DECL_GROUP("curve25519", test_wc_curve25519_shared_secret_ex_kat), \ + TEST_DECL_GROUP("curve25519", test_wc_curve25519_make_pub), \ + TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_public_ex), \ + TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_private_raw_ex), \ +diff --git a/wolfcrypt/src/fe_x25519_asm.S b/wolfcrypt/src/fe_x25519_asm.S +index f4cdf343c..5abe4cd5e 100644 +--- a/wolfcrypt/src/fe_x25519_asm.S ++++ b/wolfcrypt/src/fe_x25519_asm.S +@@ -4639,6 +4639,7 @@ L_curve25519_base_x64_3: + adcq $0x00, %r8 + adcq $0x00, %r9 + adcq $0x00, %r10 ++ andq %rax, %r10 + # Store + movq %rcx, (%rdi) + movq %r8, 8(%rdi) +@@ -7054,6 +7055,7 @@ L_curve25519_x64_3: + adcq $0x00, %r9 + adcq $0x00, %r10 + adcq $0x00, %r11 ++ andq %rax, %r11 + # Store + movq %rcx, (%rdi) + movq %r9, 8(%rdi) +@@ -15107,6 +15109,7 @@ L_curve25519_base_avx2_last_3: + adcq $0x00, %r9 + adcq $0x00, %r10 + adcq $0x00, %r11 ++ andq %rcx, %r11 + # Store + movq %r8, (%rdi) + movq %r9, 8(%rdi) +@@ -17116,6 +17119,7 @@ L_curve25519_avx2_last_3: + adcq $0x00, %r10 + adcq $0x00, %r11 + adcq $0x00, %r12 ++ andq %rcx, %r12 + # Store + movq %r9, (%rdi) + movq %r10, 8(%rdi) diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 094bf8d78b..4f6ae56567 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -17,6 +17,7 @@ SRC_URI = " \ file://run-ptest \ file://CVE-2026-10098-1.patch \ file://CVE-2026-10098-2.patch \ + file://CVE-2026-10512.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:07 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97490 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 A128EC79FA7 for ; Mon, 7 Sep 2026 10:24:39 +0000 (UTC) Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31705.1788776672481622207 for ; Mon, 07 Sep 2026 03:24:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=kAUWFXLP; spf=pass (domain: gmail.com, ip: 209.85.214.178, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-2d5335cf904so32741005ad.2 for ; Mon, 07 Sep 2026 03:24:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776672; x=1789381472; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=DaUz7eGZUstvPyAv7Q8oSHcEzEsvpIuLpOqg0brqCcY=; b=kAUWFXLPCytvyoEwkPkqXTfQ/wgN5fRsIB7qusrKgkfWCoDOcK6HgJZZo5O8CYjdQU DrxSWHbQoJOgQ+cQ9A7RHO6BRkigYbu2uZaScYN8Ww8vixDtE+HMX65P5DShVbKnSIGK GKD8i+WfX2Zc6MATlSG6NbHswfPtK+Kl7aGPkHmlFsU8Z9tDncOOyNa8/rctld8sd5iW g48XKrcsJ0r0FGvU5CT/uLXftvFhrRP4D0Fdq6r8siwh2zXREnoOs0nNOZRnC7/4tnSX XpWQrz9unYwoYa75TBgxh5OxN40JmHmfV4OKvczxSPCUdIiDnrATauE3vs6l/qe9v2C7 LDFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776672; x=1789381472; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=DaUz7eGZUstvPyAv7Q8oSHcEzEsvpIuLpOqg0brqCcY=; b=J/SdlJH0sjmTxbjY5Lb9tpF6XwTAJjzEj5vGpPlDqsswwXWz6exSilplHv3bfqYHNZ 0mBgZtXXU0/2lPAv1eB/B616WOeurIFzB5MG+JDw2M9N8SOEyemxeQFzn+9MklEAuJGI UV6Nv7slKD4nNqN1lf9SSDNln4wCUMOlrUjYvwwIT5p8Y2sBHTzCyQjc1LalfzpEyUA2 YOu0QiMeo0x9FBxiLpmC91TvQ1oUHV5yfboe6dI4ml7mV8yC25H3IKEtls/RsxqVzcvN nReVxfE7DSB/gdzSUGT4jhAUNAjeANEpwlGkmHWJi78PFp8nzMyxtlgWqv6mwmYpt4Qv FNBA== X-Gm-Message-State: AFuF++lESB3Qo92hMxtR1fkxVgw4QyGBXlr9xsBgGceWyUxeS7O8FDYq LLCcxGd+VNjPlvhP5axnVxSFKbgaaM8rvx6kZbAsFSxAvRAJorSCL5I2MpB+B/sb X-Gm-Gg: AYBFou2u+MD1gR8FtzmP/iEplIftDCs9fL+aK+BzNo3SB7/VwB/BvaVmBDweA+FvG0i 0VcssjaRUSUjgG9AkfFhLlS2Fs0m17VMfCwsSOXuadIWrh3UwXNV7zVawtGyD+lGzUA5b/c+SYA VvTmr/eR+lNlAa2VL+maPpgSrze2fNfH0dv3NGfwHZ3xaQsN/+E8DCEBiI6mDROysDmrfnMChjO aYTf5XzEBJIKUBjkemtoQ0ZLLpmHSGoOLYYiZPsr4gIgjjIk8bKRy1WVNvSIwYdu2RcjSjhkdXE b9JePG9uiWjZSBVhinLLnajA0lV6ZulL23B61b9BeVEwiDrlbXDejERDCJ6O20Aa8/2czYU1uDz ZRASvReO+M8DpL7QdV8tYDcvnZfdo7MoQjkKpfHIWGq4J0RPI0mzPZm92O78RbG3TCaMzA9r2Xi 28IyMCXu+Mebk8YmH8vb9yC4lHgm091ynFJ1Scg+vIzwL7En/hyIsUf0d4zA/P/3NrjW8N3hAp X-Received: by 2002:a17:90b:2b43:b0:38e:c7b0:84ad with SMTP id 98e67ed59e1d1-39b25ed34f3mr38494247a91.0.1788776671853; Mon, 07 Sep 2026 03:24:31 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:31 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 23/33] wolfssl: ignore CVE-2026-12340 Date: Mon, 7 Sep 2026 22:23:07 +1200 Message-ID: <20260907102318.2459883-23-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129835 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-12340 Signed-off-by: Ankur Tyagi --- meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 4f6ae56567..f69497a80c 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -74,3 +74,4 @@ CVE_STATUS[CVE-2026-5772] = "fixed-version: fixed in 5.9.1" CVE_STATUS[CVE-2026-5778] = "fixed-version: fixed in 5.9.1" CVE_STATUS[CVE-2023-6937] = "fixed-version: fixed since v5.6.6" CVE_STATUS[CVE-2024-5814] = "fixed-version: fixed since v5.7.2" +CVE_STATUS[CVE-2026-12340] = "not-applicable-config: this only affects builds with SM2 support" From patchwork Mon Sep 7 10:23:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97489 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 8FD27C79F99 for ; Mon, 7 Sep 2026 10:24:39 +0000 (UTC) Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31928.1788776675262656263 for ; Mon, 07 Sep 2026 03:24:35 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=Zp7cTd5s; spf=pass (domain: gmail.com, ip: 209.85.215.179, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-cc1b838f9b6so3691654a12.3 for ; Mon, 07 Sep 2026 03:24:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776675; x=1789381475; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OuBhiL2fLTIddje9rQ5MiwRSJdwzNTSYWjBUVmncH2s=; b=Zp7cTd5sjt7upYA3I+FMeb0lv1kRG9jGa2iB6jQLqqqt3vrAaEzjr+8C0VtEIlnDtD scPfWURt2np74HWxonGXJyPuqEa8DIlxN808Qm87BgDY/s4GqystoAvi9KfEAqjuDcHh xdbQX7FgQQY37QVwFVryfp5rdTtW/0VT0RU/DWO4P6QtKcNqpRfrNVBmLQlNBcw0jzZY ihWDp1d2HWMJBmsjMnHZbvK7bBnxUXf9uGnX5UKub926nKX6MLVfYGvehcdn9gfKnHQU DB3dG5oYkM6hp6jN65y+xwUXfu/81gSU0MuoUFWGfMkcKTqQo8Wm6DXu63So3KX+lzwN CFFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776675; x=1789381475; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OuBhiL2fLTIddje9rQ5MiwRSJdwzNTSYWjBUVmncH2s=; b=BMafR9e9DLwATFAMvB/U4bFNhdFD6iYpExSU1eGoIP7/zkeW2VRqIwM40G1g590iz+ c1yvA7zfuuZoPO/dKtbLlc50qpNVKN03mocZOmylPOk2qJWmlAk8V3pueV2AuGUaZw4z tC6jQePAzjReVpo5NZX7miztVLGg32qxOHP+7Jhypq/6SA60ZckJ6SYwgWvV2Pu6+5kX lXRs9AtYdDg2HFebkNVoLKSGpyLRq8FsQKec/oJInlbUDV+8AMfMrOjM9ggQFZAhuGyR Ab/jIEOTv9M8Uk/D7us1lPL+8M8XKdOGkrENowkT2J2ph/CJ3OAdrCqYwxf4kLG3wxHQ acfw== X-Gm-Message-State: AFuF++nHhLLXdI3SRWRzhowB3X44MlB9Zh13AbYZd2tXgvi5NVUNusMl yneBwHBkybRpdow5LLhhEZ8ZyK4NCUOJ00eHCmYh/0nHpYkFnwXzhEUp50U5xPxh X-Gm-Gg: AYBFou14nLY/8seT+fwbeJE552anOzIi0quTNbAivZyreU6UPN5nTQlmAxm+n2i+IV/ mRIDz8x1S4ZLWCZzWpQq6eAkuUgZtNhAdBtkedSrsf0m4w7osFtvQSxBs0SC3K62ggULKNhjRnl uAFmTezC4TVa/i+ZXrQi5I/n4Vl8ioWV+8DhC/yFzgObiERVVXMbc+uPm7F/YzVbe4dXMlz3TaW QGuFrG+kqNGbjyvs7+nUIWt+7skGwW/VhAc3M5DD6RMrW8FPe6IGP69G8UuEYT4BfyQ0hbB/NMM QqKUcnZIra8EV+L72dpvR0sjlP/BQXUkMN8Mgskg5m23O/fbYkDWEIJgrCyRo5JWgZ1CNUV358r zY400qizCx7int1DepiiiYFHwGNstdsTTdXFu3kLQYhT96bb0nsTtx6lYKG/BpWUr/+ZHIXOC7s XwEll/XV7176nECn3vQepplpzTsH3Pf8GDmENqsFn61C20AFg0hqjIBvgFnxw340yaLXlahMUh X-Received: by 2002:a05:6a20:2d26:b0:3d3:adad:f174 with SMTP id adf61e73a8af0-3da3a0a918dmr36395210637.22.1788776674516; Mon, 07 Sep 2026 03:24:34 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:34 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 24/33] wolfssl: patch CVE-2026-55958 Date: Mon, 7 Sep 2026 22:23:08 +1200 Message-ID: <20260907102318.2459883-24-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129836 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-55958 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-55958.patch | 36 +++++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 1 + 2 files changed, 37 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-55958.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-55958.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-55958.patch new file mode 100644 index 0000000000..a1f77eb40f --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-55958.patch @@ -0,0 +1,36 @@ +From ea7c289d463c506fe3eb856c5d128b7d0e1799b7 Mon Sep 17 00:00:00 2001 +From: Chris Conlon +Date: Tue, 16 Jun 2026 13:58:52 -0600 +Subject: [PATCH] Renesas TSIP: skip XMEMCPY on MEMORY_E from + tsip_StoreMessage() + +(cherry picked from commit 6ebc379f313769ac49a84be0221c626162ffcfab) + +CVE: CVE-2026-55958 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/6ebc379f313769ac49a84be0221c626162ffcfab] + +Signed-off-by: Ankur Tyagi +--- + wolfcrypt/src/port/Renesas/renesas_tsip_sha.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c b/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c +index 0d5957744..d04072397 100644 +--- a/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c ++++ b/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c +@@ -203,10 +203,11 @@ WOLFSSL_LOCAL int tsip_StoreMessage(struct WOLFSSL* ssl, const byte* data, + WOLFSSL_MSG("Capacity over error in tsip_StoreMessage"); + ret = MEMORY_E; + } +- +- XMEMCPY(bag->buff + bag->buffIdx, data, sz); +- bag->msgTypes[bag->msgIdx++] = *data; /* store message type */ +- bag->buffIdx += sz; ++ else { ++ XMEMCPY(bag->buff + bag->buffIdx, data, sz); ++ bag->msgTypes[bag->msgIdx++] = *data; /* store message type */ ++ bag->buffIdx += sz; ++ } + } + + WOLFSSL_LEAVE("tsip_StoreMessage", ret); diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index f69497a80c..e2bb53a646 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -18,6 +18,7 @@ SRC_URI = " \ file://CVE-2026-10098-1.patch \ file://CVE-2026-10098-2.patch \ file://CVE-2026-10512.patch \ + file://CVE-2026-55958.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97492 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 9638DC79F9E for ; Mon, 7 Sep 2026 10:24:39 +0000 (UTC) Received: from mail-pj1-f52.google.com (mail-pj1-f52.google.com [209.85.216.52]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31708.1788776678320320513 for ; Mon, 07 Sep 2026 03:24:38 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=R1+iEX4n; spf=pass (domain: gmail.com, ip: 209.85.216.52, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f52.google.com with SMTP id 98e67ed59e1d1-38d489b6b71so3898486a91.0 for ; Mon, 07 Sep 2026 03:24:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776678; x=1789381478; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Cr9wcImjSA5SstHSdqZ391WKyH+6CGibg+RQ8cwlIb8=; b=R1+iEX4nGl556MWHky9gQF8anBV4nFb68fPBFhiUQg7z2gYTubfZaxrRiJBNi33sI7 rmJGmA0nkgxdQvBBQw9QdhrZA7fbg/3o36V1C3065lnKIwsZ6/dxRfMLvmsh1ZfoGKUj pP35ldxOY9jrxf4Qmlb0v2YRwlNRz3kS4WqQIFlDaiTBnzmKXo3FNV83ebuelg/qv/Ca GXre3f0OtMlPCYs7/ypkGe0JEb0zB7yGl9TJaB72r3Tcg8C8Vq5kjkSyrSLA2cRrvYWO mbcGfga8qXuKIkgd/5Y9LYhOJsug4jUVPO0/F8FozW7nhGe4KrXnI/qmkOgeBKRHmpL2 2Lyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776678; x=1789381478; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Cr9wcImjSA5SstHSdqZ391WKyH+6CGibg+RQ8cwlIb8=; b=Ou5wZHgH1ssSdR3/S9y+y+1dDWNCoOn7SGIbfCg0lKU7neNImmsyJBC2EyCp2Tm7n1 nVuU1IXhqs4/NSu5LlOyaS+4jadTwc2wgarleh6gTIc4mRAVIC7vnDFKVvdx/92KJ/9X 9rKDxcjuti0WiFdANzuyeYW4EfeZJcIf+arAWr9/R6Dfl4gZXGykytyKCgQC4buuMiYW aSZtdeK94SlX5jH/gp6ti3J6RlxSAIKW80UORzye7O9Cbrw9ely4hYFde1DywH2Wy/Qd OjbCbr83uA8dptVfqXaE61NJVyjF8iO//f+rfnYLymKwMLXlC3bYGSLu17/QLUS+iuYz yNvw== X-Gm-Message-State: AFuF++mh+QbPHWQ6xoJtLaKI+b3cEEh0L00oDQP9teFkRv2xhwcwaeB9 h3iavQnexlMknTHPMTbXKtlXpeSIfUK4NydjMcxgS7aGtCD42ck34Ae8wU5xOBMB X-Gm-Gg: AYBFou0RfpCkhB+3K9evjOnw5k+j0+rcPZX6Z7nN0sVhknJ/8UZ6FtizHoL8i/Qo3ac kvQu7XQPJeFhFyqpYB+hR8qwHDVHB4VEkIYMSdJFCd1yUWLlQTYmXm9SJcb+mvuo67ytdASL4dq GoD/ER/qjAmcOE/TjNqw5lLJE9ncPqs6CunWqqgvh0IBjZkNmLetWpPXN/BEu7T5fqaugNgVCAg n8T8h428ZC3sLvNED9ERmROf+NS4wbFLFXJJ/vHIwQVCrl0ohvAgoBUOqObEha/kleZ3Krf6OQa CQZJiAKx0cQ2iZdcAgFgwrMOXLjtdIgZrcwAe94YdxQKrwcQVToL0vUqma7Ee2Z1SMNaowuzo4n OjUUuUfzZMWHiMOItpSVLIouwLu+1f6vmEVBt+FwIeoK5tVmCJYDweNPZFmTx+tSHt/Y7fhEZ0m ByEQURaXzHTQip9Pev3eVAokaXoGoKyAKHVOn4KhydGLbn9m/XQzZiORtX1/dac9GOlrBKE/zj X-Received: by 2002:a17:90b:28ce:b0:38d:fda6:4873 with SMTP id 98e67ed59e1d1-39b26100cbfmr35688511a91.10.1788776677434; Mon, 07 Sep 2026 03:24:37 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:37 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 25/33] wolfssl: patch CVE-2026-6091 Date: Mon, 7 Sep 2026 22:23:09 +1200 Message-ID: <20260907102318.2459883-25-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129837 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-6091 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-6091-1.patch | 295 ++++++++++++++++++ .../wolfssl/files/CVE-2026-6091-2.patch | 30 ++ .../wolfssl/files/CVE-2026-6091-3.patch | 36 +++ .../wolfssl/wolfssl_5.9.1.bb | 3 + 4 files changed, 364 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-1.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-2.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-3.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-1.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-1.patch new file mode 100644 index 0000000000..644797266e --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-1.patch @@ -0,0 +1,295 @@ +From 54bce5dd1dce8839ea64e0bddebe4c6f8fd2cc6c Mon Sep 17 00:00:00 2001 +From: Eric Blankenhorn +Date: Wed, 8 Apr 2026 16:27:07 -0500 +Subject: [PATCH] Fix partial chain verification + +(cherry picked from commit a6fd25b94e0c03c1be265a4454390d7225e81129) + +CVE: CVE-2026-6091 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/a6fd25b94e0c03c1be265a4454390d7225e81129] + +Signed-off-by: Ankur Tyagi +--- + src/x509_str.c | 90 ++++++++++++++++++++++- + tests/api/test_ossl_x509_str.c | 127 +++++++++++++++++++++++++++++++++ + 2 files changed, 216 insertions(+), 1 deletion(-) + +diff --git a/src/x509_str.c b/src/x509_str.c +index 90113caed..01e975198 100644 +--- a/src/x509_str.c ++++ b/src/x509_str.c +@@ -552,6 +552,53 @@ static int X509VerifyCertSetupRetry(WOLFSSL_X509_STORE_CTX* ctx, + return ret; + } + ++/* Returns 1 if cur and x509 have identical DER encodings, 0 otherwise. */ ++static int X509DerEquals(WOLFSSL_X509* cur, WOLFSSL_X509* x509) ++{ ++ if (cur == NULL || cur->derCert == NULL || ++ x509 == NULL || x509->derCert == NULL) { ++ return 0; ++ } ++ if (cur->derCert->length != x509->derCert->length) ++ return 0; ++ return XMEMCMP(cur->derCert->buffer, x509->derCert->buffer, ++ x509->derCert->length) == 0; ++} ++ ++/* Returns 1 if x509's DER matches an entry in either origTrustedSk (an ++ * immutable snapshot of the caller's trusted set captured before any ++ * intermediates were injected for this verification call) or in ++ * store->trusted. Returns 0 otherwise. Used by the ++ * X509_V_FLAG_PARTIAL_CHAIN fallback to confirm that a chain actually ++ * terminates at a caller-trusted certificate. */ ++static int X509StoreCertIsTrusted(WOLFSSL_X509_STORE* store, ++ WOLFSSL_X509* x509, WOLF_STACK_OF(WOLFSSL_X509)* origTrustedSk) ++{ ++ int i; ++ int n; ++ ++ if (x509 == NULL || x509->derCert == NULL) ++ return 0; ++ ++ if (origTrustedSk != NULL) { ++ n = wolfSSL_sk_X509_num(origTrustedSk); ++ for (i = 0; i < n; i++) { ++ if (X509DerEquals(wolfSSL_sk_X509_value(origTrustedSk, i), x509)) ++ return 1; ++ } ++ } ++ ++ if (store != NULL && store->trusted != NULL) { ++ n = wolfSSL_sk_X509_num(store->trusted); ++ for (i = 0; i < n; i++) { ++ if (X509DerEquals(wolfSSL_sk_X509_value(store->trusted, i), x509)) ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ + /* Verifies certificate chain using WOLFSSL_X509_STORE_CTX + * returns 1 on success or <= 0 on failure. + */ +@@ -570,6 +617,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) + WOLF_STACK_OF(WOLFSSL_X509)* certs = NULL; + WOLF_STACK_OF(WOLFSSL_X509)* certsToUse = NULL; + WOLF_STACK_OF(WOLFSSL_X509)* failedCerts = NULL; ++ WOLF_STACK_OF(WOLFSSL_X509)* origTrustedSk = NULL; + WOLFSSL_ENTER("wolfSSL_X509_verify_cert"); + + if (ctx == NULL || ctx->store == NULL || ctx->store->cm == NULL +@@ -586,9 +634,37 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) + if (certs == NULL && + wolfSSL_sk_X509_num(ctx->ctxIntermediates) > 0) { + certsToUse = wolfSSL_sk_X509_new_null(); ++ if (certsToUse == NULL) { ++ ret = WOLFSSL_FAILURE; ++ goto exit; ++ } + ret = addAllButSelfSigned(certsToUse, ctx->ctxIntermediates, NULL); ++ /* certsToUse holds only injected intermediates, none are trusted, so ++ * leave origTrustedSk NULL (empty snapshot). */ ++ certs = certsToUse; + } + else { ++ /* Snapshot the caller-trusted entries before injecting the ++ * caller-supplied untrusted intermediates. Only the entries already ++ * present count as trusted for the partial-chain check below, and ++ * we need a stable reference because X509VerifyCertSetupRetry may ++ * remove nodes from `certs` during chain building. */ ++ if (certs != NULL && wolfSSL_sk_X509_num(certs) > 0) { ++ int j; ++ int n = wolfSSL_sk_X509_num(certs); ++ origTrustedSk = wolfSSL_sk_X509_new_null(); ++ if (origTrustedSk == NULL) { ++ ret = WOLFSSL_FAILURE; ++ goto exit; ++ } ++ for (j = 0; j < n; j++) { ++ if (wolfSSL_sk_X509_push(origTrustedSk, ++ wolfSSL_sk_X509_value(certs, j)) <= 0) { ++ ret = WOLFSSL_FAILURE; ++ goto exit; ++ } ++ } ++ } + /* Add the intermediates provided on init to the list of untrusted + * intermediates to be used */ + ret = addAllButSelfSigned(certs, ctx->ctxIntermediates, &numInterAdd); +@@ -677,9 +753,17 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) + * a trusted CA in the CM */ + ret = X509StoreVerifyCert(ctx); + if (ret != WOLFSSL_SUCCESS) { ++ /* WOLFSSL_PARTIAL_CHAIN may only terminate the chain at a ++ * certificate the caller actually trusts. The previous ++ * "added == 1" guard merely confirmed that some untrusted ++ * intermediate had been temporarily loaded into the ++ * CertManager during chain building, which would accept ++ * chains that never reach a trust anchor. Verify that ++ * ctx->current_cert is itself in the original trust set. */ + if (((ctx->flags & WOLFSSL_PARTIAL_CHAIN) || + (ctx->store->param->flags & WOLFSSL_PARTIAL_CHAIN)) && +- (added == 1)) { ++ X509StoreCertIsTrusted(ctx->store, ctx->current_cert, ++ origTrustedSk)) { + wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert); + ret = WOLFSSL_SUCCESS; + } else { +@@ -749,6 +833,10 @@ exit: + if (certsToUse != NULL) { + wolfSSL_sk_X509_free(certsToUse); + } ++ if (origTrustedSk != NULL) { ++ /* Shallow free: only the snapshot's stack nodes, not the X509s. */ ++ wolfSSL_sk_X509_free(origTrustedSk); ++ } + + /* Enforce hostname / IP verification from X509_VERIFY_PARAM if set. + * Always check against the leaf (end-entity) certificate, captured in +diff --git a/tests/api/test_ossl_x509_str.c b/tests/api/test_ossl_x509_str.c +index 99b82877c..01ed9edfb 100644 +--- a/tests/api/test_ossl_x509_str.c ++++ b/tests/api/test_ossl_x509_str.c +@@ -785,6 +785,127 @@ static int test_wolfSSL_X509_STORE_CTX_ex11(X509_STORE_test_data *testData) + return EXPECT_RESULT(); + } + ++static int test_wolfSSL_X509_STORE_CTX_ex_partial_chain_neg( ++ X509_STORE_test_data *testData) ++{ ++ EXPECT_DECLS; ++ X509_STORE* store = NULL; ++ X509_STORE_CTX* ctx = NULL; ++ STACK_OF(X509)* untrusted = NULL; ++ ++ /* Negative partial-chain test: with X509_V_FLAG_PARTIAL_CHAIN set, the ++ * intermediates are supplied ONLY as untrusted (passed through the ++ * X509_STORE_CTX_init "chain" argument and never added to the store). ++ * No certificate in the chain is in the store, so verification must ++ * fail. Pre-fix, wolfSSL_X509_verify_cert would incorrectly accept ++ * this chain because its partial-chain fallback only checked that some ++ * intermediate had been temporarily loaded into the CertManager, not ++ * that any chain certificate was actually trusted. */ ++ ExpectNotNull(store = X509_STORE_new()); ++ /* Intentionally do NOT add x509CaInt, x509CaInt2, or x509Ca. */ ++ ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN), 1); ++ ++ ExpectNotNull(untrusted = sk_X509_new_null()); ++ ExpectIntGT(sk_X509_push(untrusted, testData->x509CaInt2), 0); ++ ExpectIntGT(sk_X509_push(untrusted, testData->x509CaInt), 0); ++ ++ ExpectNotNull(ctx = X509_STORE_CTX_new()); ++ ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, untrusted), ++ 1); ++ /* Must NOT verify: partial-chain does not relax the trust requirement. */ ++ ExpectIntNE(X509_verify_cert(ctx), 1); ++ /* Verify the failure is specifically due to missing trust anchor, not ++ * some unrelated error. */ ++ ExpectIntEQ(X509_STORE_CTX_get_error(ctx), ++ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); ++ ++ X509_STORE_CTX_free(ctx); ++ X509_STORE_free(store); ++ sk_X509_free(untrusted); ++ return EXPECT_RESULT(); ++} ++ ++static int test_wolfSSL_X509_STORE_CTX_ex_partial_chain_mixed( ++ X509_STORE_test_data *testData) ++{ ++ EXPECT_DECLS; ++ X509_STORE* store = NULL; ++ X509_STORE_CTX* ctx = NULL; ++ STACK_OF(X509)* untrusted = NULL; ++ ++ /* Mixed trusted-store + untrusted-chain partial-chain test: the store ++ * trusts an intermediate (x509CaInt2, the leaf's direct issuer), while ++ * an additional intermediate (x509CaInt) is supplied only as untrusted ++ * via the chain argument. With X509_V_FLAG_PARTIAL_CHAIN, verification ++ * must succeed by terminating at the trusted intermediate. This test ++ * exercises the snapshot-based trust check in X509StoreCertIsTrusted: ++ * the untrusted intermediate injected during verification must not be ++ * treated as a trust anchor, but the intermediate already in the store ++ * must be. */ ++ ExpectNotNull(store = X509_STORE_new()); ++ ExpectIntEQ(X509_STORE_add_cert(store, testData->x509CaInt2), 1); ++ ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN), 1); ++ ++ ExpectNotNull(untrusted = sk_X509_new_null()); ++ ExpectIntGT(sk_X509_push(untrusted, testData->x509CaInt), 0); ++ ++ ExpectNotNull(ctx = X509_STORE_CTX_new()); ++ ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, untrusted), ++ 1); ++ /* Must verify: chain terminates at trusted intermediate in the store. */ ++ ExpectIntEQ(X509_verify_cert(ctx), 1); ++ ++ X509_STORE_CTX_free(ctx); ++ X509_STORE_free(store); ++ sk_X509_free(untrusted); ++ return EXPECT_RESULT(); ++} ++ ++static int test_wolfSSL_X509_STORE_CTX_ex_partial_chain_untrusted_terminal( ++ X509_STORE_test_data *testData) ++{ ++ EXPECT_DECLS; ++ X509_STORE* store = NULL; ++ X509_STORE_CTX* ctx = NULL; ++ STACK_OF(X509)* untrusted = NULL; ++ ++ /* Partial-chain boundary test: the store trusts a CA (x509Ca) that is ++ * NOT reachable from the leaf given the supplied untrusted intermediates, ++ * and an untrusted intermediate (x509CaInt2) IS the terminal of the ++ * (truncated) chain. With X509_V_FLAG_PARTIAL_CHAIN set, verification ++ * must FAIL because the chain terminates at an untrusted certificate. ++ * ++ * This test specifically targets the snapshot-based trust check in ++ * X509StoreCertIsTrusted. Before addAllButSelfSigned injects ++ * x509CaInt2, origTrustedSk is snapshotted from the caller-trusted set ++ * and contains only x509Ca. When the chain terminates at x509CaInt2, ++ * the trust check consults origTrustedSk (not the mutated working ++ * stack) and correctly finds no match. A regression that consulted ++ * the post-injection working stack instead of the snapshot would ++ * incorrectly mark x509CaInt2 as trusted and cause verification to ++ * succeed. */ ++ ExpectNotNull(store = X509_STORE_new()); ++ ExpectIntEQ(X509_STORE_add_cert(store, testData->x509Ca), 1); ++ ExpectIntEQ(X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN), 1); ++ ++ /* Only x509CaInt2 supplied as untrusted; x509CaInt is intentionally ++ * withheld so the chain cannot actually reach the trusted x509Ca. */ ++ ExpectNotNull(untrusted = sk_X509_new_null()); ++ ExpectIntGT(sk_X509_push(untrusted, testData->x509CaInt2), 0); ++ ++ ExpectNotNull(ctx = X509_STORE_CTX_new()); ++ ExpectIntEQ(X509_STORE_CTX_init(ctx, store, testData->x509Leaf, untrusted), ++ 1); ++ /* Must NOT verify: the chain terminal (x509CaInt2) is not in the ++ * original trust set, even though the store is non-empty. */ ++ ExpectIntNE(X509_verify_cert(ctx), 1); ++ ++ X509_STORE_CTX_free(ctx); ++ X509_STORE_free(store); ++ sk_X509_free(untrusted); ++ return EXPECT_RESULT(); ++} ++ + #ifdef HAVE_ECC + static int test_wolfSSL_X509_STORE_CTX_ex12(void) + { +@@ -870,6 +991,12 @@ int test_wolfSSL_X509_STORE_CTX_ex(void) + ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex9(&testData), 1); + ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex10(&testData), 1); + ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex11(&testData), 1); ++ ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex_partial_chain_neg(&testData), 1); ++ ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex_partial_chain_mixed(&testData), ++ 1); ++ ExpectIntEQ( ++ test_wolfSSL_X509_STORE_CTX_ex_partial_chain_untrusted_terminal( ++ &testData), 1); + #ifdef HAVE_ECC + ExpectIntEQ(test_wolfSSL_X509_STORE_CTX_ex12(), 1); + #endif diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-2.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-2.patch new file mode 100644 index 0000000000..373f942496 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-2.patch @@ -0,0 +1,30 @@ +From 62e57461f512849af4f466f77594085c90ffad73 Mon Sep 17 00:00:00 2001 +From: Eric Blankenhorn +Date: Tue, 14 Apr 2026 07:58:43 -0500 +Subject: [PATCH] Fix from review + +(cherry picked from commit c873f3f77da8273e160612468f08892b2ba0ed99) + +CVE: CVE-2026-6091 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/c873f3f77da8273e160612468f08892b2ba0ed99] + +Signed-off-by: Ankur Tyagi +--- + src/x509_str.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/x509_str.c b/src/x509_str.c +index 01e975198..67e3fcae6 100644 +--- a/src/x509_str.c ++++ b/src/x509_str.c +@@ -765,6 +765,10 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) + X509StoreCertIsTrusted(ctx->store, ctx->current_cert, + origTrustedSk)) { + wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert); ++ /* Clear error set by the failed X509StoreVerifyCert ++ * attempt; the partial-chain fallback accepted the ++ * chain at a caller-trusted certificate. */ ++ ctx->error = 0; + ret = WOLFSSL_SUCCESS; + } else { + X509VerifyCertSetupRetry(ctx, certs, failedCerts, diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-3.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-3.patch new file mode 100644 index 0000000000..418e45fc13 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6091-3.patch @@ -0,0 +1,36 @@ +From 13c4a12c9904a2e50d1729d8a6899f111f3bcd2a Mon Sep 17 00:00:00 2001 +From: Eric Blankenhorn +Date: Tue, 14 Apr 2026 07:41:30 -0500 +Subject: [PATCH] Fix from review + +(cherry picked from commit 2b503dae543d09c63a08b1e24238e0e9ce1ac6c5) + +CVE: CVE-2026-6091 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/2b503dae543d09c63a08b1e24238e0e9ce1ac6c5] + +Signed-off-by: Ankur Tyagi +--- + tests/api/test_ossl_x509_str.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tests/api/test_ossl_x509_str.c b/tests/api/test_ossl_x509_str.c +index 01ed9edfb..14f3538a4 100644 +--- a/tests/api/test_ossl_x509_str.c ++++ b/tests/api/test_ossl_x509_str.c +@@ -854,6 +854,7 @@ static int test_wolfSSL_X509_STORE_CTX_ex_partial_chain_mixed( + 1); + /* Must verify: chain terminates at trusted intermediate in the store. */ + ExpectIntEQ(X509_verify_cert(ctx), 1); ++ ExpectIntEQ(X509_STORE_CTX_get_error(ctx), X509_V_OK); + + X509_STORE_CTX_free(ctx); + X509_STORE_free(store); +@@ -899,6 +900,8 @@ static int test_wolfSSL_X509_STORE_CTX_ex_partial_chain_untrusted_terminal( + /* Must NOT verify: the chain terminal (x509CaInt2) is not in the + * original trust set, even though the store is non-empty. */ + ExpectIntNE(X509_verify_cert(ctx), 1); ++ ExpectIntEQ(X509_STORE_CTX_get_error(ctx), ++ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); + + X509_STORE_CTX_free(ctx); + X509_STORE_free(store); diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index e2bb53a646..139d73c572 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -19,6 +19,9 @@ SRC_URI = " \ file://CVE-2026-10098-2.patch \ file://CVE-2026-10512.patch \ file://CVE-2026-55958.patch \ + file://CVE-2026-6091-1.patch \ + file://CVE-2026-6091-2.patch \ + file://CVE-2026-6091-3.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:10 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97494 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 CFCB5C79F89 for ; Mon, 7 Sep 2026 10:24:49 +0000 (UTC) Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31709.1788776681128070407 for ; Mon, 07 Sep 2026 03:24:41 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=BJF/c4+f; spf=pass (domain: gmail.com, ip: 209.85.215.170, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-cc1c3d79b9bso2417198a12.3 for ; Mon, 07 Sep 2026 03:24:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776680; x=1789381480; darn=lists.openembedded.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=/uaoDC/Eotzbq81q9Prg8lzbDhgg4CMNuyUCblR5jPQ=; b=BJF/c4+fcIR05aQqCokE4Q4IsG+czoZxIzMuqIgkrLfvpfL33NLS04JBNuA4I8gz1W nZownjnxxpzR+flKoSO6EfwbQEj2zaOm4xCOwG7ExylNAOqTMqfuFNI55VOAG3lRCV5I QdlzYQskl0zP9uivX3IxKCXHr5J6U2izvQcOvB9bVP3EobpLRbCVfV80G9eqWcF1uXvY hX+3OxLetzOO0H4+EyvqV61k9aLhq1OwhF/K9uOrmOmZb7IDjHTUwyaJ9wfsCW2zcIOq o0jWOu0mNPFkpLOtZJ5OJf/DZ9Qk35mMFaCnBdc+6GHfRFg2JSBgeh+8pMqRJThueIk3 OiGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776680; x=1789381480; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=/uaoDC/Eotzbq81q9Prg8lzbDhgg4CMNuyUCblR5jPQ=; b=Fnczkla8s98Je2mUU8yWT9rjeT7qRJABbB0GY+NOBGyUrbWmZQcab0kiFImPxm3Kf7 k/YIzYT4e8re3mPWmV7oVBSobgYwgIqoudN5Uv2b2qpKz2Pvs3oJgmdzi8fW05LfGFLC jfBy/kwok00ACuGo+S1Kqj11uPvP2Apv9Gsbt3CchkDcjGvgnoB5yQnZ1cHYx0RI7G4t l6x6CXEQSvkDipLv461wsnRzWbXyQx6TTufmdvPciruoPtPr2tsbml+FN3TpLMrHocbJ tMRCrf1tnUvYh449XwQoNxxImkdX5XpIX47mO4by18lfApDD5tuWq+dO6k92XAKaX772 tGRA== X-Gm-Message-State: AFuF++n9oZ2BnW32fcVdTMd4rYhE0R3iVlIvfZ1keA2aPbKzxKcfafoJ wrTEdlhhgWuUBGkD1amKz6qzBI2Do741I9f2kv//D/oPWzoI9ALgRZNanunH0JIB X-Gm-Gg: AYBFou03EvR5T4erPQMaC2UJNX0AapxNDz7Ua3yIWmwWLU4u5vLPWNmztHiwPlqWfn+ /5U/SYEeWcGg6iptcMARGGyZ74iomukKdEXiOu9ENd/sk3QmHgOOljTcML3FNXT796uy4YIlTNB pX7+4A+ht37ugk7mlBagk1y3O5PGHOcbiixIii5FKxpkkXkTuycEPqXFcjuzOP65ycbwUHLr9oA PJcApWi5GPYNW4g9fOY1359bwc+CcRTno/qcnN3m5AwP5lNeifQFDvY6b8OyjzpaAUeZbXDcZQI rSaxUwta/mKe6qipYceAS++cKUGM0sBb6zuJ0mWRTbdP519BuYQ5qFgnD2wX2g+eugKC0TW12JS whxoL0SV9jCdAwI+3hhG4WrWTxIiDkIR3CGCTQ7TdTlDjYDwJebTl+/eppUaG+JbB6cMjhUTxik t4MpUiC25hQpc5ssghMDRM1RBhRhk8sB/IWv44O5o2hKoEbJ2wFUcmXZVLaW0s8xLOtB8EMAqK X-Received: by 2002:a05:6a21:510:b0:3d3:adbf:777e with SMTP id adf61e73a8af0-3da3a167fb9mr35253516637.19.1788776680378; Mon, 07 Sep 2026 03:24:40 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:40 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 26/33] wolfssl: patch CVE-2026-6092 Date: Mon, 7 Sep 2026 22:23:10 +1200 Message-ID: <20260907102318.2459883-26-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:49 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129838 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-6092 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-6092.patch | 163 ++++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 1 + 2 files changed, 164 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6092.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6092.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6092.patch new file mode 100644 index 0000000000..80868d255e --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6092.patch @@ -0,0 +1,163 @@ +From 5e2fa43aed59a2524c33a443c93445882519677b Mon Sep 17 00:00:00 2001 +From: Eric Blankenhorn +Date: Wed, 8 Apr 2026 15:06:11 -0500 +Subject: [PATCH] Fix ETM on resumption + +(cherry picked from commit af5369636a938faf4a79d1f550d3b206c51fafec) + +CVE: CVE-2026-6092 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/af5369636a938faf4a79d1f550d3b206c51fafec] + +Signed-off-by: Ankur Tyagi +--- + src/internal.c | 20 +++++++---- + tests/api/test_tls.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ + tests/api/test_tls.h | 2 ++ + 3 files changed, 99 insertions(+), 6 deletions(-) + +diff --git a/src/internal.c b/src/internal.c +index ad1587e0f..267c75a5d 100644 +--- a/src/internal.c ++++ b/src/internal.c +@@ -38436,13 +38436,21 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl) + + #if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_ENCRYPT_THEN_MAC) && \ + !defined(WOLFSSL_AEAD_ONLY) +- if (ssl->options.encThenMac && ssl->specs.cipher_type == block) { +- ret = TLSX_EncryptThenMac_Respond(ssl); +- if (ret != 0) +- goto out; ++ /* Only respond to ETM here when resumption actually succeeded; ++ * HandleTlsResumption populates ssl->specs via SetCipherSpecs only ++ * on the success path. If resumption failed, resuming has been ++ * cleared and ssl->specs.cipher_type is still zero-initialized, ++ * so we must defer the ETM decision until after MatchSuite. */ ++ if (ssl->options.resuming) { ++ if (ssl->options.encThenMac && ++ ssl->specs.cipher_type == block) { ++ ret = TLSX_EncryptThenMac_Respond(ssl); ++ if (ret != 0) ++ goto out; ++ } ++ else ++ ssl->options.encThenMac = 0; + } +- else +- ssl->options.encThenMac = 0; + #endif + if (ssl->options.clientState == CLIENT_KEYEXCHANGE_COMPLETE) { + WOLFSSL_LEAVE("DoClientHello", ret); +diff --git a/tests/api/test_tls.c b/tests/api/test_tls.c +index 565006171..f6cbb6d38 100644 +--- a/tests/api/test_tls.c ++++ b/tests/api/test_tls.c +@@ -730,6 +730,89 @@ int test_tls12_no_null_compression(void) + * uppercase names like "SECP384R1" do not match the lowercase "secp384r1" + * entry; they fall through to the wolfCrypt ECC look-up which uses + * XSTRCASECMP. */ ++/* Regression test for the encrypt-then-MAC silent-disable bug. ++ * ++ * Before the fix, when a client sent a 32-byte session ID in its ClientHello ++ * (so the server set ssl->options.resuming = 1) but the server's session ++ * cache did not contain that session, DoClientHello would run an ++ * encrypt_then_mac decision *before* MatchSuite/SetCipherSpecs had populated ++ * ssl->specs.cipher_type. Because cipher_type was zero-initialized ++ * (== stream, not block), the ETM block cleared encThenMac to 0, and the ++ * post-MatchSuite block could not re-enable it. The connection then ++ * silently negotiated MAC-then-encrypt instead of encrypt-then-MAC. ++ * ++ * This test forces a stale-resumption ClientHello against a server with an ++ * empty session cache, using a CBC-mode cipher suite, and asserts that the ++ * server still negotiates encrypt-then-MAC. */ ++int test_tls12_etm_failed_resumption(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \ ++ !defined(WOLFSSL_NO_TLS12) && defined(HAVE_ENCRYPT_THEN_MAC) && \ ++ !defined(WOLFSSL_AEAD_ONLY) && !defined(NO_RSA) && !defined(NO_AES) && \ ++ defined(HAVE_AES_CBC) && !defined(NO_SHA256) && \ ++ defined(HAVE_SESSION_TICKET) && defined(HAVE_ECC) ++ /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 — a CBC suite, where ETM applies. */ ++ const char* cbcSuite = "ECDHE-RSA-AES128-SHA256"; ++ WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; ++ WOLFSSL *ssl_c = NULL, *ssl_s = NULL; ++ WOLFSSL_SESSION *sess = NULL; ++ struct test_memio_ctx test_ctx; ++ ++ /* First handshake: establish a session-ID-based session on the client. ++ * Disable TLS 1.2 session tickets on both sides so resumption uses the ++ * session ID path (not tickets), which is the path the bug lives on. */ ++ XMEMSET(&test_ctx, 0, sizeof(test_ctx)); ++ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, ++ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0); ++ ExpectIntEQ(wolfSSL_NoTicketTLSv12(ssl_c), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_NoTicketTLSv12(ssl_s), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, cbcSuite), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, cbcSuite), WOLFSSL_SUCCESS); ++ ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); ++ /* Sanity: the first handshake itself must use ETM. */ ++ ExpectIntEQ(ssl_s->options.encThenMac, 1); ++ ExpectNotNull(sess = wolfSSL_get1_session(ssl_c)); ++ ++ wolfSSL_free(ssl_c); ssl_c = NULL; ++ wolfSSL_free(ssl_s); ssl_s = NULL; ++ wolfSSL_CTX_free(ctx_c); ctx_c = NULL; ++ wolfSSL_CTX_free(ctx_s); ctx_s = NULL; ++ ++ /* Second handshake against a *fresh* server context (empty cache). The ++ * client offers the saved session, so the server's ClientHello parser ++ * sets options.resuming = 1, but HandleTlsResumption then fails to find ++ * the session and clears resuming. Pre-fix, ETM was silently dropped ++ * here. */ ++ XMEMSET(&test_ctx, 0, sizeof(test_ctx)); ++ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, ++ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0); ++ /* The internal session cache is process-global, so the saved session is ++ * still findable via the cache. Disable lookups on this server SSL ++ * directly so that HandleTlsResumption hits its "session lookup failed" ++ * path — exactly the scenario the bug fix targets. */ ++ ssl_s->options.sessionCacheOff = 1; ++ ExpectIntEQ(wolfSSL_NoTicketTLSv12(ssl_c), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_NoTicketTLSv12(ssl_s), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, cbcSuite), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, cbcSuite), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS); ++ ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); ++ /* The server should NOT have actually resumed (fresh ctx, empty cache). */ ++ ExpectIntEQ(ssl_s->options.resuming, 0); ++ /* And — the regression check — encrypt-then-MAC must still be active. */ ++ ExpectIntEQ(ssl_s->options.encThenMac, 1); ++ ExpectIntEQ(ssl_c->options.encThenMac, 1); ++ ++ wolfSSL_SESSION_free(sess); ++ wolfSSL_free(ssl_c); ++ wolfSSL_free(ssl_s); ++ wolfSSL_CTX_free(ctx_c); ++ wolfSSL_CTX_free(ctx_s); ++#endif ++ return EXPECT_RESULT(); ++} ++ + int test_tls_set_curves_list_ecc_fallback(void) + { + EXPECT_DECLS; +diff --git a/tests/api/test_tls.h b/tests/api/test_tls.h +index 46d540434..9d28a599a 100644 +--- a/tests/api/test_tls.h ++++ b/tests/api/test_tls.h +@@ -30,6 +30,7 @@ int test_tls13_curve_intersection(void); + int test_tls_certreq_order(void); + int test_tls12_bad_cv_sig_alg(void); + int test_tls12_no_null_compression(void); ++int test_tls12_etm_failed_resumption(void); + int test_tls_set_curves_list_ecc_fallback(void); + + #define TEST_TLS_DECLS \ +@@ -41,6 +42,7 @@ int test_tls_set_curves_list_ecc_fallback(void); + TEST_DECL_GROUP("tls", test_tls_certreq_order), \ + TEST_DECL_GROUP("tls", test_tls12_bad_cv_sig_alg), \ + TEST_DECL_GROUP("tls", test_tls12_no_null_compression), \ ++ TEST_DECL_GROUP("tls", test_tls12_etm_failed_resumption), \ + TEST_DECL_GROUP("tls", test_tls_set_curves_list_ecc_fallback) + + #endif /* TESTS_API_TEST_TLS_H */ diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 139d73c572..ce3839e9a2 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -22,6 +22,7 @@ SRC_URI = " \ file://CVE-2026-6091-1.patch \ file://CVE-2026-6091-2.patch \ file://CVE-2026-6091-3.patch \ + file://CVE-2026-6092.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97493 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 BD7F5C79F9F for ; Mon, 7 Sep 2026 10:24:49 +0000 (UTC) Received: from mail-ot1-f51.google.com (mail-ot1-f51.google.com [209.85.210.51]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31931.1788776684425673340 for ; Mon, 07 Sep 2026 03:24:44 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=DxW/yT3W; spf=pass (domain: gmail.com, ip: 209.85.210.51, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-ot1-f51.google.com with SMTP id 46e09a7af769-7f0167e59a3so2285115a34.0 for ; Mon, 07 Sep 2026 03:24:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776683; x=1789381483; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=sh5dHMOiqpi5SSfO8YOnCXhGP3wDVWtZr3JBczcmXm0=; b=DxW/yT3WGpQ1c8P3mQOweULM3psK7qXte6dwxNoch1B6qO1/3+ORid7RAX43HXQooR HlMWNgEImtPQlDF4baIbzX3uhlHKbR4Mdp3Jz0e9aoXrqGoa1iTuqnX2dtoRwuGhTqcO E1v6i6tyk3KLOw+G3k0dcbSVfKiwDEY5xAhJIkuv7vdbiAPhztQPMAILS1Hf2vVAcB7G pcpRzr1dzg6JdYnu7U4cYapDFp0XoZ6A3lheIJXGMIYrtMvrOhO83CbHV5tNZ+t0Fdp+ WkRqq+Jm+Qw1FYO8lRtATnUBaBJJoOnUc0QTyCk1Vahp3avnFHyjGAfHmqB5ZcqAywE3 hagw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776683; x=1789381483; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=sh5dHMOiqpi5SSfO8YOnCXhGP3wDVWtZr3JBczcmXm0=; b=RrmV8Iix41HSWznE5711m81PLaMirFXW3f3UHd+xEAFeZDgex6P2BD+4fYg+9JIqFH qp8LH1OBjy46IDXqwvouRK00Eub7SrOee1m5WhzbvWKhyuSMaukZJ0zcZVmFISmybf1D p8ymxN9aSZJj8RHhzWgFioI5u9vYr2VSxmhsO/8iVKJ+EPbAEvUJ1d5dRIrRQm63epnz kgUu8Yq05/IIgt6+0dkO/7sXXaGyfgzxLryHcr4uQfebjoLbHTlRi66iZCcrz7GThoSF WyO3AvSYfvSiY2oUKsONUKLKaJ2tF1zi/tJHs0NCCfSCj6HtkKkb7VUzDrUX3EboPUHZ ttrA== X-Gm-Message-State: AFuF++l+SrGinMz2fgUJj9NnsK9fSwGGLTpPtXd+PpUSrreAGCSzmIQa /UyIo0buQD1ROFCrAYC98HLq9vFAHb+PrBjgspwHXmReikvJWEbdKKdybw7X9dmo X-Gm-Gg: AYBFou2yNw/SF3s4Y0PQ4vPZie9NDUibCy29wmVynGlWxdwJr48WknVwexRV1P45Zur /As/WLnj8KoQ2vPjpjUZGURvXiyL5jlFkE3SYbxR6BS8IGICD1mtAKYKUUogsUlVVF9JFJA3JN8 aAUH+ydoIwyOTLFS8CNsN2yzGnc9DfgdMf63J7pZz2s6QL9j8eDgpLgzJu84RYsN/HRSNSiJ4ar vsXLAKn1n2nwtYwDfKLFVBdqn8VZ0JGwHC5OT/qYXEXNsDrE1AWAnxPYn6ekv7SQWW6twv+PuDn eikAGGYrfu+XoaacoTqAkcGpCAsZ3dVBsMAf4kAhe+xikL5I5c4xipsvbG2Oo/P8BWWZOOAXbuG 6W45gH5PQM6aZNRYUNxRw3+ZQu+scyleozz6KJsghXCbr3iYMeUHiHziTa/d1RlJloICF81SGkH hFe93MiFXI9EHgUu93x2r0JMhosBCn8BLvlizrQdOWbJ99KdDc0zY5NVt4CBaMlQzX/6sHS5Tp X-Received: by 2002:a05:6820:4b94:b0:6b7:8396:f3de with SMTP id 006d021491bc7-6b78396f966mr9379044eaf.64.1788776683362; Mon, 07 Sep 2026 03:24:43 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:42 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 27/33] wolfssl: patch CVE-2026-6094 Date: Mon, 7 Sep 2026 22:23:11 +1200 Message-ID: <20260907102318.2459883-27-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:49 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129839 From: Ankur Tyagi Details https://nvd.nist.gov/vuln/detail/cve-2026-6094 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-6094-1.patch | 32 ++++++++ .../wolfssl/files/CVE-2026-6094-2.patch | 35 +++++++++ .../wolfssl/files/CVE-2026-6094-3.patch | 39 ++++++++++ .../wolfssl/files/CVE-2026-6094-4.patch | 36 +++++++++ .../wolfssl/files/CVE-2026-6094-5.patch | 73 +++++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 5 ++ 6 files changed, 220 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-1.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-2.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-3.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-4.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-5.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-1.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-1.patch new file mode 100644 index 0000000000..c9a7c1867e --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-1.patch @@ -0,0 +1,32 @@ +From f162b7679bafacd5b9866d72400b1115f8fbc7b7 Mon Sep 17 00:00:00 2001 +From: Kareem +Date: Fri, 3 Apr 2026 16:05:44 -0700 +Subject: [PATCH] Ensure esd->signedAttribsCount contains the correct count in + case some are skipped by using the current idx rather than the total array + size. + +Thanks to Zou Dikai for the report. + +(cherry picked from commit 7f218574c4d30a8aa8c520c7023c3d017fc13b86) + +CVE: CVE-2026-6094 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/7f218574c4d30a8aa8c520c7023c3d017fc13b86] + +Signed-off-by: Ankur Tyagi +--- + wolfcrypt/src/pkcs7.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c +index 3f6649d0a..67803f84d 100644 +--- a/wolfcrypt/src/pkcs7.c ++++ b/wolfcrypt/src/pkcs7.c +@@ -2253,7 +2253,7 @@ static int wc_PKCS7_BuildSignedAttributes(wc_PKCS7* pkcs7, ESD* esd, + idx++; + } + +- esd->signedAttribsCount += cannedAttribsCount; ++ esd->signedAttribsCount += idx; + esd->signedAttribsSz += (word32)EncodeAttributes( + &esd->signedAttribs[atrIdx], (int)idx, cannedAttribs, + (int)cannedAttribsCount); diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-2.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-2.patch new file mode 100644 index 0000000000..8df72e6f5b --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-2.patch @@ -0,0 +1,35 @@ +From 6d7fe2926a18982278c53b4ec413fe7b2349a019 Mon Sep 17 00:00:00 2001 +From: Kareem +Date: Fri, 3 Apr 2026 16:06:35 -0700 +Subject: [PATCH] In wc_PKCS7_DecodeEnvelopedData, confirm + encryptedContentTotalSz does not exceed the total message size before using + it in the non-streaming case. + +Thanks to Zou Dikai for the report. + +(cherry picked from commit 1397268aa12e2cf3f80c3acfa9b6036b809c08ef) + +CVE: CVE-2026-6094 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/1397268aa12e2cf3f80c3acfa9b6036b809c08ef] + +Signed-off-by: Ankur Tyagi +--- + wolfcrypt/src/pkcs7.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c +index 67803f84d..43bcf3ee4 100644 +--- a/wolfcrypt/src/pkcs7.c ++++ b/wolfcrypt/src/pkcs7.c +@@ -13231,6 +13231,11 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, + } + wc_PKCS7_DecryptContentFree(pkcs7, encOID, pkcs7->heap); + } else { ++ if ((idx + (word32)encryptedContentTotalSz) > pkiMsgSz) { ++ ret = BUFFER_E; ++ break; ++ } ++ + pkcs7->cachedEncryptedContentSz = + (word32)encryptedContentTotalSz; + pkcs7->totalEncryptedContentSz = diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-3.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-3.patch new file mode 100644 index 0000000000..6e0d902c85 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-3.patch @@ -0,0 +1,39 @@ +From c7f7a8ef00e6a7a33a623543507f8fa089f6037b Mon Sep 17 00:00:00 2001 +From: Kareem +Date: Fri, 3 Apr 2026 16:56:04 -0700 +Subject: [PATCH] Code review feedback + +(cherry picked from commit ebdcc03b718cd7175355097b1a3831a0eb4875b2) + +CVE: CVE-2026-6094 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/ebdcc03b718cd7175355097b1a3831a0eb4875b2] + +Signed-off-by: Ankur Tyagi +--- + wolfcrypt/src/pkcs7.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c +index 43bcf3ee4..50d33bdb8 100644 +--- a/wolfcrypt/src/pkcs7.c ++++ b/wolfcrypt/src/pkcs7.c +@@ -2256,7 +2256,7 @@ static int wc_PKCS7_BuildSignedAttributes(wc_PKCS7* pkcs7, ESD* esd, + esd->signedAttribsCount += idx; + esd->signedAttribsSz += (word32)EncodeAttributes( + &esd->signedAttribs[atrIdx], (int)idx, cannedAttribs, +- (int)cannedAttribsCount); ++ (int)idx); + atrIdx += idx; + } else { + esd->signedAttribsCount = 0; +@@ -13231,7 +13231,9 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, + } + wc_PKCS7_DecryptContentFree(pkcs7, encOID, pkcs7->heap); + } else { +- if ((idx + (word32)encryptedContentTotalSz) > pkiMsgSz) { ++ word32 tmpSum; ++ if (!WC_SAFE_SUM_WORD32(idx, (word32)encryptedContentTotalSz, tmpSum) || ++ tmpSum > pkiMsgSz) { + ret = BUFFER_E; + break; + } diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-4.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-4.patch new file mode 100644 index 0000000000..3c49028ec4 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-4.patch @@ -0,0 +1,36 @@ +From a9015491db03d415f766f47c139841249adce843 Mon Sep 17 00:00:00 2001 +From: Kareem +Date: Mon, 6 Apr 2026 11:58:12 -0700 +Subject: [PATCH] Fix unused variable error + +(cherry picked from commit 3e04475875a4942652fdf6794a01fdfd65801fdc) + +CVE: CVE-2026-6094 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/3e04475875a4942652fdf6794a01fdfd65801fdc] + +Signed-off-by: Ankur Tyagi +--- + wolfcrypt/src/pkcs7.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c +index 50d33bdb8..2cde73846 100644 +--- a/wolfcrypt/src/pkcs7.c ++++ b/wolfcrypt/src/pkcs7.c +@@ -2197,7 +2197,6 @@ static int wc_PKCS7_BuildSignedAttributes(wc_PKCS7* pkcs7, ESD* esd, + #endif + word32 idx = 0; + word32 atrIdx = 0; +- word32 cannedAttribsCount; + + if (pkcs7 == NULL || esd == NULL || contentType == NULL || + contentTypeOid == NULL || messageDigestOid == NULL || +@@ -2220,8 +2219,6 @@ static int wc_PKCS7_BuildSignedAttributes(wc_PKCS7* pkcs7, ESD* esd, + return timeSz; + #endif + +- cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); +- + XMEMSET(&cannedAttribs[idx], 0, sizeof(cannedAttribs[idx])); + + if ((pkcs7->defaultSignedAttribs & WOLFSSL_CONTENT_TYPE_ATTRIBUTE) || diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-5.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-5.patch new file mode 100644 index 0000000000..a0dcd8ce72 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6094-5.patch @@ -0,0 +1,73 @@ +From c27fbdecfd2f4a31acdc73229a5bc631184265f1 Mon Sep 17 00:00:00 2001 +From: Kareem +Date: Mon, 6 Apr 2026 16:41:32 -0700 +Subject: [PATCH] Add additional checks for encryptedContentSz exceeding + pkiMsgSz. + +(cherry picked from commit b3c2877a146e0c75715368ca5dfe2387bfc2cadf) + +CVE: CVE-2026-6094 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/b3c2877a146e0c75715368ca5dfe2387bfc2cadf] + +Signed-off-by: Ankur Tyagi +--- + wolfcrypt/src/pkcs7.c | 38 ++++++++++++++++++++++++++------------ + 1 file changed, 26 insertions(+), 12 deletions(-) + +diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c +index 2cde73846..8df3a2430 100644 +--- a/wolfcrypt/src/pkcs7.c ++++ b/wolfcrypt/src/pkcs7.c +@@ -14380,9 +14380,17 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, + } + + if (ret == 0) { +- XMEMCPY(encryptedContent, &pkiMsg[idx], ++ word32 tmpSum; ++ if (!WC_SAFE_SUM_WORD32(idx, (word32)encryptedContentSz, ++ tmpSum) || ++ tmpSum > pkiMsgSz) { ++ ret = BUFFER_E; ++ break; ++ } else { ++ XMEMCPY(encryptedContent, &pkiMsg[idx], + (word32)encryptedContentSz); +- idx += (word32)encryptedContentSz; ++ idx += (word32)encryptedContentSz; ++ } + } + #ifndef NO_PKCS7_STREAM + pkcs7->stream->bufferPt = encryptedContent; +@@ -15316,16 +15324,22 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, + } + + if (ret == 0) { +- XMEMCPY(encryptedContent, &pkiMsg[idx], +- (unsigned int)encryptedContentSz); +- idx += (word32)encryptedContentSz; +- +- /* decrypt encryptedContent */ +- ret = wc_PKCS7_DecryptContent(pkcs7, encOID, +- pkcs7->encryptionKey, pkcs7->encryptionKeySz, +- tmpIv, expBlockSz, NULL, 0, NULL, 0, +- encryptedContent, encryptedContentSz, +- encryptedContent, pkcs7->devId, pkcs7->heap); ++ word32 tmpSum; ++ if (!WC_SAFE_SUM_WORD32(idx, (word32)encryptedContentSz, tmpSum) || ++ tmpSum > pkiMsgSz) { ++ ret = BUFFER_E; ++ } else { ++ XMEMCPY(encryptedContent, &pkiMsg[idx], ++ (unsigned int)encryptedContentSz); ++ idx += (word32)encryptedContentSz; ++ ++ /* decrypt encryptedContent */ ++ ret = wc_PKCS7_DecryptContent(pkcs7, encOID, ++ pkcs7->encryptionKey, pkcs7->encryptionKeySz, ++ tmpIv, expBlockSz, NULL, 0, NULL, 0, ++ encryptedContent, encryptedContentSz, ++ encryptedContent, pkcs7->devId, pkcs7->heap); ++ } + if (ret != 0) { + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + } diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index ce3839e9a2..8802202114 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -23,6 +23,11 @@ SRC_URI = " \ file://CVE-2026-6091-2.patch \ file://CVE-2026-6091-3.patch \ file://CVE-2026-6092.patch \ + file://CVE-2026-6094-1.patch \ + file://CVE-2026-6094-2.patch \ + file://CVE-2026-6094-3.patch \ + file://CVE-2026-6094-4.patch \ + file://CVE-2026-6094-5.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97495 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 BD7C0C79F99 for ; Mon, 7 Sep 2026 10:24:49 +0000 (UTC) Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31933.1788776689322919214 for ; Mon, 07 Sep 2026 03:24:49 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=cV23lXsj; spf=pass (domain: gmail.com, ip: 209.85.210.181, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-85339ed040aso2590454b3a.1 for ; Mon, 07 Sep 2026 03:24:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776689; x=1789381489; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=HON1y1N+1bKpRINhJfjPcYvbV2MAITLuYzwepVVHZ80=; b=cV23lXsjNWAAWs8RQXRxF3ISrahZxruhG6wETXIIvJ8v0/bH0M6PvEtZAJ9mlyiCvc 10buxXRZm8kfHdvFKtmkYIkyaIDpC/f7fdi3X3RHFWTOP8Iiwsz19Ik7DuaPn3YimDGq M/p/o8pzVVJY9Pz5x3fPGyJDj4PYcM8lJfijeMJ6+vYfuscnD6Zj57OR0C5K9RWPmL8N X68B26yLUvC2UGWFTrXxvx1eVBokAgpfn6GA4o4QLzVtN6gvL+ngRx5VU1ok082Rg6Sq QuvGehd4wvzyusz86kYviopQ/NNOZpgfRQkpbT1HiEmRfyZwlhtwIg0pjrpNTyEi/bW+ 2Ufw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776689; x=1789381489; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=HON1y1N+1bKpRINhJfjPcYvbV2MAITLuYzwepVVHZ80=; b=sOmzdfrUUG+qP9xcWm8zKj4tIUniosMXt1dGb+4UXuGEJAEHyKhqfl/sP1l4aarPCA XkGJU/fAPeQuOzHu3xWYPg1Igjldl5b4sFl4Qq0n12hvJpIGMrXl5rGWCnWmW3p0U1oE q7LyfOTA7/1oaFnj4IBZpoe9Ifpg0SzXDJw/CA+FKVFLNw0Ia2+flRswuQAg2YfTyLfY GWPz56skdi/FK4M1qdbYH/GOfUTn+qfUwMHuUucV3UM1mjVdVPu2LKV6sNrRhfZuO8Uy oqb1To6vuvRM2ZXAsEt+kVVkoea+VUv/SYIPE8FYYfLMki7ye+6UBBkIdN46CfSZRN8p M4Ug== X-Gm-Message-State: AFuF++ko/fWVjshhWBeHSLgu0QQAnC9UnTf9d83gpz9es7nHsxPlYStp vUnGtOUI+3H1MTjXQGAAdYBIpp+kcyZsXZ+O2CyKf66X7uMjJEozf38eXYP5ShH5 X-Gm-Gg: AYBFou3xvr9GKXsSwaewfM9OVLlOYGZDmHEoJiUZAU0wmt3tOh50UcmzUYHQH0S29Am 5zQwbGCpRCKjRJoqKj5RoZU+mEvM9pkf6s4srCQmAW+CZqLbDOJL9Gj8sgY2VrOBBD/DnFj/ipE KYBBULDtKwRbn14+6dVOJeAnJCZDA82312W36IH5SJ3CpI5Vkzetd7p8koabsgrz8DQwkBnm57x +ivx2K0vomCMdVIMbMPNNEPFnvMDZolyetf3inpsHWeAGex3vRZ/HzdqrqGqxN0k4LbzGanzEIb lBn5X+LY1viOT0UCtc6GWlaWqyGRdlah1frKj9t891dI7pcayt3x8J2C/Stkf2/lT+rrwuoVb0M i0t6KZyVH+Y6fKi3AjXqGoGr2rShXOY7atAdaYRZRIO1YtEdUyHLMgNbgSEICO7Pa/y3SFj7MRt bF4Swt332WLAZt8WFR2Nua9dxutStnQiumHoRACebLajYSrdFepQG3242Rh2Bf+G+E/jg/jzJmw Q== X-Received: by 2002:a05:6a21:7002:b0:3c4:2b8b:e88f with SMTP id adf61e73a8af0-3da39d1877amr39101182637.5.1788776687261; Mon, 07 Sep 2026 03:24:47 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:46 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 28/33] wolfssl: patch CVE-2026-6291 Date: Mon, 7 Sep 2026 22:23:12 +1200 Message-ID: <20260907102318.2459883-28-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:49 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129840 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-6291 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-6291.patch | 2948 +++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 1 + 2 files changed, 2949 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6291.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6291.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6291.patch new file mode 100644 index 0000000000..dd41f9f15d --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6291.patch @@ -0,0 +1,2948 @@ +From 3aab2df7436240515c608971ca9b899c37f93f47 Mon Sep 17 00:00:00 2001 +From: Sean Parkinson +Date: Fri, 24 Apr 2026 10:13:43 +1000 +Subject: [PATCH] Merge pull request #10203 from Frauschi/pkcs7_fixes + +PKCS#7 fixes + +(cherry picked from commit 936f8e54230b11dee50e82bcc5a2247ea9d9c91c) + +CVE: CVE-2026-6291 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/936f8e54230b11dee50e82bcc5a2247ea9d9c91c] + +Signed-off-by: Ankur Tyagi +--- + .wolfssl_known_macro_extras | 1 + + src/ssl_p7p12.c | 28 +- + tests/api.c | 707 +++++++++++++++++++++++++++++++++ + tests/api/test_ossl_p7p12.c | 454 +++++++++++++++++++++ + tests/api/test_ossl_p7p12.h | 4 + + tests/api/test_pkcs7.c | 356 +++++++++++++++-- + tests/api/test_pkcs7.h | 25 +- + wolfcrypt/src/pkcs7.c | 633 +++++++++++++++++++++++++++-- + wolfssl/wolfcrypt/wc_encrypt.h | 3 + + 9 files changed, 2154 insertions(+), 57 deletions(-) + +diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras +index ba5e47ef6..3e411ca86 100644 +--- a/.wolfssl_known_macro_extras ++++ b/.wolfssl_known_macro_extras +@@ -825,6 +825,7 @@ WOLFSSL_NO_KCAPI_HMAC_SHA256 + WOLFSSL_NO_KCAPI_HMAC_SHA384 + WOLFSSL_NO_KCAPI_HMAC_SHA512 + WOLFSSL_NO_KCAPI_SHA224 ++WOLFSSL_NO_KTRI_ORACLE_WARNING + WOLFSSL_NO_OCSP_DATE_CHECK + WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK + WOLFSSL_NO_OCSP_OPTIONAL_CERTS +diff --git a/src/ssl_p7p12.c b/src/ssl_p7p12.c +index ee48d700a..a07f018b2 100644 +--- a/src/ssl_p7p12.c ++++ b/src/ssl_p7p12.c +@@ -269,24 +269,42 @@ WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs, + WOLFSSL_X509* x509 = NULL; + WOLFSSL_STACK* signers = NULL; + WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7; ++ byte* signerCert; ++ word32 signerCertSz; + + if (p7 == NULL) + return NULL; + +- /* Only PKCS#7 messages with a single cert that is the verifying certificate +- * is supported. +- */ + if (flags & PKCS7_NOINTERN) { + WOLFSSL_MSG("PKCS7_NOINTERN flag not supported"); + return NULL; + } + ++ /* Prefer the certificate that actually verified the signature. Falling ++ * back to singleCert (cert[0]) would let an attacker that bundles a ++ * trusted cert ahead of their own attacker cert have the trusted cert ++ * reported as the signer even though it did not produce the signature. ++ * ++ * Copy the chosen pointer into a local before passing its address to ++ * wolfSSL_d2i_X509; d2i_X509 advances *in by the DER length, and if ++ * we handed it the address of the struct field directly it would ++ * permanently corrupt the field, producing a heap-OOB read on the ++ * next use (pointer advanced, singleCertSz unchanged). */ ++ if (p7->pkcs7.verifyCert != NULL && p7->pkcs7.verifyCertSz > 0) { ++ signerCert = p7->pkcs7.verifyCert; ++ signerCertSz = p7->pkcs7.verifyCertSz; ++ } ++ else { ++ signerCert = p7->pkcs7.singleCert; ++ signerCertSz = p7->pkcs7.singleCertSz; ++ } ++ + signers = wolfSSL_sk_X509_new_null(); + if (signers == NULL) + return NULL; + +- if (wolfSSL_d2i_X509(&x509, (const byte**)&p7->pkcs7.singleCert, +- p7->pkcs7.singleCertSz) == NULL) { ++ if (wolfSSL_d2i_X509(&x509, (const byte**)&signerCert, ++ signerCertSz) == NULL) { + wolfSSL_sk_X509_pop_free(signers, NULL); + return NULL; + } +diff --git a/tests/api.c b/tests/api.c +index ad5f84573..78fcf13ce 100644 +--- a/tests/api.c ++++ b/tests/api.c +@@ -34990,6 +34990,706 @@ static int test_pkcs7_ori_oversized_oid(void) + return EXPECT_RESULT(); + } + ++/* ORI callback that flags if oriValueSz looks like an underflow (>= 0x80000000) */ ++#if defined(HAVE_PKCS7) && !defined(WOLFSSL_NO_MALLOC) ++static int test_ori_underflow_cb(wc_PKCS7* pkcs7, byte* oriType, ++ word32 oriTypeSz, byte* oriValue, ++ word32 oriValueSz, byte* decryptedKey, ++ word32* decryptedKeySz, void* ctx) ++{ ++ int* called = (int*)ctx; ++ (void)pkcs7; (void)oriType; (void)oriTypeSz; ++ (void)oriValue; (void)decryptedKey; (void)decryptedKeySz; ++ if (called != NULL) ++ *called = (int)oriValueSz; /* record what we received */ ++ return -1; ++} ++#endif ++ ++/* Test: PKCS#7 ORI must reject when OID consumption exceeds the [4] implicit ++ * SEQUENCE length (integer underflow in oriValueSz computation). ++ * ++ * With implicit tagging, [4] CONSTRUCTED replaces the SEQUENCE tag, so ++ * wc_PKCS7_DecryptOri reads seqSz directly from the [4] length field. ++ * We set [4] length = 5 while the OID inside consumes 22 bytes ++ * (tag + length + 20 content), triggering oriValueSz = 5 - 22 = underflow. ++ * ++ * The buffer includes a dummy EncryptedContentInfo after the RecipientInfos ++ * so the total message is large enough for the PKCS7 streaming code (which ++ * requests the full remaining message before parsing the ORI). */ ++static int test_pkcs7_ori_seqsz_underflow(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_PKCS7) && !defined(WOLFSSL_NO_MALLOC) ++ wc_PKCS7* p7 = NULL; ++ byte out[256]; ++ int cbCalled = 0; ++ ++ /* ++ * Byte layout (all outer lengths match actual byte counts on wire): ++ * ++ * OID inside [4]: 06 14 <20 bytes> = 22 bytes ++ * [4] (declared len 5, actual content 22): ++ * a4 05 <22 bytes> = 24 bytes on wire ++ * SET: 31 18 <24 bytes> = 26 bytes on wire ++ * version: 02 01 00 = 3 bytes ++ * EncryptedContentInfo (filler, never parsed): ++ * 30 0b { 06 09 <9 bytes OID> } = 13 bytes on wire ++ * EnvelopedData: 30 2a <3+26+13=42 bytes> = 44 bytes on wire ++ * [0] EXPLICIT: a0 2c <44 bytes> = 46 bytes on wire ++ * OID(envelopedData): 06 09 <9 bytes> = 11 bytes on wire ++ * ContentInfo: 30 39 <11+46=57 bytes> = 59 bytes total ++ */ ++ static const byte poc[] = { ++ /* ContentInfo SEQUENCE (length 57) */ ++ 0x30, 0x39, ++ /* contentType = envelopedData 1.2.840.113549.1.7.3 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03, ++ /* [0] EXPLICIT (length 44) */ ++ 0xa0, 0x2c, ++ /* EnvelopedData SEQUENCE (length 42) */ ++ 0x30, 0x2a, ++ /* version = 0 */ ++ 0x02, 0x01, 0x00, ++ /* RecipientInfos SET (length 24) */ ++ 0x31, 0x18, ++ /* [4] CONSTRUCTED = ORI implicit SEQUENCE, declared len 5 */ ++ /* Actual OID is 22 bytes -> exceeds declared 5 */ ++ 0xa4, 0x05, ++ /* OID: tag=06, len=0x14(20), content=20 bytes = 22 total */ ++ 0x06, 0x14, ++ 0x2a, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, ++ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, ++ 0x12, 0x13, 0x14, 0x15, ++ /* EncryptedContentInfo SEQUENCE (length 11) - filler so ++ * streaming has enough data; never actually parsed because ++ * DecryptOri fails before we get here */ ++ 0x30, 0x0b, ++ /* contentType = data 1.2.840.113549.1.7.1 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, ++ 0x01 ++ }; ++ ++ p7 = wc_PKCS7_New(NULL, INVALID_DEVID); ++ ExpectNotNull(p7); ++ if (p7 != NULL) { ++ wc_PKCS7_SetOriDecryptCb(p7, test_ori_underflow_cb); ++ wc_PKCS7_SetOriDecryptCtx(p7, &cbCalled); ++ ++ /* Must return an error before the callback sees an underflowed size */ ++ ExpectIntLT(wc_PKCS7_DecodeEnvelopedData(p7, (byte*)poc, sizeof(poc), ++ out, sizeof(out)), 0); ++ ++ /* The callback must NOT have been invoked with a wrapped oriValueSz. ++ * cbCalled == 0 means the callback was never reached (ideal). ++ * cbCalled < 0 would indicate the underflow was passed through. */ ++ ExpectIntGE(cbCalled, 0); ++ ++ wc_PKCS7_Free(p7); ++ } ++#endif ++ return EXPECT_RESULT(); ++} ++ ++/* Test: PKCS#7 ORI must reject when seqSz extends oriValue past input buffer. ++ * ++ * The first ORI bounds check (OID exceeds SEQUENCE boundary) is covered by ++ * test_pkcs7_ori_seqsz_underflow. This test covers the *second* check: ++ * oriValue region extends past the end of the input buffer. We craft a ++ * message where the [4] SEQUENCE length is valid relative to the OID ++ * (OID fits inside it), but the remaining oriValue portion extends past ++ * the end of the actual input buffer. ++ * ++ * To bypass GetLength's own bounds validation, we set the outer lengths ++ * (EnvelopedData SEQUENCE, RecipientInfos SET) to match the [4] claim, ++ * but truncate the actual buffer we pass to DecodeEnvelopedData. */ ++static int test_pkcs7_ori_orivalue_overflow(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_PKCS7) && !defined(WOLFSSL_NO_MALLOC) ++ wc_PKCS7* p7 = NULL; ++ byte out[256]; ++ ++ /* EnvelopedData with [4] ORI whose seqSz (40) is valid for the OID ++ * (6 bytes consumed) but oriValueSz (34) extends past the truncated ++ * input buffer. ++ * ++ * Layout: ++ * ContentInfo SEQUENCE ++ * OID envelopedData ++ * [0] EXPLICIT ++ * EnvelopedData SEQUENCE ++ * version = 0 ++ * RecipientInfos SET ++ * [4] CONSTRUCTED (seqSz = 40) ++ * OID (tag 06, len 04, 4 content bytes = 6 total) ++ * oriValue should be 34 bytes but input is truncated ++ * EncryptedContentInfo (filler for streaming) ++ * ++ * We pass the full array to DecodeEnvelopedData, but the actual ++ * input ends before [4]'s declared 40 bytes are consumed. ++ */ ++ static const byte poc[] = { ++ /* ContentInfo SEQUENCE */ ++ 0x30, 0x43, ++ /* contentType = envelopedData 1.2.840.113549.1.7.3 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03, ++ /* [0] EXPLICIT */ ++ 0xa0, 0x36, ++ /* EnvelopedData SEQUENCE */ ++ 0x30, 0x34, ++ /* version = 0 */ ++ 0x02, 0x01, 0x00, ++ /* RecipientInfos SET (len = 44 covers [4] tag+len+40) */ ++ 0x31, 0x2c, ++ /* [4] CONSTRUCTED = ORI implicit SEQUENCE, seqSz = 40 */ ++ 0xa4, 0x28, ++ /* OID: tag=06, len=04, 4 content bytes = 6 total */ ++ 0x06, 0x04, 0x2a, 0x03, 0x04, 0x05, ++ /* Only 4 bytes of oriValue here, but seqSz claims 34 more */ ++ 0x00, 0x00, 0x00, 0x00, ++ /* EncryptedContentInfo SEQUENCE (filler) */ ++ 0x30, 0x0b, ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, ++ 0x01 ++ }; ++ ++ p7 = wc_PKCS7_New(NULL, INVALID_DEVID); ++ ExpectNotNull(p7); ++ if (p7 != NULL) { ++ wc_PKCS7_SetOriDecryptCb(p7, test_dummy_ori_cb); ++ ++ /* Must return error - oriValue extends past input buffer */ ++ ExpectIntLT(wc_PKCS7_DecodeEnvelopedData(p7, (byte*)poc, sizeof(poc), ++ out, sizeof(out)), 0); ++ ++ wc_PKCS7_Free(p7); ++ } ++#endif ++ return EXPECT_RESULT(); ++} ++ ++/* Test: PKCS#7 KTRI must not match recipient when SKID length differs ++ * from expected keyIdSize. ++ * ++ * The fix adds a `length == keyIdSize` check before comparing the SKID ++ * bytes. Without this check, XMEMCMP could compare against data beyond ++ * the SKID content. This test crafts a KTRI RecipientInfo where the ++ * [0] SubjectKeyIdentifier has length 5 instead of KEYID_SIZE (20). ++ * The decode must return an error (no matching recipient). */ ++static int test_pkcs7_ktri_skid_length_mismatch(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_PKCS7) && !defined(NO_RSA) && !defined(WOLFSSL_NO_MALLOC) ++ wc_PKCS7* p7 = NULL; ++ byte out[256]; ++ ++ /* Minimal EnvelopedData with KTRI using version=2 (SKID path). ++ * The SKID [0] has length 5 instead of 20. ++ * ++ * ContentInfo SEQUENCE ++ * OID envelopedData ++ * [0] EXPLICIT ++ * EnvelopedData SEQUENCE ++ * version = 2 ++ * RecipientInfos SET ++ * KTRI SEQUENCE ++ * version = 2 ++ * [0] SKID (5 bytes, should be 20) ++ * AlgorithmIdentifier (RSA OID) ++ * OCTET STRING (fake encrypted key) ++ * EncryptedContentInfo (filler) ++ */ ++ static const byte poc[] = { ++ /* ContentInfo SEQUENCE */ ++ 0x30, 0x46, ++ /* contentType = envelopedData 1.2.840.113549.1.7.3 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03, ++ /* [0] EXPLICIT */ ++ 0xa0, 0x39, ++ /* EnvelopedData SEQUENCE */ ++ 0x30, 0x37, ++ /* version = 2 (triggers SKID-based recipient identification) */ ++ 0x02, 0x01, 0x02, ++ /* RecipientInfos SET */ ++ 0x31, 0x21, ++ /* KTRI SEQUENCE */ ++ 0x30, 0x1f, ++ /* version = 2 (SKID) */ ++ 0x02, 0x01, 0x02, ++ /* [0] IMPLICIT SubjectKeyIdentifier, length = 5 (wrong!) */ ++ 0x80, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, ++ /* AlgorithmIdentifier: RSA 1.2.840.113549.1.1.1 */ ++ 0x30, 0x0d, ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, ++ 0x01, 0x01, 0x01, ++ 0x05, 0x00, /* NULL params */ ++ /* encryptedKey OCTET STRING (2 bytes fake) */ ++ 0x04, 0x02, 0xAA, 0xBB, ++ /* EncryptedContentInfo SEQUENCE (filler) */ ++ 0x30, 0x0b, ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, ++ 0x01 ++ }; ++ ++ p7 = wc_PKCS7_New(NULL, INVALID_DEVID); ++ ExpectNotNull(p7); ++ if (p7 != NULL) { ++ /* Decode without a cert - SKID will never match, and the ++ * mismatched SKID length must not cause out-of-bounds reads */ ++ ExpectIntLT(wc_PKCS7_DecodeEnvelopedData(p7, (byte*)poc, sizeof(poc), ++ out, sizeof(out)), 0); ++ ++ wc_PKCS7_Free(p7); ++ } ++#endif ++ return EXPECT_RESULT(); ++} ++ ++/* Test: PKCS#7 KARI must reject BIT STRING with length < 2 in ++ * OriginatorPublicKey. ++ * ++ * The fix adds `if (length < 2) return ASN_PARSE_E` after parsing ++ * the BIT STRING tag and length. A BIT STRING must have at least ++ * the unused-bits byte plus one byte of content. This test crafts ++ * a KARI [1] RecipientInfo where the OriginatorPublicKey's BIT STRING ++ * has length 1 (degenerate). The PKCS7 object is initialized with a ++ * real ECC cert so that KariParseRecipCert succeeds and parsing reaches ++ * the BIT STRING validation. */ ++static int test_pkcs7_kari_degenerate_bitstring(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_PKCS7) && defined(HAVE_ECC) && defined(HAVE_X963_KDF) && \ ++ !defined(WOLFSSL_NO_MALLOC) ++ wc_PKCS7* p7 = NULL; ++ byte out[256]; ++ byte* eccCert = NULL; ++ byte* eccPrivKey = NULL; ++ word32 eccCertSz = 0; ++ word32 eccPrivKeySz = 0; ++#if !defined(USE_CERT_BUFFERS_256) && !defined(NO_FILESYSTEM) ++ XFILE f = XBADFILE; ++#endif ++ ++ /* Minimal EnvelopedData with KARI [1] containing a degenerate ++ * BIT STRING (length 1) in OriginatorPublicKey. ++ * ++ * ContentInfo SEQUENCE ++ * OID envelopedData ++ * [0] EXPLICIT ++ * EnvelopedData SEQUENCE ++ * version = 2 ++ * RecipientInfos SET ++ * [1] CONSTRUCTED (KARI) ++ * version = 3 ++ * [0] CONSTRUCTED (OriginatorIdentifierOrKey) ++ * [1] CONSTRUCTED (OriginatorPublicKey) ++ * AlgorithmIdentifier (ECDSAk) ++ * BIT STRING length=1 (degenerate!) ++ * EncryptedContentInfo (filler) ++ */ ++ static const byte poc[] = { ++ /* ContentInfo SEQUENCE */ ++ 0x30, 0x44, ++ /* contentType = envelopedData 1.2.840.113549.1.7.3 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03, ++ /* [0] EXPLICIT */ ++ 0xa0, 0x37, ++ /* EnvelopedData SEQUENCE */ ++ 0x30, 0x35, ++ /* version = 2 */ ++ 0x02, 0x01, 0x02, ++ /* RecipientInfos SET */ ++ 0x31, 0x1f, ++ /* [1] CONSTRUCTED (KARI implicit) */ ++ 0xa1, 0x1d, ++ /* version = 3 */ ++ 0x02, 0x01, 0x03, ++ /* [0] CONSTRUCTED (OriginatorIdentifierOrKey) */ ++ 0xa0, 0x18, ++ /* [1] CONSTRUCTED (OriginatorPublicKey) */ ++ 0xa1, 0x16, ++ /* AlgorithmIdentifier SEQUENCE */ ++ 0x30, 0x13, ++ /* OID: id-ecPublicKey 1.2.840.10045.2.1 */ ++ 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, ++ /* OID: prime256v1 1.2.840.10045.3.1.7 */ ++ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, ++ 0x01, 0x07, ++ /* BIT STRING with length 1 - degenerate! */ ++ 0x03, 0x01, 0x00, ++ /* EncryptedContentInfo SEQUENCE (filler) */ ++ 0x30, 0x0b, ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, ++ 0x01 ++ }; ++ ++ /* Load ECC cert and key so KariParseRecipCert succeeds and ++ * parsing reaches the BIT STRING check */ ++#ifdef USE_CERT_BUFFERS_256 ++ eccCertSz = (word32)sizeof_cliecc_cert_der_256; ++ ExpectNotNull(eccCert = (byte*)XMALLOC(eccCertSz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (eccCert != NULL) ++ XMEMCPY(eccCert, cliecc_cert_der_256, eccCertSz); ++ eccPrivKeySz = (word32)sizeof_ecc_clikey_der_256; ++ ExpectNotNull(eccPrivKey = (byte*)XMALLOC(eccPrivKeySz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (eccPrivKey != NULL) ++ XMEMCPY(eccPrivKey, ecc_clikey_der_256, eccPrivKeySz); ++#elif !defined(NO_FILESYSTEM) ++ eccCertSz = FOURK_BUF; ++ ExpectNotNull(eccCert = (byte*)XMALLOC(eccCertSz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ ExpectTrue((f = XFOPEN("./certs/client-ecc-cert.der", "rb")) != XBADFILE); ++ ExpectTrue((eccCertSz = (word32)XFREAD(eccCert, 1, eccCertSz, f)) > 0); ++ if (f != XBADFILE) { ++ XFCLOSE(f); ++ f = XBADFILE; ++ } ++ eccPrivKeySz = FOURK_BUF; ++ ExpectNotNull(eccPrivKey = (byte*)XMALLOC(eccPrivKeySz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ ExpectTrue((f = XFOPEN("./certs/ecc-client-key.der", "rb")) != XBADFILE); ++ ExpectTrue((eccPrivKeySz = (word32)XFREAD(eccPrivKey, 1, eccPrivKeySz, ++ f)) > 0); ++ if (f != XBADFILE) ++ XFCLOSE(f); ++#else ++ eccCert = NULL; ++ eccCertSz = 0; ++ eccPrivKey = NULL; ++ eccPrivKeySz = 0; ++#endif ++ ++ p7 = wc_PKCS7_New(HEAP_HINT, INVALID_DEVID); ++ ExpectNotNull(p7); ++ if (p7 != NULL && eccCert != NULL) { ++ ExpectIntEQ(wc_PKCS7_InitWithCert(p7, eccCert, eccCertSz), 0); ++ if (p7 != NULL) { ++ p7->privateKey = eccPrivKey; ++ p7->privateKeySz = eccPrivKeySz; ++ } ++ ++ /* Must return error - BIT STRING length < 2 is invalid */ ++ ExpectIntLT(wc_PKCS7_DecodeEnvelopedData(p7, (byte*)poc, sizeof(poc), ++ out, sizeof(out)), 0); ++ ++ if (p7 != NULL) { ++ p7->privateKey = NULL; ++ p7->privateKeySz = 0; ++ } ++ wc_PKCS7_Free(p7); ++ } ++ else if (p7 != NULL) { ++ wc_PKCS7_Free(p7); ++ } ++ ++ XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++#endif ++ return EXPECT_RESULT(); ++} ++ ++/* Test: PKCS#7 EncryptedData must reject when encryptedContentSz exceeds ++ * the remaining input buffer. ++ * ++ * The fix adds `encryptedContentSz > (int)(pkiMsgSz - idx)` to the ++ * existing `encryptedContentSz <= 0` check in stage 6. This test crafts ++ * a minimal EncryptedData where the [0] IMPLICIT content length claims ++ * 0x200 (512) bytes but only 32 bytes of ciphertext are present. */ ++static int test_pkcs7_encrypted_content_size_overflow(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_PKCS7) && !defined(NO_AES) && defined(HAVE_AES_CBC) && \ ++ defined(WOLFSSL_AES_256) && !defined(NO_PKCS7_ENCRYPTED_DATA) && \ ++ !defined(WOLFSSL_NO_MALLOC) ++ wc_PKCS7* p7 = NULL; ++ byte key[32]; ++ byte out[256]; ++ ++ /* EncryptedData with [0] content claiming 512 bytes but only 32 present. ++ * ++ * ContentInfo SEQUENCE ++ * OID encryptedData (1.2.840.113549.1.7.6) ++ * [0] EXPLICIT ++ * EncryptedData SEQUENCE ++ * version = 0 ++ * EncryptedContentInfo SEQUENCE ++ * OID data (1.2.840.113549.1.7.1) ++ * AlgorithmIdentifier ++ * OID AES-256-CBC (2.16.840.1.101.3.4.1.42) ++ * OCTET STRING IV (16 zero bytes) ++ * [0] IMPLICIT content (claimed len=0x200, actual=32 bytes) ++ */ ++ static const byte poc[] = { ++ /* ContentInfo SEQUENCE (len covers entire message) */ ++ 0x30, 0x50, ++ /* OID encryptedData 1.2.840.113549.1.7.6 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, ++ /* [0] EXPLICIT */ ++ 0xa0, 0x43, ++ /* EncryptedData SEQUENCE */ ++ 0x30, 0x41, ++ /* version = 0 */ ++ 0x02, 0x01, 0x00, ++ /* EncryptedContentInfo SEQUENCE */ ++ 0x30, 0x3c, ++ /* OID data 1.2.840.113549.1.7.1 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, ++ 0x01, ++ /* AlgorithmIdentifier SEQUENCE */ ++ 0x30, 0x1d, ++ /* OID AES-256-CBC 2.16.840.1.101.3.4.1.42 */ ++ 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, ++ 0x2a, ++ /* IV: OCTET STRING (16 zero bytes) */ ++ 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* [0] IMPLICIT encryptedContent - claims 512 bytes! ++ * Only 16 bytes of fake ciphertext follow. */ ++ 0x80, 0x82, 0x02, 0x00, ++ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, ++ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA ++ }; ++ ++ XMEMSET(key, 0, sizeof(key)); ++ ++ p7 = wc_PKCS7_New(NULL, INVALID_DEVID); ++ ExpectNotNull(p7); ++ if (p7 != NULL) { ++ p7->encryptionKey = key; ++ p7->encryptionKeySz = sizeof(key); ++ ++ /* Must return error - content extends past input buffer */ ++ ExpectIntLT(wc_PKCS7_DecodeEncryptedData(p7, (byte*)poc, sizeof(poc), ++ out, sizeof(out)), 0); ++ ++ wc_PKCS7_Free(p7); ++ } ++#endif ++ return EXPECT_RESULT(); ++} ++ ++/* Test: PKCS#7 SignedData must reject when the signature field is not ++ * an OCTET STRING. ++ * ++ * The fix adds `else if (ret == 0) { ret = ASN_PARSE_E; }` so that ++ * when the tag at the signature position is not ASN_OCTET_STRING, ++ * parsing returns an error instead of silently continuing with no ++ * signature. This test encodes a valid SignedData, then corrupts ++ * the signature OCTET STRING tag and verifies that decode fails. */ ++static int test_pkcs7_signed_bad_sig_tag(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_PKCS7) && !defined(NO_RSA) && !defined(NO_SHA256) && \ ++ !defined(WOLFSSL_NO_MALLOC) ++ PKCS7* pkcs7 = NULL; ++ WC_RNG rng; ++ byte encoded[FOURK_BUF]; ++ int encodedSz = 0; ++ int i; ++ byte* rsaCert = NULL; ++ byte* rsaPrivKey = NULL; ++ word32 rsaCertSz = 0; ++ word32 rsaPrivKeySz = 0; ++#if !defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_1024) && \ ++ !defined(NO_FILESYSTEM) ++ XFILE f = XBADFILE; ++#endif ++ ++ const byte data[] = "Test signed data"; ++ ++ XMEMSET(&rng, 0, sizeof(WC_RNG)); ++ ++ /* Load RSA cert and key */ ++#if defined(USE_CERT_BUFFERS_2048) ++ rsaCertSz = (word32)sizeof_client_cert_der_2048; ++ ExpectNotNull(rsaCert = (byte*)XMALLOC(rsaCertSz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (rsaCert != NULL) ++ XMEMCPY(rsaCert, client_cert_der_2048, rsaCertSz); ++ rsaPrivKeySz = (word32)sizeof_client_key_der_2048; ++ ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(rsaPrivKeySz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (rsaPrivKey != NULL) ++ XMEMCPY(rsaPrivKey, client_key_der_2048, rsaPrivKeySz); ++#elif defined(USE_CERT_BUFFERS_1024) ++ rsaCertSz = (word32)sizeof_client_cert_der_1024; ++ ExpectNotNull(rsaCert = (byte*)XMALLOC(rsaCertSz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (rsaCert != NULL) ++ XMEMCPY(rsaCert, client_cert_der_1024, rsaCertSz); ++ rsaPrivKeySz = (word32)sizeof_client_key_der_1024; ++ ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(rsaPrivKeySz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (rsaPrivKey != NULL) ++ XMEMCPY(rsaPrivKey, client_key_der_1024, rsaPrivKeySz); ++#elif !defined(NO_FILESYSTEM) ++ rsaCertSz = FOURK_BUF; ++ ExpectNotNull(rsaCert = (byte*)XMALLOC(rsaCertSz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ ExpectTrue((f = XFOPEN("./certs/client-cert.der", "rb")) != XBADFILE); ++ ExpectTrue((rsaCertSz = (word32)XFREAD(rsaCert, 1, rsaCertSz, f)) > 0); ++ if (f != XBADFILE) { XFCLOSE(f); f = XBADFILE; } ++ rsaPrivKeySz = FOURK_BUF; ++ ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(rsaPrivKeySz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ ExpectTrue((f = XFOPEN("./certs/client-key.der", "rb")) != XBADFILE); ++ ExpectTrue((rsaPrivKeySz = (word32)XFREAD(rsaPrivKey, 1, ++ rsaPrivKeySz, f)) > 0); ++ if (f != XBADFILE) XFCLOSE(f); ++#else ++ rsaCert = NULL; rsaCertSz = 0; ++ rsaPrivKey = NULL; rsaPrivKeySz = 0; ++#endif ++ ++ if (rsaCert == NULL || rsaPrivKey == NULL) { ++ XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ return TEST_SKIPPED; ++ } ++ ++ ExpectIntEQ(wc_InitRng(&rng), 0); ++ ++ /* Encode a valid SignedData */ ++ ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); ++ ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, rsaCert, rsaCertSz), 0); ++ if (pkcs7 != NULL) { ++ pkcs7->content = (byte*)data; ++ pkcs7->contentSz = (word32)sizeof(data); ++ pkcs7->contentOID = DATA; ++ pkcs7->hashOID = SHA256h; ++ pkcs7->encryptOID = RSAk; ++ pkcs7->privateKey = rsaPrivKey; ++ pkcs7->privateKeySz = rsaPrivKeySz; ++ pkcs7->rng = &rng; ++ } ++ ++ ExpectIntGT(encodedSz = wc_PKCS7_EncodeSignedData(pkcs7, encoded, ++ sizeof(encoded)), 0); ++ wc_PKCS7_Free(pkcs7); ++ pkcs7 = NULL; ++ ++ /* Find the signature OCTET STRING tag (0x04) near the end of the ++ * encoded message and corrupt it. The signature is the last large ++ * OCTET STRING in the SignerInfo. Search backwards for 0x04 followed ++ * by a length that looks like an RSA signature (>= 64 bytes). ++ * This heuristic depends on the signature being the last large ++ * OCTET STRING; the found==1 assertion below guards against ++ * silent false passes if encoding changes. */ ++ if (EXPECT_SUCCESS()) { ++ int found = 0; ++ for (i = encodedSz - 10; i > 10; i--) { ++ if (encoded[i] == 0x04) { ++ int len = 0, lbytes = 0; ++ if (encoded[i+1] < 0x80) { ++ len = encoded[i+1]; lbytes = 1; ++ } ++ else if (encoded[i+1] == 0x81) { ++ len = encoded[i+2]; lbytes = 2; ++ } ++ else if (encoded[i+1] == 0x82) { ++ len = (encoded[i+2] << 8) | encoded[i+3]; lbytes = 3; ++ } ++ /* RSA signature is typically >= 128 bytes */ ++ if (len >= 64 && i + 1 + lbytes + len <= encodedSz) { ++ /* Corrupt the OCTET STRING tag to INTEGER */ ++ encoded[i] = 0x02; /* ASN_INTEGER instead of OCTET STRING */ ++ found = 1; ++ break; ++ } ++ } ++ } ++ ExpectIntEQ(found, 1); ++ } ++ ++ /* Verify the corrupted SignedData - must fail */ ++ if (EXPECT_SUCCESS()) { ++ ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); ++ ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0); ++ ExpectIntLT(wc_PKCS7_VerifySignedData(pkcs7, encoded, ++ (word32)encodedSz), 0); ++ wc_PKCS7_Free(pkcs7); ++ pkcs7 = NULL; ++ } ++ ++ DoExpectIntEQ(wc_FreeRng(&rng), 0); ++ XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++#endif ++ return EXPECT_RESULT(); ++} ++ ++/* Test: PKCS#7 EnvelopedData must reject when encryptedContentTotalSz ++ * exceeds the remaining input buffer. ++ * ++ * The fix adds a bounds check under NO_PKCS7_STREAM, but the same ++ * crafted message should also be properly handled in streaming mode. ++ * This test crafts an EnvelopedData where the [0] content length ++ * claims 512 bytes but only minimal data follows. */ ++static int test_pkcs7_enveloped_content_size_overflow(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_PKCS7) && !defined(WOLFSSL_NO_MALLOC) && !defined(NO_RSA) ++ wc_PKCS7* p7 = NULL; ++ byte out[256]; ++ ++ /* EnvelopedData with KTRI where the EncryptedContentInfo [0] claims ++ * 512 bytes but only 16 are present. ++ * ++ * The outer structure is valid enough to reach the content parsing: ++ * ContentInfo -> EnvelopedData -> version=0 -> ++ * RecipientInfos (empty SET) -> EncryptedContentInfo -> ++ * contentType + AlgorithmIdentifier + [0] oversized content */ ++ static const byte poc[] = { ++ /* ContentInfo SEQUENCE */ ++ 0x30, 0x50, ++ /* OID envelopedData 1.2.840.113549.1.7.3 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03, ++ /* [0] EXPLICIT */ ++ 0xa0, 0x43, ++ /* EnvelopedData SEQUENCE */ ++ 0x30, 0x41, ++ /* version = 0 */ ++ 0x02, 0x01, 0x00, ++ /* RecipientInfos SET (empty - no recipients) */ ++ 0x31, 0x00, ++ /* EncryptedContentInfo SEQUENCE */ ++ 0x30, 0x3c, ++ /* OID data 1.2.840.113549.1.7.1 */ ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, ++ 0x01, ++ /* AlgorithmIdentifier SEQUENCE */ ++ 0x30, 0x1d, ++ /* OID AES-256-CBC 2.16.840.1.101.3.4.1.42 */ ++ 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, ++ 0x2a, ++ /* IV: OCTET STRING (16 zero bytes) */ ++ 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* [0] IMPLICIT encryptedContent - claims 512 bytes! */ ++ 0x80, 0x82, 0x02, 0x00, ++ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, ++ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA ++ }; ++ ++ p7 = wc_PKCS7_New(NULL, INVALID_DEVID); ++ ExpectNotNull(p7); ++ if (p7 != NULL) { ++ /* With an empty RecipientInfos SET, the function may fail at ++ * the recipient matching stage before reaching the content-size ++ * bounds check. The ExpectIntLT assertion ensures the ++ * oversized content does not cause a buffer over-read. */ ++ ExpectIntLT(wc_PKCS7_DecodeEnvelopedData(p7, (byte*)poc, sizeof(poc), ++ out, sizeof(out)), 0); ++ ++ wc_PKCS7_Free(p7); ++ } ++#endif ++ return EXPECT_RESULT(); ++} ++ + /* Dilithium verify_ctx_msg must reject absurdly large msgLen */ + static int test_dilithium_hash(void) + { +@@ -35936,6 +36636,13 @@ TEST_CASE testCases[] = { + TEST_DECL(test_ed448_rejects_identity_key), + TEST_DECL(test_pkcs7_decode_encrypted_outputsz), + TEST_DECL(test_pkcs7_ori_oversized_oid), ++ TEST_DECL(test_pkcs7_ori_seqsz_underflow), ++ TEST_DECL(test_pkcs7_ori_orivalue_overflow), ++ TEST_DECL(test_pkcs7_ktri_skid_length_mismatch), ++ TEST_DECL(test_pkcs7_kari_degenerate_bitstring), ++ TEST_DECL(test_pkcs7_encrypted_content_size_overflow), ++ TEST_DECL(test_pkcs7_signed_bad_sig_tag), ++ TEST_DECL(test_pkcs7_enveloped_content_size_overflow), + TEST_DECL(test_pkcs7_padding), + + #if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT) +diff --git a/tests/api/test_ossl_p7p12.c b/tests/api/test_ossl_p7p12.c +index c92b80ee5..03590a3ad 100644 +--- a/tests/api/test_ossl_p7p12.c ++++ b/tests/api/test_ossl_p7p12.c +@@ -446,6 +446,460 @@ int test_wolfSSL_PKCS7_sign(void) + return EXPECT_RESULT(); + } + ++/* Regression test for CMS SignedData signer-identity forgery. ++ * ++ * The embedded DER is a CMS SignedData message crafted so that the ++ * certificates SET contains two certificates: ++ * cert[0] = certs/ca-cert.pem (trusted wolfSSL CA; attacker does NOT hold ++ * its private key) ++ * cert[1] = a self-signed "attacker" P-256 certificate (attacker holds ++ * the private key) ++ * The signerInfo sid names the attacker certificate, and the signature ++ * was produced with the attacker's key over "Hello World". ++ * ++ * The bug that was present: wolfSSL_PKCS7_verify() iterated all bundled ++ * certificates trying each public key against the signature. When the ++ * attacker's key verified, it still reported cert[0] (the trusted CA cert, ++ * via singleCert) as the signer, and chain validation therefore succeeded ++ * on an unrelated trusted cert - a full signer-identity forgery. ++ * ++ * The expected, correct behavior: the CMS message is rejected because the ++ * signer certificate named by the sid (the attacker cert) does not chain ++ * to any certificate in the trust store. */ ++int test_wolfSSL_PKCS7_verify_signer_forgery(void) ++{ ++ EXPECT_DECLS; ++#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) && !defined(NO_BIO) && \ ++ !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(HAVE_ECC) ++ static const byte forgedSignedData[] = { ++ 0x30, 0x82, 0x07, 0x9c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, ++ 0x01, 0x07, 0x02, 0xa0, 0x82, 0x07, 0x8d, 0x30, 0x82, 0x07, 0x89, 0x02, ++ 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, ++ 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x0e, 0x04, 0x0c, 0x48, 0x65, ++ 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0xa0, 0x82, ++ 0x06, 0xab, 0x30, 0x82, 0x04, 0xff, 0x30, 0x82, 0x03, 0xe7, 0xa0, 0x03, ++ 0x02, 0x01, 0x02, 0x02, 0x14, 0x3f, 0x29, 0x11, 0x20, 0x57, 0x71, 0xe7, ++ 0x8e, 0xf9, 0x18, 0x0d, 0xca, 0x70, 0x4d, 0x5b, 0x15, 0x2a, 0x43, 0xd6, ++ 0x24, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, ++ 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, ++ 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, ++ 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, ++ 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, ++ 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, 0x11, 0x30, 0x0f, ++ 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6f, ++ 0x6f, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, ++ 0x0c, 0x0a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, ++ 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, ++ 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, ++ 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, ++ 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, ++ 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, ++ 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x31, 0x31, 0x31, 0x33, 0x32, 0x30, 0x34, ++ 0x31, 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x38, 0x30, 0x39, ++ 0x32, 0x30, 0x34, 0x31, 0x31, 0x31, 0x5a, 0x30, 0x81, 0x94, 0x31, 0x0b, ++ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, ++ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, ++ 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, ++ 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, ++ 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x53, 0x61, ++ 0x77, 0x74, 0x6f, 0x6f, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, ++ 0x55, 0x04, 0x0b, 0x0c, 0x0a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, ++ 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, ++ 0x0c, 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, ++ 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, ++ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, ++ 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, ++ 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, ++ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, ++ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbf, ++ 0x0c, 0xca, 0x2d, 0x14, 0xb2, 0x1e, 0x84, 0x42, 0x5b, 0xcd, 0x38, 0x1f, ++ 0x4a, 0xf2, 0x4d, 0x75, 0x10, 0xf1, 0xb6, 0x35, 0x9f, 0xdf, 0xca, 0x7d, ++ 0x03, 0x98, 0xd3, 0xac, 0xde, 0x03, 0x66, 0xee, 0x2a, 0xf1, 0xd8, 0xb0, ++ 0x7d, 0x6e, 0x07, 0x54, 0x0b, 0x10, 0x98, 0x21, 0x4d, 0x80, 0xcb, 0x12, ++ 0x20, 0xe7, 0xcc, 0x4f, 0xde, 0x45, 0x7d, 0xc9, 0x72, 0x77, 0x32, 0xea, ++ 0xca, 0x90, 0xbb, 0x69, 0x52, 0x10, 0x03, 0x2f, 0xa8, 0xf3, 0x95, 0xc5, ++ 0xf1, 0x8b, 0x62, 0x56, 0x1b, 0xef, 0x67, 0x6f, 0xa4, 0x10, 0x41, 0x95, ++ 0xad, 0x0a, 0x9b, 0xe3, 0xa5, 0xc0, 0xb0, 0xd2, 0x70, 0x76, 0x50, 0x30, ++ 0x5b, 0xa8, 0xe8, 0x08, 0x2c, 0x7c, 0xed, 0xa7, 0xa2, 0x7a, 0x8d, 0x38, ++ 0x29, 0x1c, 0xac, 0xc7, 0xed, 0xf2, 0x7c, 0x95, 0xb0, 0x95, 0x82, 0x7d, ++ 0x49, 0x5c, 0x38, 0xcd, 0x77, 0x25, 0xef, 0xbd, 0x80, 0x75, 0x53, 0x94, ++ 0x3c, 0x3d, 0xca, 0x63, 0x5b, 0x9f, 0x15, 0xb5, 0xd3, 0x1d, 0x13, 0x2f, ++ 0x19, 0xd1, 0x3c, 0xdb, 0x76, 0x3a, 0xcc, 0xb8, 0x7d, 0xc9, 0xe5, 0xc2, ++ 0xd7, 0xda, 0x40, 0x6f, 0xd8, 0x21, 0xdc, 0x73, 0x1b, 0x42, 0x2d, 0x53, ++ 0x9c, 0xfe, 0x1a, 0xfc, 0x7d, 0xab, 0x7a, 0x36, 0x3f, 0x98, 0xde, 0x84, ++ 0x7c, 0x05, 0x67, 0xce, 0x6a, 0x14, 0x38, 0x87, 0xa9, 0xf1, 0x8c, 0xb5, ++ 0x68, 0xcb, 0x68, 0x7f, 0x71, 0x20, 0x2b, 0xf5, 0xa0, 0x63, 0xf5, 0x56, ++ 0x2f, 0xa3, 0x26, 0xd2, 0xb7, 0x6f, 0xb1, 0x5a, 0x17, 0xd7, 0x38, 0x99, ++ 0x08, 0xfe, 0x93, 0x58, 0x6f, 0xfe, 0xc3, 0x13, 0x49, 0x08, 0x16, 0x0b, ++ 0xa7, 0x4d, 0x67, 0x00, 0x52, 0x31, 0x67, 0x23, 0x4e, 0x98, 0xed, 0x51, ++ 0x45, 0x1d, 0xb9, 0x04, 0xd9, 0x0b, 0xec, 0xd8, 0x28, 0xb3, 0x4b, 0xbd, ++ 0xed, 0x36, 0x79, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x45, ++ 0x30, 0x82, 0x01, 0x41, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, ++ 0x16, 0x04, 0x14, 0x27, 0x8e, 0x67, 0x11, 0x74, 0xc3, 0x26, 0x1d, 0x3f, ++ 0xed, 0x33, 0x63, 0xb3, 0xa4, 0xd8, 0x1d, 0x30, 0xe5, 0xe8, 0xd5, 0x30, ++ 0x81, 0xd4, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xcc, 0x30, 0x81, ++ 0xc9, 0x80, 0x14, 0x27, 0x8e, 0x67, 0x11, 0x74, 0xc3, 0x26, 0x1d, 0x3f, ++ 0xed, 0x33, 0x63, 0xb3, 0xa4, 0xd8, 0x1d, 0x30, 0xe5, 0xe8, 0xd5, 0xa1, ++ 0x81, 0x9a, 0xa4, 0x81, 0x97, 0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, ++ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, ++ 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, 0x6e, 0x74, ++ 0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, ++ 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, 0x11, 0x30, ++ 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x53, 0x61, 0x77, 0x74, ++ 0x6f, 0x6f, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, ++ 0x0b, 0x0c, 0x0a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, ++ 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, ++ 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, ++ 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, ++ 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, ++ 0x82, 0x14, 0x3f, 0x29, 0x11, 0x20, 0x57, 0x71, 0xe7, 0x8e, 0xf9, 0x18, ++ 0x0d, 0xca, 0x70, 0x4d, 0x5b, 0x15, 0x2a, 0x43, 0xd6, 0x24, 0x30, 0x0c, ++ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, ++ 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x15, 0x30, 0x13, 0x82, ++ 0x0b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, ++ 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, ++ 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, ++ 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, ++ 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, ++ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x0f, 0xae, 0x89, ++ 0xd5, 0x68, 0xe4, 0x41, 0xf8, 0x9b, 0xe0, 0xc5, 0x61, 0x06, 0x57, 0xff, ++ 0xa0, 0x92, 0x0f, 0xb2, 0xed, 0xd3, 0x99, 0x5b, 0x99, 0x5e, 0x32, 0x7e, ++ 0x97, 0xc7, 0xaf, 0x6c, 0xfe, 0x8c, 0xa6, 0xae, 0x32, 0xa1, 0x0d, 0xca, ++ 0xcd, 0xfc, 0x18, 0xe5, 0xd1, 0xf8, 0x20, 0x5b, 0x5a, 0x38, 0x81, 0x46, ++ 0x5b, 0x48, 0x87, 0xa5, 0x3f, 0x3b, 0x7b, 0xc7, 0xea, 0xf5, 0x35, 0x29, ++ 0x31, 0x15, 0x39, 0x38, 0x5d, 0x48, 0xe6, 0x01, 0x81, 0x5c, 0x5e, 0x7c, ++ 0x10, 0xf5, 0x16, 0xe3, 0x59, 0xaf, 0x44, 0xc8, 0xb5, 0x8d, 0xc1, 0x32, ++ 0x23, 0xb3, 0xb8, 0x12, 0x6e, 0x5c, 0x8d, 0xe6, 0xc2, 0xd2, 0x41, 0x03, ++ 0xeb, 0x17, 0x42, 0xe2, 0x7f, 0xbc, 0x00, 0x5d, 0xa5, 0x31, 0xef, 0xc6, ++ 0x48, 0xee, 0xdb, 0xcc, 0xe0, 0xf1, 0x56, 0xf5, 0xd4, 0xca, 0x45, 0xa1, ++ 0x59, 0xb5, 0xe4, 0xd7, 0x60, 0x9c, 0x57, 0xe0, 0xa7, 0x5a, 0xf2, 0x35, ++ 0x1e, 0xa0, 0x22, 0xdb, 0x5e, 0x1c, 0x0c, 0x61, 0xbd, 0xa1, 0xc5, 0x7b, ++ 0x9f, 0x69, 0xf2, 0xd5, 0x95, 0xe2, 0xbc, 0x52, 0xb9, 0x1d, 0x9c, 0x2c, ++ 0xda, 0xb6, 0x73, 0x75, 0x4a, 0x84, 0xe5, 0x94, 0xb8, 0x19, 0x4d, 0xdd, ++ 0x70, 0xbd, 0x7f, 0x4c, 0xb9, 0x17, 0x6a, 0x58, 0x16, 0x89, 0x22, 0x44, ++ 0x37, 0x57, 0x55, 0x26, 0x42, 0xe3, 0xb7, 0xe5, 0xc7, 0x2b, 0x40, 0x0c, ++ 0xe9, 0xe4, 0x7f, 0x52, 0x75, 0xdf, 0x06, 0xc9, 0xfb, 0x01, 0x44, 0x34, ++ 0xac, 0x20, 0x3c, 0xb4, 0xbe, 0x2b, 0x3e, 0xef, 0x85, 0x38, 0x96, 0x5b, ++ 0x9b, 0x1e, 0x25, 0x86, 0x18, 0x4c, 0xa4, 0x06, 0x70, 0x06, 0x6a, 0xc8, ++ 0x4b, 0x6f, 0x5f, 0xc4, 0x05, 0x1f, 0x03, 0x62, 0x30, 0x11, 0x61, 0xbc, ++ 0xc1, 0x40, 0x31, 0x66, 0xdc, 0x64, 0xf0, 0x4f, 0x6b, 0xb9, 0xec, 0xc8, ++ 0x29, 0x30, 0x82, 0x01, 0xa4, 0x30, 0x82, 0x01, 0x49, 0xa0, 0x03, 0x02, ++ 0x01, 0x02, 0x02, 0x14, 0x62, 0x4d, 0x11, 0x9c, 0xcf, 0x5d, 0xe5, 0x71, ++ 0xa2, 0x82, 0xd9, 0x8f, 0xe0, 0x04, 0xb8, 0x5f, 0x0e, 0x4d, 0x07, 0xad, ++ 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, ++ 0x30, 0x27, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, ++ 0x08, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x31, 0x12, 0x30, ++ 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x75, 0x6e, 0x74, 0x72, ++ 0x75, 0x73, 0x74, 0x65, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, ++ 0x34, 0x32, 0x31, 0x31, 0x31, 0x31, 0x36, 0x32, 0x38, 0x5a, 0x17, 0x0d, ++ 0x33, 0x36, 0x30, 0x34, 0x31, 0x38, 0x31, 0x31, 0x31, 0x36, 0x32, 0x38, ++ 0x5a, 0x30, 0x27, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, ++ 0x0c, 0x08, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x31, 0x12, ++ 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x75, 0x6e, 0x74, ++ 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, ++ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, ++ 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xae, 0xdb, 0xf7, ++ 0x3b, 0x7e, 0x82, 0x88, 0xfc, 0x1a, 0xfb, 0x86, 0x56, 0x83, 0x03, 0xdd, ++ 0x05, 0x14, 0x79, 0x51, 0x0f, 0x3c, 0x86, 0x85, 0x2d, 0xeb, 0x18, 0x17, ++ 0x20, 0x3b, 0x37, 0x6f, 0x7f, 0x78, 0x19, 0x3b, 0xf6, 0x71, 0xad, 0xc9, ++ 0x65, 0x81, 0x7e, 0xe0, 0xa9, 0x29, 0xdd, 0xfd, 0xf0, 0xff, 0x04, 0x7d, ++ 0x5a, 0x59, 0xd6, 0x6c, 0xe2, 0xde, 0xc5, 0xd5, 0xb6, 0x1f, 0x69, 0xd9, ++ 0x33, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, ++ 0x04, 0x16, 0x04, 0x14, 0xf7, 0xab, 0x3f, 0x49, 0xcf, 0x7d, 0x48, 0x9c, ++ 0x04, 0x49, 0x1a, 0xac, 0x8f, 0x26, 0x16, 0x09, 0xa8, 0x2a, 0x74, 0xf5, ++ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, ++ 0x14, 0xf7, 0xab, 0x3f, 0x49, 0xcf, 0x7d, 0x48, 0x9c, 0x04, 0x49, 0x1a, ++ 0xac, 0x8f, 0x26, 0x16, 0x09, 0xa8, 0x2a, 0x74, 0xf5, 0x30, 0x0f, 0x06, ++ 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, ++ 0x01, 0xff, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, ++ 0x03, 0x02, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x8d, 0xbf, ++ 0x36, 0xe5, 0x51, 0x9a, 0xde, 0xf4, 0x7f, 0xbf, 0xbd, 0x7f, 0x71, 0x66, ++ 0xc1, 0x67, 0xfa, 0x71, 0x0d, 0x79, 0xc6, 0x60, 0x3a, 0x6c, 0xeb, 0x43, ++ 0xc3, 0xf2, 0x5e, 0xe8, 0x74, 0xb6, 0x02, 0x21, 0x00, 0xfa, 0xdb, 0x40, ++ 0x47, 0x72, 0xf0, 0x15, 0x52, 0xc1, 0x78, 0x11, 0x6b, 0x76, 0xc5, 0x1f, ++ 0xcf, 0xb6, 0x09, 0x6d, 0x8f, 0xcb, 0x92, 0x2f, 0x1b, 0x3c, 0xc3, 0x28, ++ 0x48, 0x61, 0x0f, 0x60, 0x71, 0x31, 0x81, 0xa8, 0x30, 0x81, 0xa5, 0x02, ++ 0x01, 0x01, 0x30, 0x3f, 0x30, 0x27, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, ++ 0x55, 0x04, 0x03, 0x0c, 0x08, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x65, ++ 0x72, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, ++ 0x75, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x02, 0x14, 0x62, ++ 0x4d, 0x11, 0x9c, 0xcf, 0x5d, 0xe5, 0x71, 0xa2, 0x82, 0xd9, 0x8f, 0xe0, ++ 0x04, 0xb8, 0x5f, 0x0e, 0x4d, 0x07, 0xad, 0x30, 0x0b, 0x06, 0x09, 0x60, ++ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, ++ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x46, 0x30, 0x44, ++ 0x02, 0x20, 0x22, 0x4a, 0x99, 0xb1, 0xbc, 0xa9, 0xee, 0x24, 0x60, 0x81, ++ 0xb9, 0x64, 0xba, 0x86, 0x00, 0xae, 0xb5, 0xd7, 0xb8, 0x72, 0xb9, 0x8c, ++ 0xb3, 0xe7, 0x78, 0x29, 0xdb, 0xa8, 0x27, 0xf7, 0x30, 0xf0, 0x02, 0x20, ++ 0x19, 0x2d, 0xd3, 0x17, 0x9a, 0xc1, 0xf9, 0xd2, 0x63, 0x92, 0x8e, 0x78, ++ 0xcc, 0xa4, 0x0b, 0x91, 0x12, 0xa5, 0xb2, 0xbc, 0x35, 0x87, 0x8e, 0x33, ++ 0xa7, 0xe0, 0x5e, 0xab, 0x95, 0xb2, 0x2a, 0xf4 ++ }; ++ PKCS7* p7 = NULL; ++ X509_STORE* store = NULL; ++ X509* caCert = NULL; ++ WOLFSSL_BIO* caBio = NULL; ++ const byte* p = forgedSignedData; ++ const char* ca = "./certs/ca-cert.pem"; ++ ++ /* Load the same CA into the trust store that the attacker bundled at ++ * cert[0] in the forged message. */ ++ ExpectNotNull(caBio = BIO_new_file(ca, "r")); ++ ExpectNotNull(caCert = PEM_read_bio_X509(caBio, NULL, 0, NULL)); ++ ExpectNotNull(store = X509_STORE_new()); ++ ExpectIntEQ(X509_STORE_add_cert(store, caCert), 1); ++ ++ /* Parse the forged message. d2i_PKCS7 internally runs ++ * wc_PKCS7_VerifySignedData, which must NOT accept the attacker's ++ * signature under any bundled cert other than the one named by the ++ * signerInfo sid. Since the sid names the attacker cert (which does ++ * not chain to the trusted CA), the parse may succeed but verification ++ * against the trust store must fail. */ ++ ExpectNotNull(p7 = d2i_PKCS7(NULL, &p, (int)sizeof(forgedSignedData))); ++ ++ /* PKCS7_verify() MUST fail: the only certificate in the trust store ++ * is the wolfSSL CA - it is bundled at cert[0] but did NOT sign this ++ * message. The actual signer (the attacker's self-signed cert at ++ * cert[1]) cannot chain to any trust anchor. */ ++ ExpectIntEQ(PKCS7_verify(p7, NULL, store, NULL, NULL, 0), ++ WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); ++ ++ PKCS7_free(p7); ++ X509_STORE_free(store); ++ X509_free(caCert); ++ BIO_free(caBio); ++#endif ++ return EXPECT_RESULT(); ++} ++ ++/* Exercise the SignerInfo-sid binding enforcement end-to-end. ++ * ++ * For both supported sid encodings (v1 = IssuerAndSerialNumber, v3 = ++ * SubjectKeyIdentifier), this builds a valid CMS SignedData message with ++ * two certificates in the bundle: ++ * cert[0] = ca-cert (extra, non-signing) ++ * cert[1] = server-cert (actual signer) ++ * and checks that: ++ * - parsing + signature verification succeeds, ++ * - chain validation against a trust store containing ca-cert succeeds, ++ * - PKCS7_get0_signers() returns the *signer* (server-cert), not the ++ * extra cert at cert[0] - which would be the pre-fix behavior and the ++ * core of the signer-identity forgery bug. */ ++int test_wolfSSL_PKCS7_verify_sid_binding(void) ++{ ++ EXPECT_DECLS; ++#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) && !defined(NO_BIO) && \ ++ !defined(NO_FILESYSTEM) && !defined(NO_RSA) ++ const char* signerCertFile = "./certs/server-cert.pem"; ++ const char* signerKeyFile = "./certs/server-key.pem"; ++ const char* caFile = "./certs/ca-cert.pem"; ++ const byte content[] = "sid-binding test content"; ++ /* Build both variants: default v1 (IssuerAndSerialNumber) and v3 ++ * (SubjectKeyIdentifier). */ ++ const int sidTypes[2] = { CMS_ISSUER_AND_SERIAL_NUMBER, CMS_SKID }; ++ int variant; ++ ++ BIO* signerCertBio = NULL; ++ BIO* caBio = NULL; ++ X509* signerCertX509 = NULL; ++ X509* caX509 = NULL; ++ byte* signerCertDer = NULL; ++ byte* caDer = NULL; ++ byte* signerKey = NULL; ++ int signerCertDerSz = 0; ++ int caDerSz = 0; ++ size_t signerKeySz = 0; ++ XFILE keyFile = XBADFILE; ++ WC_RNG rng; ++ int rngInited = 0; ++ ++ /* ---- Load signer cert + key and the CA cert. ---- */ ++ ExpectNotNull(signerCertBio = BIO_new_file(signerCertFile, "r")); ++ ExpectNotNull(signerCertX509 = PEM_read_bio_X509(signerCertBio, NULL, 0, ++ NULL)); ++ ExpectIntGT(signerCertDerSz = i2d_X509(signerCertX509, &signerCertDer), 0); ++ ++ ExpectNotNull(caBio = BIO_new_file(caFile, "r")); ++ ExpectNotNull(caX509 = PEM_read_bio_X509(caBio, NULL, 0, NULL)); ++ ExpectIntGT(caDerSz = i2d_X509(caX509, &caDer), 0); ++ ++ /* Slurp the DER private key straight from a PEM->DER round-trip via ++ * wc_KeyPemToDer. The test only needs the bytes in a form ++ * wc_PKCS7_EncodeSignedData can consume. */ ++ { ++ long filePemLen = 0; ++ byte* keyPem = NULL; ++ int derLen = 0; ++ ++ ExpectTrue((keyFile = XFOPEN(signerKeyFile, "rb")) != XBADFILE); ++ if (keyFile != XBADFILE) { ++ (void)XFSEEK(keyFile, 0, XSEEK_END); ++ filePemLen = XFTELL(keyFile); ++ (void)XFSEEK(keyFile, 0, XSEEK_SET); ++ ExpectIntGT(filePemLen, 0); ++ keyPem = (byte*)XMALLOC((size_t)filePemLen, NULL, ++ DYNAMIC_TYPE_TMP_BUFFER); ++ ExpectNotNull(keyPem); ++ if (keyPem != NULL) { ++ ExpectIntEQ(XFREAD(keyPem, 1, (size_t)filePemLen, keyFile), ++ (size_t)filePemLen); ++ /* First call sizes the output buffer. */ ++ derLen = wc_KeyPemToDer(keyPem, (word32)filePemLen, NULL, 0, ++ NULL); ++ ExpectIntGT(derLen, 0); ++ if (derLen > 0) { ++ signerKey = (byte*)XMALLOC((size_t)derLen, NULL, ++ DYNAMIC_TYPE_TMP_BUFFER); ++ ExpectNotNull(signerKey); ++ if (signerKey != NULL) { ++ derLen = wc_KeyPemToDer(keyPem, (word32)filePemLen, ++ signerKey, (word32)derLen, ++ NULL); ++ ExpectIntGT(derLen, 0); ++ signerKeySz = (size_t)derLen; ++ } ++ } ++ } ++ XFREE(keyPem, NULL, DYNAMIC_TYPE_TMP_BUFFER); ++ XFCLOSE(keyFile); ++ keyFile = XBADFILE; ++ } ++ } ++ ++ ExpectIntEQ(wc_InitRng(&rng), 0); ++ if (EXPECT_SUCCESS()) ++ rngInited = 1; ++ ++ for (variant = 0; variant < 2; variant++) { ++ wc_PKCS7* p7Enc = NULL; ++ byte encoded[4096]; ++ int encodedSz = 0; ++ PKCS7* p7Ver = NULL; ++ X509_STORE* store = NULL; ++ const byte* encodedPtr = NULL; ++ STACK_OF(X509)* signers = NULL; ++ X509* reportedSigner = NULL; ++ byte* reportedSignerDer = NULL; ++ int reportedSignerDerSz = 0; ++ X509* caForStore = NULL; ++ BIO* caForStoreBio = NULL; ++ ++ /* ---- Encode: signer=server-cert, extra bundle cert=ca. ---- */ ++ ExpectNotNull(p7Enc = wc_PKCS7_New(HEAP_HINT, INVALID_DEVID)); ++ ExpectIntEQ(wc_PKCS7_Init(p7Enc, HEAP_HINT, INVALID_DEVID), 0); ++ ExpectIntEQ(wc_PKCS7_InitWithCert(p7Enc, signerCertDer, ++ (word32)signerCertDerSz), 0); ++ /* wc_PKCS7_AddCertificate prepends to the cert list - the encoded ++ * SET therefore ends up [ca, signer], putting the actual signer ++ * at index 1 and exercising the sid-selection path (cert[0] is ++ * NOT the signer and must be skipped). */ ++ ExpectIntEQ(wc_PKCS7_AddCertificate(p7Enc, caDer, (word32)caDerSz), 0); ++ ++ if (p7Enc != NULL) { ++ p7Enc->content = (byte*)content; ++ p7Enc->contentSz = (word32)sizeof(content); ++ p7Enc->encryptOID = RSAk; ++ p7Enc->hashOID = SHA256h; ++ p7Enc->privateKey = signerKey; ++ p7Enc->privateKeySz = (word32)signerKeySz; ++ p7Enc->rng = &rng; ++ } ++ ++ ExpectIntEQ(wc_PKCS7_SetSignerIdentifierType(p7Enc, sidTypes[variant]), ++ 0); ++ ++ ExpectIntGT((encodedSz = wc_PKCS7_EncodeSignedData(p7Enc, encoded, ++ sizeof(encoded))), ++ 0); ++ wc_PKCS7_Free(p7Enc); ++ p7Enc = NULL; ++ ++ /* ---- Parse + verify through the OpenSSL compat layer. ---- */ ++ encodedPtr = encoded; ++ ExpectNotNull(p7Ver = d2i_PKCS7(NULL, &encodedPtr, encodedSz)); ++ ++ /* Trust store holds only ca-cert. Reload it rather than reusing ++ * caX509, since X509_STORE_free takes ownership-like semantics. */ ++ ExpectNotNull(caForStoreBio = BIO_new_file(caFile, "r")); ++ ExpectNotNull(caForStore = PEM_read_bio_X509(caForStoreBio, NULL, 0, ++ NULL)); ++ ExpectNotNull(store = X509_STORE_new()); ++ ExpectIntEQ(X509_STORE_add_cert(store, caForStore), 1); ++ ++ ExpectIntEQ(PKCS7_verify(p7Ver, NULL, store, NULL, NULL, 0), 1); ++ ++ /* Snapshot the singleCert / verifyCert pointers and sizes after ++ * PKCS7_verify has finished re-parsing the message. A buggy ++ * implementation that passes &p7->pkcs7.singleCert (or verifyCert) ++ * directly to wolfSSL_d2i_X509 permanently advances the struct ++ * field, which corrupts it for any subsequent use - producing a ++ * heap-OOB read on the next call since the size isn't advanced. ++ * These pointers must stay exactly where they are across repeated ++ * get0_signers calls. */ ++ if (p7Ver != NULL) { ++ wc_PKCS7* wcP7 = &((WOLFSSL_PKCS7*)p7Ver)->pkcs7; ++ byte* singleBefore = wcP7->singleCert; ++ word32 singleSzBefore = wcP7->singleCertSz; ++ byte* verifyBefore = wcP7->verifyCert; ++ word32 verifySzBefore = wcP7->verifyCertSz; ++ int i; ++ ++ /* Call get0_signers repeatedly. Each invocation must return ++ * the correct cert and must not mutate singleCert/verifyCert. ++ * Three iterations so the "second call reads past the end" ++ * pattern (the exact OOB the reporter hit) is exercised. */ ++ for (i = 0; i < 3; i++) { ++ ExpectNotNull(signers = PKCS7_get0_signers(p7Ver, NULL, 0)); ++ ExpectIntEQ(sk_X509_num(signers), 1); ++ ExpectNotNull(reportedSigner = sk_X509_value(signers, 0)); ++ ExpectIntGT(reportedSignerDerSz = i2d_X509(reportedSigner, ++ &reportedSignerDer), 0); ++ /* DER-compare: reportedSigner must equal server-cert and ++ * must NOT equal ca-cert (the pre-fix signer-confusion ++ * outcome). */ ++ ExpectIntEQ(reportedSignerDerSz, signerCertDerSz); ++ if (reportedSignerDer != NULL && signerCertDer != NULL) { ++ ExpectIntEQ(XMEMCMP(reportedSignerDer, signerCertDer, ++ (size_t)signerCertDerSz), 0); ++ if (reportedSignerDerSz == caDerSz) { ++ ExpectIntNE(XMEMCMP(reportedSignerDer, caDer, ++ (size_t)caDerSz), 0); ++ } ++ } ++ XFREE(reportedSignerDer, NULL, DYNAMIC_TYPE_OPENSSL); ++ reportedSignerDer = NULL; ++ sk_X509_pop_free(signers, NULL); ++ signers = NULL; ++ ++ /* Struct fields must survive every call unchanged. */ ++ ExpectPtrEq(wcP7->singleCert, singleBefore); ++ ExpectIntEQ(wcP7->singleCertSz, singleSzBefore); ++ ExpectPtrEq(wcP7->verifyCert, verifyBefore); ++ ExpectIntEQ(wcP7->verifyCertSz, verifySzBefore); ++ } ++ } ++ ++ PKCS7_free(p7Ver); ++ X509_STORE_free(store); ++ X509_free(caForStore); ++ BIO_free(caForStoreBio); ++ } ++ ++ if (rngInited) ++ wc_FreeRng(&rng); ++ ++ XFREE(signerKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); ++ XFREE(signerCertDer, NULL, DYNAMIC_TYPE_OPENSSL); ++ XFREE(caDer, NULL, DYNAMIC_TYPE_OPENSSL); ++ X509_free(signerCertX509); ++ X509_free(caX509); ++ BIO_free(signerCertBio); ++ BIO_free(caBio); ++#endif ++ return EXPECT_RESULT(); ++} ++ + int test_wolfSSL_PKCS7_SIGNED_new(void) + { + EXPECT_DECLS; +diff --git a/tests/api/test_ossl_p7p12.h b/tests/api/test_ossl_p7p12.h +index 58aa9dd12..6704ab51e 100644 +--- a/tests/api/test_ossl_p7p12.h ++++ b/tests/api/test_ossl_p7p12.h +@@ -27,6 +27,8 @@ + int test_wolfssl_PKCS7(void); + int test_wolfSSL_PKCS7_certs(void); + int test_wolfSSL_PKCS7_sign(void); ++int test_wolfSSL_PKCS7_verify_signer_forgery(void); ++int test_wolfSSL_PKCS7_verify_sid_binding(void); + int test_wolfSSL_PKCS7_SIGNED_new(void); + int test_wolfSSL_PEM_write_bio_PKCS7(void); + int test_wolfSSL_PEM_write_bio_encryptedKey(void); +@@ -38,6 +40,8 @@ int test_wolfSSL_PKCS12(void); + TEST_DECL_GROUP("ossl_p7", test_wolfssl_PKCS7), \ + TEST_DECL_GROUP("ossl_p7", test_wolfSSL_PKCS7_certs), \ + TEST_DECL_GROUP("ossl_p7", test_wolfSSL_PKCS7_sign), \ ++ TEST_DECL_GROUP("ossl_p7", test_wolfSSL_PKCS7_verify_signer_forgery), \ ++ TEST_DECL_GROUP("ossl_p7", test_wolfSSL_PKCS7_verify_sid_binding), \ + TEST_DECL_GROUP("ossl_p7", test_wolfSSL_PKCS7_SIGNED_new), \ + TEST_DECL_GROUP("ossl_p7", test_wolfSSL_PEM_write_bio_PKCS7), \ + TEST_DECL_GROUP("ossl_p7", test_wolfSSL_PEM_write_bio_encryptedKey), \ +diff --git a/tests/api/test_pkcs7.c b/tests/api/test_pkcs7.c +index 3c8b59fb8..69b463160 100644 +--- a/tests/api/test_pkcs7.c ++++ b/tests/api/test_pkcs7.c +@@ -1118,6 +1118,229 @@ int test_wc_PKCS7_EnvelopedData_KTRI_RSA_PSS(void) + #endif + + ++/* ++ * Bleichenbacher padding-oracle regression: wc_PKCS7_DecryptKtri must not ++ * return a distinguishable error when RSA PKCS#1 v1.5 unwrap of the ++ * encrypted CEK fails vs. when it succeeds with a wrong key. The ++ * mitigation substitutes a deterministic pseudo-random CEK on RSA failure ++ * so content decryption fails indistinguishably. This test corrupts the ++ * encryptedKey in a valid EnvelopedData and asserts the error matches ++ * content corruption rather than surfacing an RSA/recipient-level code. ++ * Runs for AES-128 and AES-256 because the fake CEK is a fixed 32 bytes: ++ * AES-128 (key size 16) exercises the path where the fake size differs ++ * from the real CEK size. ++ */ ++#if defined(HAVE_PKCS7) && !defined(NO_RSA) && !defined(NO_SHA256) && \ ++ !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128) && \ ++ defined(WOLFSSL_AES_256) && !defined(NO_HMAC) && \ ++ !defined(WOLFSSL_NO_MALLOC) && \ ++ (defined(USE_CERT_BUFFERS_2048) || defined(USE_CERT_BUFFERS_1024) || \ ++ !defined(NO_FILESYSTEM)) ++static int pkcs7_ktri_bad_pad_case(int encryptOID, byte* rsaCert, ++ word32 rsaCertSz, byte* rsaPrivKey, ++ word32 rsaPrivKeySz, byte* encrypted, ++ word32 encryptedCap, byte* decoded, ++ word32 decodedCap) ++{ ++ EXPECT_DECLS; ++ PKCS7* pkcs7 = NULL; ++ byte data[] = "PKCS7 KTRI bad-RSA-padding regression payload."; ++ int encryptedSz = 0; ++ int badKeyRet = 0; ++ int badContentRet = 0; ++ byte savedKeyByte = 0; ++ byte savedContentByte = 0; ++ word32 i; ++ word32 encryptedKeyOff = 0; ++ static const byte rsaEncOid[] = { ++ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, ++ 0x01, 0x01, 0x01 ++ }; ++ ++ ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); ++ ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, rsaCert, rsaCertSz), 0); ++ if (pkcs7 != NULL) { ++ pkcs7->content = data; ++ pkcs7->contentSz = (word32)sizeof(data); ++ pkcs7->contentOID = DATA; ++ pkcs7->encryptOID = encryptOID; ++ } ++ ExpectIntGT(encryptedSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, ++ encrypted, encryptedCap), 0); ++ wc_PKCS7_Free(pkcs7); ++ pkcs7 = NULL; ++ ++ /* Locate the KTRI encryptedKey OCTET STRING. After the rsaEncryption ++ * OID there are NULL algorithm parameters (05 00), then a 256-byte ++ * OCTET STRING (tag 04, long-form length 82 01 00 for RSA-2048). */ ++ for (i = 0; (int)(i + sizeof(rsaEncOid)) < encryptedSz; i++) { ++ if (XMEMCMP(&encrypted[i], rsaEncOid, sizeof(rsaEncOid)) == 0) { ++ word32 p = i + (word32)sizeof(rsaEncOid); ++ if (p + 2 < (word32)encryptedSz && ++ encrypted[p] == 0x05 && encrypted[p + 1] == 0x00) { ++ p += 2; ++ } ++ if (p + 4 < (word32)encryptedSz && encrypted[p] == 0x04) { ++ if (encrypted[p + 1] == 0x82) { ++ encryptedKeyOff = p + 4; ++ } ++ else if (encrypted[p + 1] == 0x81) { ++ encryptedKeyOff = p + 3; ++ } ++ else { ++ encryptedKeyOff = p + 2; ++ } ++ } ++ break; ++ } ++ } ++ ExpectIntGT(encryptedKeyOff, 0); ++ ExpectIntLT(encryptedKeyOff + 32, (word32)encryptedSz); ++ ++ /* Case 1: corrupt a byte inside the RSA ciphertext, decode, restore. */ ++ savedKeyByte = encrypted[encryptedKeyOff + 16]; ++ encrypted[encryptedKeyOff + 16] ^= 0xA5; ++ ++ ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); ++ ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, rsaCert, rsaCertSz), 0); ++ if (pkcs7 != NULL) { ++ pkcs7->privateKey = rsaPrivKey; ++ pkcs7->privateKeySz = rsaPrivKeySz; ++ } ++ badKeyRet = wc_PKCS7_DecodeEnvelopedData(pkcs7, encrypted, ++ (word32)encryptedSz, decoded, decodedCap); ++ wc_PKCS7_Free(pkcs7); ++ pkcs7 = NULL; ++ encrypted[encryptedKeyOff + 16] = savedKeyByte; ++ ++ /* Case 2: corrupt a byte in the second-to-last AES ciphertext block. ++ * In CBC mode this deterministically XOR-flips the corresponding byte ++ * in the last plaintext block, invalidating the PKCS#7 padding ++ * (original pad byte 0x01 becomes 0x01^0xA5 = 0xA4 > blockSz). ++ * Corrupting the last ciphertext block directly would randomize the ++ * entire last plaintext block, giving ~1/256 chance of accidentally ++ * valid padding and intermittent test failures. */ ++ savedContentByte = encrypted[encryptedSz - 17]; ++ encrypted[encryptedSz - 17] ^= 0xA5; ++ ++ ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); ++ ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, rsaCert, rsaCertSz), 0); ++ if (pkcs7 != NULL) { ++ pkcs7->privateKey = rsaPrivKey; ++ pkcs7->privateKeySz = rsaPrivKeySz; ++ } ++ badContentRet = wc_PKCS7_DecodeEnvelopedData(pkcs7, encrypted, ++ (word32)encryptedSz, decoded, decodedCap); ++ wc_PKCS7_Free(pkcs7); ++ pkcs7 = NULL; ++ encrypted[encryptedSz - 17] = savedContentByte; ++ ++ /* Case 2 must always fail: the CBC-chain corruption deterministically ++ * invalidates the PKCS#7 padding. */ ++ ExpectIntLT(badContentRet, 0); ++ /* Bad-key must NOT leak as an RSA- or recipient-level error. */ ++ ExpectIntNE(badKeyRet, WC_NO_ERR_TRACE(PKCS7_RECIP_E)); ++ ExpectIntNE(badKeyRet, WC_NO_ERR_TRACE(RSA_PAD_E)); ++ ExpectIntNE(badKeyRet, WC_NO_ERR_TRACE(RSA_BUFFER_E)); ++ ExpectIntNE(badKeyRet, WC_NO_ERR_TRACE(BAD_PADDING_E)); ++ /* Case 1 (bad RSA key) decrypts content with a random fake CEK, ++ * producing fully random plaintext. With ~1/256 probability the ++ * PKCS#7 padding accidentally looks valid, causing a positive ++ * garbage-length return instead of an error. This does not leak ++ * RSA key information, so it is acceptable. When both cases do ++ * fail, verify they fail at the same content-decryption layer. */ ++ if (badKeyRet < 0) { ++ ExpectIntEQ(badKeyRet, badContentRet); ++ } ++ ++ return EXPECT_RESULT(); ++} ++ ++int test_wc_PKCS7_EnvelopedData_KTRI_BadRsaPad(void) ++{ ++ EXPECT_DECLS; ++ byte encrypted[FOURK_BUF]; ++ byte decoded[FOURK_BUF]; ++ byte* rsaCert = NULL; ++ byte* rsaPrivKey = NULL; ++ word32 rsaCertSz = 0; ++ word32 rsaPrivKeySz = 0; ++#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \ ++ !defined(NO_FILESYSTEM) ++ XFILE f = XBADFILE; ++#endif ++ ++ /* Load RSA cert and key */ ++#if defined(USE_CERT_BUFFERS_1024) ++ rsaCertSz = (word32)sizeof_client_cert_der_1024; ++ ExpectNotNull(rsaCert = (byte*)XMALLOC(rsaCertSz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (rsaCert != NULL) ++ XMEMCPY(rsaCert, client_cert_der_1024, rsaCertSz); ++ rsaPrivKeySz = (word32)sizeof_client_key_der_1024; ++ ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(rsaPrivKeySz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (rsaPrivKey != NULL) ++ XMEMCPY(rsaPrivKey, client_key_der_1024, rsaPrivKeySz); ++#elif defined(USE_CERT_BUFFERS_2048) ++ rsaCertSz = (word32)sizeof_client_cert_der_2048; ++ ExpectNotNull(rsaCert = (byte*)XMALLOC(rsaCertSz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (rsaCert != NULL) ++ XMEMCPY(rsaCert, client_cert_der_2048, rsaCertSz); ++ rsaPrivKeySz = (word32)sizeof_client_key_der_2048; ++ ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(rsaPrivKeySz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ if (rsaPrivKey != NULL) ++ XMEMCPY(rsaPrivKey, client_key_der_2048, rsaPrivKeySz); ++#elif !defined(NO_FILESYSTEM) ++ rsaCertSz = FOURK_BUF; ++ ExpectNotNull(rsaCert = (byte*)XMALLOC(rsaCertSz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ ExpectTrue((f = XFOPEN("./certs/client-cert.der", "rb")) != XBADFILE); ++ ExpectTrue((rsaCertSz = (word32)XFREAD(rsaCert, 1, rsaCertSz, f)) > 0); ++ if (f != XBADFILE) { ++ XFCLOSE(f); ++ f = XBADFILE; ++ } ++ rsaPrivKeySz = FOURK_BUF; ++ ExpectNotNull(rsaPrivKey = (byte*)XMALLOC(rsaPrivKeySz, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ ExpectTrue((f = XFOPEN("./certs/client-key.der", "rb")) != XBADFILE); ++ ExpectTrue((rsaPrivKeySz = (word32)XFREAD(rsaPrivKey, 1, ++ rsaPrivKeySz, f)) > 0); ++ if (f != XBADFILE) ++ XFCLOSE(f); ++#endif ++ ++ if (rsaCert == NULL || rsaPrivKey == NULL) { ++ XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ return TEST_SKIPPED; ++ } ++ ++ /* AES-128: 32-byte fake CEK larger than real CEK size (16 bytes). */ ++ ExpectIntEQ(pkcs7_ktri_bad_pad_case(AES128CBCb, rsaCert, rsaCertSz, ++ rsaPrivKey, rsaPrivKeySz, encrypted, sizeof(encrypted), ++ decoded, sizeof(decoded)), TEST_SUCCESS); ++#ifdef WOLFSSL_AES_192 ++ /* AES-192: fake CEK (32) vs real CEK (24) - another size mismatch. */ ++ ExpectIntEQ(pkcs7_ktri_bad_pad_case(AES192CBCb, rsaCert, rsaCertSz, ++ rsaPrivKey, rsaPrivKeySz, encrypted, sizeof(encrypted), ++ decoded, sizeof(decoded)), TEST_SUCCESS); ++#endif ++ /* AES-256: fake CEK size matches real CEK size (32 bytes). */ ++ ExpectIntEQ(pkcs7_ktri_bad_pad_case(AES256CBCb, rsaCert, rsaCertSz, ++ rsaPrivKey, rsaPrivKeySz, encrypted, sizeof(encrypted), ++ decoded, sizeof(decoded)), TEST_SUCCESS); ++ ++ XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ return EXPECT_RESULT(); ++} /* END test_wc_PKCS7_EnvelopedData_KTRI_BadRsaPad */ ++#endif ++ ++ + /* + * Testing wc_PKCS7_EncodeSignedData_ex() and wc_PKCS7_VerifySignedData_ex() + */ +@@ -2397,7 +2620,8 @@ static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId, + HAVE_AES_KEYWRAP */ + + +-#if defined(HAVE_PKCS7) && defined(ASN_BER_TO_DER) && !defined(NO_RSA) ++#if defined(HAVE_PKCS7) && defined(ASN_BER_TO_DER) && !defined(NO_RSA) && \ ++ !defined(NO_PKCS7_STREAM) + #define MAX_TEST_DECODE_SIZE 6000 + static int test_wc_PKCS7_DecodeEnvelopedData_stream_decrypt_cb(wc_PKCS7* pkcs7, + const byte* output, word32 outputSz, void* ctx) { +@@ -2430,7 +2654,8 @@ static int test_wc_PKCS7_DecodeEnvelopedData_stream_decrypt_cb(wc_PKCS7* pkcs7, + int test_wc_PKCS7_DecodeEnvelopedData_stream(void) + { + EXPECT_DECLS; +-#if defined(HAVE_PKCS7) && defined(ASN_BER_TO_DER) && !defined(NO_RSA) ++#if defined(HAVE_PKCS7) && defined(ASN_BER_TO_DER) && !defined(NO_RSA) && \ ++ !defined(NO_PKCS7_STREAM) + PKCS7* pkcs7 = NULL; + int ret = 0; + XFILE f = XBADFILE; +@@ -2486,6 +2711,72 @@ int test_wc_PKCS7_DecodeEnvelopedData_stream(void) + } /* END test_wc_PKCS7_DecodeEnvelopedData_stream() */ + + ++/* ++ * Regression test: a PKCS#7 EnvelopedData with a forged RecipientInfo SET ++ * length (parsed via GetSet_ex with NO_USER_CHECK) must not drive an ++ * uncapped heap allocation through wc_PKCS7_GrowStream(). The decoder ++ * must reject the oversized allocation rather than attempting it. ++ */ ++int test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen(void) ++{ ++ EXPECT_DECLS; ++#if defined(HAVE_PKCS7) && !defined(NO_RSA) && !defined(NO_PKCS7_STREAM) ++ /* Crafted ContentInfo/EnvelopedData header. All lengths use the ++ * 4-byte long form for clarity. The RecipientInfo SET length is ++ * forged to 0x01000001 (16 MB + 1), which exceeds the default ++ * WOLFSSL_PKCS7_MAX_STREAM_ALLOC cap and should be rejected before ++ * any allocation succeeds. The body after the SET header is never ++ * consumed because the decoder fails at the GrowStream() cap. */ ++ static const byte forged[] = { ++ /* ContentInfo SEQUENCE, body length 0x01000021 */ ++ 0x30, 0x84, 0x01, 0x00, 0x00, 0x21, ++ /* OID 1.2.840.113549.1.7.3 (id-envelopedData) */ ++ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, ++ 0x01, 0x07, 0x03, ++ /* [0] EXPLICIT content, body length 0x01000016 */ ++ 0xA0, 0x84, 0x01, 0x00, 0x00, 0x16, ++ /* EnvelopedData SEQUENCE, body length 0x01000010 */ ++ 0x30, 0x84, 0x01, 0x00, 0x00, 0x10, ++ /* version INTEGER 0 */ ++ 0x02, 0x01, 0x00, ++ /* Forged RecipientInfo SET header: length = 0x01000001 */ ++ 0x31, 0x84, 0x01, 0x00, 0x00, 0x01, ++ /* Padding so that header-parsing states can buffer their ++ * required lookahead without returning WC_PKCS7_WANT_READ_E. ++ * These bytes are never interpreted. */ ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ++ }; ++ PKCS7* pkcs7 = NULL; ++ byte out[32]; ++ int ret; ++ ++ ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); ++ ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)client_cert_der_2048, ++ sizeof_client_cert_der_2048), 0); ++ ExpectIntEQ(wc_PKCS7_SetKey(pkcs7, (byte*)client_key_der_2048, ++ sizeof_client_key_der_2048), 0); ++ ++ ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, (byte*)forged, ++ (word32)sizeof(forged), out, (word32)sizeof(out)); ++ /* Must NOT return WC_PKCS7_WANT_READ_E (which would imply the ++ * oversized allocation succeeded and the decoder is waiting for ++ * the around 16 MB of SET body). Must NOT return 0 / positive length. ++ * Expected: BUFFER_E from the GrowStream cap. */ ++ ExpectIntEQ(ret, WC_NO_ERR_TRACE(BUFFER_E)); ++ ++ wc_PKCS7_Free(pkcs7); ++#endif ++ return EXPECT_RESULT(); ++} /* END test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen() */ ++ ++ + /* + * Testing wc_PKCS7_DecodeEnvelopedData with streaming + */ +@@ -2501,6 +2792,8 @@ int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void) + bytes */ + size_t testDerBufferSz = 0; + byte decodedData[8192]; ++ byte serverDecodedData[8192]; ++ int serverRet = 0; + + ExpectTrue((f = XFOPEN(testFile, "rb")) != XBADFILE); + if (f != XBADFILE) { +@@ -2520,12 +2813,13 @@ int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void) + ExpectIntEQ(wc_PKCS7_SetKey(pkcs7, (byte*)server_key_der_2048, + sizeof_server_key_der_2048), 0); + +- ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testDerBuffer, +- (word32)testDerBufferSz, decodedData, sizeof(decodedData)); ++ serverRet = wc_PKCS7_DecodeEnvelopedData(pkcs7, testDerBuffer, ++ (word32)testDerBufferSz, serverDecodedData, ++ sizeof(serverDecodedData)); + #if defined(NO_AES) || defined(NO_AES_256) +- ExpectIntEQ(ret, ALGO_ID_E); ++ ExpectIntEQ(serverRet, ALGO_ID_E); + #else +- ExpectIntGT(ret, 0); ++ ExpectIntGT(serverRet, 0); + #endif + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; +@@ -2551,7 +2845,14 @@ int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void) + pkcs7 = NULL; + } + +- /* test with ca cert recipient (which should fail) */ ++ /* Test with ca cert recipient. The ca cert is not a listed recipient, ++ * so RSA unwrap fails. The Bleichenbacher mitigation substitutes a ++ * pseudo-random fake CEK on unwrap failure, so the call normally ++ * returns a negative error when content decryption rejects the ++ * resulting garbage padding - but around 1/256 of the time the random ++ * CEK yields plaintext with accidentally-valid PKCS#7 padding and the ++ * call returns a non-negative "decrypted" size. That case must not ++ * produce the real plaintext. */ + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + if (pkcs7) { + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)ca_cert_der_2048, +@@ -2560,9 +2861,15 @@ int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void) + ExpectIntEQ(wc_PKCS7_SetKey(pkcs7, (byte*)ca_key_der_2048, + sizeof_ca_key_der_2048), 0); + ++ XMEMSET(decodedData, 0, sizeof(decodedData)); + ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testDerBuffer, + (word32)testDerBufferSz, decodedData, sizeof(decodedData)); +- ExpectIntLT(ret, 0); ++ #if defined(NO_AES) || defined(NO_AES_256) ++ ExpectIntEQ(ret, ALGO_ID_E); ++ #else ++ ExpectTrue(ret < 0 || ret != serverRet || ++ XMEMCMP(decodedData, serverDecodedData, (size_t)ret) != 0); ++ #endif + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + } +@@ -2579,7 +2886,7 @@ int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) + EXPECT_DECLS; + #if defined(HAVE_PKCS7) + PKCS7* pkcs7 = NULL; +-#ifdef ASN_BER_TO_DER ++#if defined(ASN_BER_TO_DER) && !defined(NO_PKCS7_STREAM) + int encodedSz = 0; + #endif + #ifdef ECC_TIMING_RESISTANT +@@ -2761,6 +3068,11 @@ int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) + AES128CBCb, AES128_WRAP, dhSinglePass_stdDH_sha1kdf_scheme, + eccCert, eccCertSz, eccPrivKey, eccPrivKeySz}, + #endif ++ #if defined(WOLFSSL_SHA224) && defined(WOLFSSL_AES_128) ++ {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA, ++ AES128CBCb, AES128_WRAP, dhSinglePass_stdDH_sha224kdf_scheme, ++ eccCert, eccCertSz, eccPrivKey, eccPrivKeySz}, ++ #endif + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_256) + {(byte*)input, (word32)(sizeof(input)/sizeof(char)), DATA, + AES256CBCb, AES256_WRAP, dhSinglePass_stdDH_sha256kdf_scheme, +@@ -2784,7 +3096,7 @@ int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) + + testSz = (int)sizeof(testVectors)/(int)sizeof(pkcs7EnvelopedVector); + for (i = 0; i < testSz; i++) { +- #ifdef ASN_BER_TO_DER ++ #if defined(ASN_BER_TO_DER) && !defined(NO_PKCS7_STREAM) + encodeSignedDataStream strm; + + /* test setting stream mode, the first one using IO callbacks */ +@@ -2950,17 +3262,11 @@ int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) + pkcs7->singleCert = NULL; + } + #ifndef NO_RSA +- #if defined(NO_PKCS7_STREAM) +- /* when none streaming mode is used and PKCS7 is in bad state buffer error +- * is returned from kari parse which gets set to bad func arg */ +- ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output, +- (word32)sizeof(output), decoded, (word32)sizeof(decoded)), +- WC_NO_ERR_TRACE(BAD_FUNC_ARG)); +- #else ++ /* With corrupted singleCert, decode should fail with a parse error. ++ * State is properly reset on error so re-decode starts from scratch. */ + ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output, + (word32)sizeof(output), decoded, (word32)sizeof(decoded)), + WC_NO_ERR_TRACE(ASN_PARSE_E)); +- #endif + #endif /* !NO_RSA */ + if (pkcs7 != NULL) { + pkcs7->singleCert = tmpBytePtr; +@@ -3991,7 +4297,8 @@ int test_wc_PKCS7_Degenerate(void) + } /* END test_wc_PKCS7_Degenerate() */ + + #if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && \ +- defined(ASN_BER_TO_DER) && !defined(NO_DES3) && !defined(NO_SHA) ++ defined(ASN_BER_TO_DER) && !defined(NO_DES3) && !defined(NO_SHA) && \ ++ !defined(NO_PKCS7_STREAM) + static byte berContent[] = { + 0x30, 0x80, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x07, 0x03, 0xA0, 0x80, 0x30, +@@ -4182,7 +4489,7 @@ static byte berContent[] = { + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + #endif /* HAVE_PKCS7 && !NO_FILESYSTEM && ASN_BER_TO_DER && +- * !NO_DES3 && !NO_SHA ++ * !NO_DES3 && !NO_SHA && !NO_PKCS7_STREAM + */ + + /* +@@ -4197,7 +4504,7 @@ int test_wc_PKCS7_BER(void) + char fName[] = "./certs/test-ber-exp02-05-2022.p7b"; + XFILE f = XBADFILE; + byte der[4096]; +-#ifndef NO_DES3 ++#if !defined(NO_DES3) && !defined(NO_PKCS7_STREAM) + byte decoded[2048]; + #endif + word32 derSz = 0; +@@ -4242,8 +4549,9 @@ int test_wc_PKCS7_BER(void) + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + +-#ifndef NO_DES3 +- /* decode BER content */ ++#if !defined(NO_DES3) && !defined(NO_PKCS7_STREAM) ++ /* decode BER content - requires PKCS7 streaming to handle indefinite ++ * length encoding in the EnvelopedData structure */ + ExpectTrue((f = XFOPEN("./certs/1024/client-cert.der", "rb")) != XBADFILE); + ExpectTrue((derSz = (word32)XFREAD(der, 1, sizeof(der), f)) > 0); + if (f != XBADFILE) { +@@ -4280,7 +4588,7 @@ int test_wc_PKCS7_BER(void) + sizeof(berContent), decoded, sizeof(decoded)), WC_NO_ERR_TRACE(NOT_COMPILED_IN)); + #endif + wc_PKCS7_Free(pkcs7); +-#endif /* !NO_DES3 */ ++#endif /* !NO_DES3 && !NO_PKCS7_STREAM */ + #endif + return EXPECT_RESULT(); + } /* END test_wc_PKCS7_BER() */ +diff --git a/tests/api/test_pkcs7.h b/tests/api/test_pkcs7.h +index 084744d43..f4aed161d 100644 +--- a/tests/api/test_pkcs7.h ++++ b/tests/api/test_pkcs7.h +@@ -38,6 +38,14 @@ int test_wc_PKCS7_EncodeSignedData_RSA_PSS(void); + !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256) + int test_wc_PKCS7_EnvelopedData_KTRI_RSA_PSS(void); + #endif ++#if defined(HAVE_PKCS7) && !defined(NO_RSA) && !defined(NO_SHA256) && \ ++ !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128) && \ ++ defined(WOLFSSL_AES_256) && !defined(NO_HMAC) && \ ++ !defined(WOLFSSL_NO_MALLOC) && \ ++ (defined(USE_CERT_BUFFERS_2048) || defined(USE_CERT_BUFFERS_1024) || \ ++ !defined(NO_FILESYSTEM)) ++int test_wc_PKCS7_EnvelopedData_KTRI_BadRsaPad(void); ++#endif + int test_wc_PKCS7_EncodeSignedData_ex(void); + int test_wc_PKCS7_VerifySignedData_RSA(void); + int test_wc_PKCS7_VerifySignedData_ECC(void); +@@ -57,6 +65,7 @@ int test_wc_PKCS7_SetOriEncryptCtx(void); + int test_wc_PKCS7_SetOriDecryptCtx(void); + int test_wc_PKCS7_DecodeCompressedData(void); + int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void); ++int test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen(void); + int test_wc_PKCS7_VerifySignedData_PKCS7ContentSeq(void); + int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void); + +@@ -82,6 +91,18 @@ int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void); + #define TEST_PKCS7_RSA_PSS_ED_DECL + #endif + ++#if defined(HAVE_PKCS7) && !defined(NO_RSA) && !defined(NO_SHA256) && \ ++ !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128) && \ ++ defined(WOLFSSL_AES_256) && !defined(NO_HMAC) && \ ++ !defined(WOLFSSL_NO_MALLOC) && \ ++ (defined(USE_CERT_BUFFERS_2048) || defined(USE_CERT_BUFFERS_1024) || \ ++ !defined(NO_FILESYSTEM)) ++#define TEST_PKCS7_KTRI_BADRSAPAD_DECL \ ++ TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_EnvelopedData_KTRI_BadRsaPad), ++#else ++#define TEST_PKCS7_KTRI_BADRSAPAD_DECL ++#endif ++ + #define TEST_PKCS7_SIGNED_DATA_DECLS \ + TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_InitWithCert), \ + TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_EncodeData), \ +@@ -100,6 +121,7 @@ int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void); + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_stream), \ + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_EncodeDecodeEnvelopedData), \ + TEST_PKCS7_RSA_PSS_ED_DECL \ ++ TEST_PKCS7_KTRI_BADRSAPAD_DECL \ + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_SetAESKeyWrapUnwrapCb), \ + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_GetEnvelopedDataKariRid), \ + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_EncodeEncryptedData), \ +@@ -108,7 +130,8 @@ int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void); + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeOneSymmetricKey), \ + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_SetOriEncryptCtx), \ + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_SetOriDecryptCtx), \ +- TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients) ++ TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients), \ ++ TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen) + + #define TEST_PKCS7_SIGNED_ENCRYPTED_DATA_DECLS \ + TEST_DECL_GROUP("pkcs7_sed", test_wc_PKCS7_signed_enveloped) +diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c +index 8df3a2430..f2c98efe5 100644 +--- a/wolfcrypt/src/pkcs7.c ++++ b/wolfcrypt/src/pkcs7.c +@@ -44,6 +44,9 @@ + + #include + #include ++#ifndef NO_HMAC ++ #include ++#endif + #ifndef NO_RSA + #include + #endif +@@ -94,6 +97,7 @@ typedef enum { + /* holds information about the signers */ + struct PKCS7SignerInfo { + int version; ++ int sidType; /* CMS_ISSUER_AND_SERIAL_NUMBER or CMS_SKID */ + byte *sid; + word32 sidSz; + }; +@@ -109,6 +113,17 @@ struct PKCS7SignerInfo { + + #ifndef NO_PKCS7_STREAM + ++/* Hard upper bound on a single PKCS7 streaming buffer allocation. Guards ++ * wc_PKCS7_GrowStream against attacker-controlled ASN.1 lengths that were ++ * parsed with NO_USER_CHECK and would otherwise drive allocations up to ++ * around 2GB (e.g. via a forged RecipientInfo SET length). 16 MB is well above ++ * any legitimate RecipientInfo / encoded-attribute size but small enough ++ * that a forged length fails allocation on constrained targets and is ++ * rejected on larger ones. */ ++#ifndef WOLFSSL_PKCS7_MAX_STREAM_ALLOC ++ #define WOLFSSL_PKCS7_MAX_STREAM_ALLOC (16 * 1024 * 1024) ++#endif ++ + #define MAX_PKCS7_STREAM_BUFFER 256 + struct PKCS7State { + byte* tmpCert; +@@ -207,10 +222,15 @@ static void wc_PKCS7_ResetStream(wc_PKCS7* pkcs7) + #endif + + /* free any buffers that may be allocated */ ++ if (pkcs7->stream->aad != NULL && pkcs7->stream->aadSz > 0) ++ ForceZero(pkcs7->stream->aad, pkcs7->stream->aadSz); + XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(pkcs7->stream->tag, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(pkcs7->stream->nonce, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ /* stream->key is always allocated with MAX_ENCRYPTED_KEY_SZ */ ++ if (pkcs7->stream->key != NULL) ++ ForceZero(pkcs7->stream->key, MAX_ENCRYPTED_KEY_SZ); + XFREE(pkcs7->stream->key, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + pkcs7->stream->aad = NULL; + pkcs7->stream->tag = NULL; +@@ -265,6 +285,16 @@ static void wc_PKCS7_FreeStream(wc_PKCS7* pkcs7) + static int wc_PKCS7_GrowStream(wc_PKCS7* pkcs7, word32 newSz) + { + byte* pt; ++ ++ /* Guard against attacker-controlled ASN.1 lengths reaching this ++ * allocation. Several callers parse lengths with NO_USER_CHECK and ++ * pass them here unvalidated (e.g. wc_PKCS7_ParseToRecipientInfoSet ++ * on a forged RecipientInfo SET header). */ ++ if (newSz > WOLFSSL_PKCS7_MAX_STREAM_ALLOC) { ++ WOLFSSL_MSG("PKCS7 streaming allocation exceeds maximum"); ++ return BUFFER_E; ++ } ++ + pt = (byte*)XMALLOC(newSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + if (pt == NULL) { + return MEMORY_E; +@@ -4275,6 +4305,94 @@ int wc_PKCS7_SetEccSignRawDigestCb(wc_PKCS7* pkcs7, CallbackEccSignRawDigest cb) + #endif /* HAVE_ECC */ + + ++#if !defined(NO_RSA) || defined(HAVE_ECC) ++/* Check whether the given decoded certificate matches the SignerIdentifier ++ * (sid) field of the currently parsed SignerInfo. Per RFC 5652 Section 5.3, ++ * the sid selects which certificate's public key must be used to verify the ++ * signature. Returns 1 on match, 0 on no match or when the sid is not ++ * available for comparison. */ ++static int wc_PKCS7_CertMatchesSignerInfo(wc_PKCS7* pkcs7, DecodedCert* dCert) ++{ ++ PKCS7SignerInfo* signerInfo; ++ ++ if (pkcs7 == NULL || dCert == NULL) ++ return 0; ++ ++ signerInfo = pkcs7->signerInfo; ++ if (signerInfo == NULL || signerInfo->sid == NULL || ++ signerInfo->sidSz == 0) { ++ /* No SID parsed, cannot perform an identity binding check. */ ++ return 0; ++ } ++ ++ if (signerInfo->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { ++ /* IssuerAndSerialNumber: SID blob stores the content of the outer ++ * SEQUENCE (issuer Name followed by INTEGER serialNumber). */ ++ word32 idx = 0; ++ byte sidIssuerHash[KEYID_SIZE]; ++ WC_DECLARE_VAR(sidSerial, mp_int, 1, pkcs7->heap); ++ WC_DECLARE_VAR(certSerial, mp_int, 1, pkcs7->heap); ++ int cmp; ++ int match = 0; ++ ++ if (GetNameHash_ex(signerInfo->sid, &idx, sidIssuerHash, ++ (int)signerInfo->sidSz, dCert->signatureOID) < 0) { ++ return 0; ++ } ++ if (XMEMCMP(sidIssuerHash, dCert->issuerHash, KEYID_SIZE) != 0) ++ return 0; ++ ++ WC_ALLOC_VAR_EX(sidSerial, mp_int, 1, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER, ++ { return 0; }); ++ WC_ALLOC_VAR_EX(certSerial, mp_int, 1, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER, ++ { WC_FREE_VAR_EX(sidSerial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); ++ return 0; }); ++ ++ if (mp_init(sidSerial) != MP_OKAY) { ++ WC_FREE_VAR_EX(sidSerial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); ++ WC_FREE_VAR_EX(certSerial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); ++ return 0; ++ } ++ if (mp_init(certSerial) != MP_OKAY) { ++ mp_clear(sidSerial); ++ WC_FREE_VAR_EX(sidSerial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); ++ WC_FREE_VAR_EX(certSerial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); ++ return 0; ++ } ++ ++ if (GetInt(sidSerial, signerInfo->sid, &idx, signerInfo->sidSz) == 0 && ++ mp_read_unsigned_bin(certSerial, dCert->serial, ++ (word32)dCert->serialSz) == MP_OKAY) { ++ cmp = mp_cmp(sidSerial, certSerial); ++ if (cmp == MP_EQ) ++ match = 1; ++ } ++ ++ mp_clear(sidSerial); ++ mp_clear(certSerial); ++ WC_FREE_VAR_EX(sidSerial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); ++ WC_FREE_VAR_EX(certSerial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); ++ return match; ++ } ++ else if (signerInfo->sidType == CMS_SKID) { ++ /* SubjectKeyIdentifier: SID blob is the raw SKID octet string ++ * content. Normalize the same way the certificate side does so ++ * that comparisons between SHA-1 SKIDs and other lengths match. */ ++ byte sidKid[KEYID_SIZE]; ++ ++ if (GetHashId(signerInfo->sid, (int)signerInfo->sidSz, sidKid, ++ HashIdAlg(dCert->signatureOID)) != 0) { ++ return 0; ++ } ++ if (XMEMCMP(sidKid, dCert->extSubjKeyId, KEYID_SIZE) == 0) ++ return 1; ++ return 0; ++ } ++ ++ return 0; ++} ++#endif /* !NO_RSA || HAVE_ECC */ ++ + #ifndef NO_RSA + + /* returns size of signature put into out, negative on error */ +@@ -4354,6 +4472,31 @@ static int wc_PKCS7_RsaVerify(wc_PKCS7* pkcs7, byte* sig, int sigSz, + continue; + } + ++ /* If the SignerInfo sid was parsed, only try the certificate whose ++ * identity matches it. This binds the verifying public key to the ++ * signer identity advertised in the CMS message and prevents signer ++ * confusion when multiple certificates are embedded. */ ++ if (pkcs7->signerInfo != NULL && pkcs7->signerInfo->sid != NULL && ++ !wc_PKCS7_CertMatchesSignerInfo(pkcs7, dCert)) { ++ FreeDecodedCert(dCert); ++ wc_FreeRsaKey(key); ++ continue; ++ } ++ ++ /* Defense in depth: the sid-matched cert must actually carry an ++ * RSA-family key before we feed its SPKI to the RSA key decoder. ++ * Rejecting here avoids depending on wc_RsaPublicKeyDecode to reject ++ * wrong-type SPKIs. */ ++ if (dCert->keyOID != RSAk ++ #ifdef WC_RSA_PSS ++ && dCert->keyOID != RSAPSSk ++ #endif ++ ) { ++ FreeDecodedCert(dCert); ++ wc_FreeRsaKey(key); ++ continue; ++ } ++ + if (wc_RsaPublicKeyDecode(dCert->publicKey, &scratch, key, + dCert->pubKeySize) < 0) { + WOLFSSL_MSG("ASN RSA key decode error"); +@@ -4464,6 +4607,24 @@ static int wc_PKCS7_RsaPssVerify(wc_PKCS7* pkcs7, byte* sig, int sigSz, + continue; + } + ++ /* Only try the certificate identified by the SignerInfo sid (see ++ * matching comment in wc_PKCS7_RsaVerify). */ ++ if (pkcs7->signerInfo != NULL && pkcs7->signerInfo->sid != NULL && ++ !wc_PKCS7_CertMatchesSignerInfo(pkcs7, dCert)) { ++ FreeDecodedCert(dCert); ++ wc_FreeRsaKey(key); ++ continue; ++ } ++ ++ /* Defense in depth: reject non-RSA SPKIs before key decode. RSA ++ * rsaEncryption certs (keyOID=RSAk) are accepted for PSS signatures ++ * per RFC 8017 - a RSASSA-PSS cert is not required. */ ++ if (dCert->keyOID != RSAk && dCert->keyOID != RSAPSSk) { ++ FreeDecodedCert(dCert); ++ wc_FreeRsaKey(key); ++ continue; ++ } ++ + pkSz = dCert->pubKeySize; + if (pkSz > (MAX_RSA_INT_SZ + MAX_RSA_E_SZ)) + pkSz = (MAX_RSA_INT_SZ + MAX_RSA_E_SZ); +@@ -4629,6 +4790,22 @@ static int wc_PKCS7_EcdsaVerify(wc_PKCS7* pkcs7, byte* sig, int sigSz, + continue; + } + ++ /* Only try the certificate identified by the SignerInfo sid (see ++ * matching comment in wc_PKCS7_RsaVerify). */ ++ if (pkcs7->signerInfo != NULL && pkcs7->signerInfo->sid != NULL && ++ !wc_PKCS7_CertMatchesSignerInfo(pkcs7, dCert)) { ++ FreeDecodedCert(dCert); ++ wc_ecc_free(key); ++ continue; ++ } ++ ++ /* Defense in depth: reject non-ECDSA SPKIs before key decode. */ ++ if (dCert->keyOID != ECDSAk) { ++ FreeDecodedCert(dCert); ++ wc_ecc_free(key); ++ continue; ++ } ++ + if (wc_EccPublicKeyDecode(dCert->publicKey, &idx, key, + dCert->pubKeySize) < 0) { + WOLFSSL_MSG("ASN ECC key decode error"); +@@ -5337,11 +5514,16 @@ static int wc_PKCS7_ParseSignerInfo(wc_PKCS7* pkcs7, byte* in, word32 inSz, + ret = ASN_PARSE_E; + + if (ret == 0) { ++ pkcs7->signerInfo->sidType = CMS_ISSUER_AND_SERIAL_NUMBER; + ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length); + idx += (word32)length; + } + + } else if (ret == 0 && version == 3) { ++ /* Default: SignerInfo version 3 carries SubjectKeyIdentifier. ++ * May be overridden below if the parser instead finds a ++ * SEQUENCE (IssuerAndSerialNumber fallback). */ ++ pkcs7->signerInfo->sidType = CMS_SKID; + /* Get the sequence of SubjectKeyIdentifier */ + if (idx + 1 > inSz) + ret = BUFFER_E; +@@ -5384,6 +5566,12 @@ static int wc_PKCS7_ParseSignerInfo(wc_PKCS7* pkcs7, byte* in, word32 inSz, + + if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0) + ret = ASN_PARSE_E; ++ ++ if (ret == 0) { ++ /* v3 carrying IssuerAndSerialNumber fallback */ ++ pkcs7->signerInfo->sidType = ++ CMS_ISSUER_AND_SERIAL_NUMBER; ++ } + } + } + +@@ -7029,6 +7217,9 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf, + + idx += (word32)length; + } ++ else if (ret == 0) { ++ ret = ASN_PARSE_E; ++ } + + pkcs7->content = content; + pkcs7->contentSz = (word32)contentSz; +@@ -7721,6 +7912,9 @@ static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, WC_RNG* rng, + secret = (byte*)XMALLOC(secretSz, kari->heap, DYNAMIC_TYPE_PKCS7); + if (secret == NULL) + return MEMORY_E; ++#ifdef WOLFSSL_CHECK_MEM_ZERO ++ wc_MemZero_Add("wc_PKCS7_KariGenerateKEK secret", secret, secretSz); ++#endif + + #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ +@@ -7756,6 +7950,7 @@ static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, WC_RNG* rng, + } + + if (ret != 0) { ++ ForceZero(secret, secretSz); + XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7); + return ret; + } +@@ -7768,7 +7963,7 @@ static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, WC_RNG* rng, + kdfType = WC_HASH_TYPE_SHA; + break; + #endif +- #ifndef WOLFSSL_SHA224 ++ #ifdef WOLFSSL_SHA224 + case dhSinglePass_stdDH_sha224kdf_scheme: + kdfType = WC_HASH_TYPE_SHA224; + break; +@@ -7790,6 +7985,7 @@ static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, WC_RNG* rng, + #endif + default: + WOLFSSL_MSG("Unsupported key agreement algorithm"); ++ ForceZero(secret, secretSz); + XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7); + return BAD_FUNC_ARG; + }; +@@ -7802,6 +7998,7 @@ static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari, WC_RNG* rng, + ret = NOT_COMPILED_IN; + #endif + ++ ForceZero(secret, secretSz); + XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7); + return ret; + } +@@ -9606,7 +9803,7 @@ static int wc_PKCS7_PwriKek_KeyUnWrap(wc_PKCS7* pkcs7, const byte* kek, + cekLen = outTmp[0]; + + /* verify length */ +- fail |= ctMaskGT(cekLen, (int)inSz); ++ fail |= ctMaskGT(cekLen, (int)inSz - 4); + /* verify check bytes */ + fail |= ctMaskNotEq((int)(outTmp[1] ^ outTmp[4]), 0xFF); + fail |= ctMaskNotEq((int)(outTmp[2] ^ outTmp[5]), 0xFF); +@@ -9747,6 +9944,7 @@ int wc_PKCS7_AddRecipient_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, + (word32)kekKeySz); + if (ret < 0) { + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ret; +@@ -9758,6 +9956,7 @@ int wc_PKCS7_AddRecipient_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, + tmpIv, (word32)kekBlockSz, encryptOID); + if (ret < 0) { + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ret; +@@ -9782,6 +9981,7 @@ int wc_PKCS7_AddRecipient_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, + ret = wc_SetContentType(PWRI_KEK_WRAP, keyEncAlgoId, sizeof(keyEncAlgoId)); + if (ret <= 0) { + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ret; +@@ -9813,6 +10013,7 @@ int wc_PKCS7_AddRecipient_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, + ret = wc_SetContentType(kdfOID, kdfAlgoId, sizeof(kdfAlgoId)); + if (ret <= 0) { + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ret; +@@ -9838,6 +10039,7 @@ int wc_PKCS7_AddRecipient_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, + if (totalSz > MAX_RECIP_SZ) { + WOLFSSL_MSG("CMS Recipient output buffer too small"); + XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return BUFFER_E; +@@ -9875,7 +10077,7 @@ int wc_PKCS7_AddRecipient_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, + XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz); + idx += encryptedKeySz; + +- ForceZero(kek, (word32)kekBlockSz); ++ ForceZero(kek, (word32)kekKeySz); + ForceZero(encryptedKey, encryptedKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); +@@ -10580,6 +10782,81 @@ int wc_PKCS7_EncodeEnvelopedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz) + } + + #ifndef NO_RSA ++#if !defined(NO_HMAC) && !defined(NO_SHA256) ++/* Bleichenbacher padding-oracle mitigation for PKCS#7/CMS KTRI: produce a ++ * WC_SHA256_DIGEST_SIZE-byte pseudo-random CEK derived from a fresh ++ * random seed and the encrypted-key ciphertext. The output is random per ++ * call (driven by the RNG seed); deriving via HMAC of the ciphertext ++ * simply gives the same value within one call regardless of where it is ++ * referenced. Called unconditionally so the work is in the timing path ++ * regardless of RSA padding validity. */ ++static int wc_PKCS7_KtriFakeCEK(wc_PKCS7* pkcs7, const byte* encryptedKey, ++ word32 encryptedKeySz, byte* out) ++{ ++ int ret; ++ byte seed[WC_SHA256_DIGEST_SIZE]; ++ WC_RNG* rng = NULL; ++ int ownRng = 0; ++ WC_DECLARE_VAR(localRng, WC_RNG, 1, pkcs7->heap); ++ WC_DECLARE_VAR(hmac, Hmac, 1, pkcs7->heap); ++ ++ if (pkcs7 == NULL || encryptedKey == NULL || out == NULL) { ++ return BAD_FUNC_ARG; ++ } ++ ++ WC_ALLOC_VAR_EX(hmac, Hmac, 1, pkcs7->heap, DYNAMIC_TYPE_HMAC, ++ return MEMORY_E); ++ ++ /* Prefer a caller-provided RNG to avoid paying a DRBG init/reseed cost ++ * on every decrypt (and to keep the timing envelope flatter on FIPS / ++ * HW-RNG builds). Fall back to a one-shot RNG when pkcs7->rng is not ++ * set. */ ++ if (pkcs7->rng != NULL) { ++ rng = pkcs7->rng; ++ } ++ else { ++ WC_ALLOC_VAR_EX(localRng, WC_RNG, 1, pkcs7->heap, DYNAMIC_TYPE_RNG, ++ WC_FREE_VAR_EX(hmac, pkcs7->heap, DYNAMIC_TYPE_HMAC); ++ return MEMORY_E); ++ ret = wc_InitRng_ex(localRng, pkcs7->heap, pkcs7->devId); ++ if (ret != 0) { ++ WC_FREE_VAR_EX(localRng, pkcs7->heap, DYNAMIC_TYPE_RNG); ++ WC_FREE_VAR_EX(hmac, pkcs7->heap, DYNAMIC_TYPE_HMAC); ++ return ret; ++ } ++ rng = localRng; ++ ownRng = 1; ++ } ++ ++ ret = wc_RNG_GenerateBlock(rng, seed, (word32)sizeof(seed)); ++ ++ if (ownRng) { ++ wc_FreeRng(localRng); ++ WC_FREE_VAR_EX(localRng, pkcs7->heap, DYNAMIC_TYPE_RNG); ++ } ++ ++ if (ret != 0) { ++ WC_FREE_VAR_EX(hmac, pkcs7->heap, DYNAMIC_TYPE_HMAC); ++ return ret; ++ } ++ ++ ret = wc_HmacInit(hmac, pkcs7->heap, pkcs7->devId); ++ if (ret == 0) { ++ ret = wc_HmacSetKey(hmac, WC_SHA256, seed, (word32)sizeof(seed)); ++ if (ret == 0) { ++ ret = wc_HmacUpdate(hmac, encryptedKey, encryptedKeySz); ++ } ++ if (ret == 0) { ++ ret = wc_HmacFinal(hmac, out); ++ } ++ wc_HmacFree(hmac); ++ } ++ ForceZero(seed, sizeof(seed)); ++ WC_FREE_VAR_EX(hmac, pkcs7->heap, DYNAMIC_TYPE_HMAC); ++ return ret; ++} ++#endif /* !NO_HMAC && !NO_SHA256 */ ++ + /* decode KeyTransRecipientInfo (ktri), return 0 on success, <0 on error */ + static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + word32* idx, byte* decryptedKey, +@@ -10596,7 +10873,9 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + word32 pkiMsgSz = inSz; + byte tag; + +- ++#ifndef WC_NO_RSA_OAEP ++ word32 outKeySz = 0; ++#endif + #ifndef NO_PKCS7_STREAM + word32 tmpIdx = *idx; + #endif +@@ -10755,15 +11034,17 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) + return ASN_PARSE_E; + +- if ((word32)keyIdSize > pkiMsgSz - (*idx)) ++ /* Validate SKID container is within buffer */ ++ if ((word32)length > pkiMsgSz - (*idx)) + return BUFFER_E; + + /* if we found correct recipient, SKID will match */ +- if (XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId, ++ if (length == keyIdSize && ++ XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId, + (word32)keyIdSize) == 0) { + *recipFound = 1; + } +- (*idx) += (word32)keyIdSize; ++ (*idx) += (word32)length; + } + + if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0) +@@ -10903,8 +11184,8 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + #ifndef WC_NO_RSA_OAEP + } + else { +- word32 outLen = (word32)wc_RsaEncryptSize(privKey); +- outKey = (byte*)XMALLOC(outLen, pkcs7->heap, ++ outKeySz = (word32)wc_RsaEncryptSize(privKey); ++ outKey = (byte*)XMALLOC(outKeySz, pkcs7->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (!outKey) { + WOLFSSL_MSG("Failed to allocate out key buffer"); +@@ -10918,9 +11199,9 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + } + + keySz = wc_RsaPrivateDecrypt_ex(encryptedKey, +- (word32)encryptedKeySz, outKey, outLen, privKey, +- WC_RSA_OAEP_PAD, +- WC_HASH_TYPE_SHA, WC_MGF1SHA1, NULL, 0); ++ (word32)encryptedKeySz, outKey, outKeySz, ++ privKey, WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA, ++ WC_MGF1SHA1, NULL, 0); + } + #endif + } +@@ -10935,30 +11216,153 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + } + wc_FreeRsaKey(privKey); + ++ #if !defined(NO_HMAC) && !defined(NO_SHA256) ++ { ++ /* Bleichenbacher padding-oracle mitigation: always compute ++ * a pseudo-random fallback CEK so timing and error ++ * behaviour do not depend on RSA padding validity. On ++ * unwrap failure we substitute the fallback and let ++ * content decryption fail indistinguishably from "unwrap ++ * succeeded but CEK is wrong". */ ++ byte fakeKey[WC_SHA256_DIGEST_SIZE]; ++ int fakeRet = wc_PKCS7_KtriFakeCEK(pkcs7, encryptedKey, ++ (word32)encryptedKeySz, ++ fakeKey); ++ ++ if (fakeRet != 0) { ++ /* Fallback generation failed (e.g. RNG/HMAC error). ++ * Return the fallback-generation status, which does ++ * not depend on RSA padding validity, rather than the ++ * RSA status which would re-open the oracle. */ ++ ForceZero(fakeKey, sizeof(fakeKey)); ++ /* In the non-OAEP path RSA is decrypted in-place via ++ * wc_RsaPrivateDecryptInline, so encryptedKey holds ++ * the (possibly valid) plaintext CEK. Zero it before ++ * free. */ ++ ForceZero(encryptedKey, (word32)encryptedKeySz); ++ XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT); ++ WC_FREE_VAR_EX(privKey, pkcs7->heap, ++ DYNAMIC_TYPE_TMP_BUFFER); ++ #ifndef WC_NO_RSA_OAEP ++ if (encOID == RSAESOAEPk) { ++ if (outKey != NULL) { ++ ForceZero(outKey, outKeySz); ++ XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); ++ } ++ } ++ #endif ++ return fakeRet; ++ } ++ ++ /* Constant-time select between fake and real CEK. On RSA ++ * failure outKey may be NULL or keySz may be <= 0; in ++ * both cases the mask selects fakeKey for every byte. ++ * ++ * To avoid data-dependent branches that leak realLen, ++ * copy the real key into a fixed-size zero-padded buffer ++ * first, then select byte-by-byte in constant time. */ ++ { ++ word32 i; ++ byte useFake; ++ int realLen = keySz; ++ byte realPad[WC_SHA256_DIGEST_SIZE]; ++ ++ XMEMSET(realPad, 0, sizeof(realPad)); ++ /* Constant-time copy: avoid data-dependent branches ++ * that could leak whether RSA padding was valid. ++ * When outKey is NULL (inline RSA failure), use ++ * encryptedKey as a safe readable source; the mask ++ * will zero out all bytes anyway. Both encryptedKey ++ * and outKey (when non-NULL) are at least ++ * sizeof(realPad) bytes for any RSA key size. ++ * ++ * Use constant-time pointer selection to avoid ++ * branching on outKey nullity, which would leak ++ * whether RSA PKCS#1 v1.5 padding was valid. */ ++ { ++ byte haveSrc = ctMaskGTE(realLen, 1); ++ const byte* srcTbl[2]; ++ const byte* src; ++ word32 j = 0; ++ word32 safeJ = 0; ++ ++ /* Select source without integer pointer synthesis. ++ * Some safety-oriented compilers (e.g. Fil-C) treat ++ * int-to-pointer reconstruction as a null-object ++ * pointer on dereference. */ ++ srcTbl[0] = encryptedKey; ++ srcTbl[1] = outKey; ++ src = srcTbl[haveSrc & 1]; ++ ++ /* safeJ is clamped to max(0, realLen-1): it ++ * only advances while the next index would ++ * still be inside realLen, so src[safeJ] is ++ * always in bounds. Bytes at j >= realLen are ++ * masked to zero by inBounds anyway. */ ++ for (j = 0; j < (word32)sizeof(realPad); j++) { ++ byte inBounds = ctMaskLT((int)j, realLen); ++ byte advance = ctMaskLT((int)(safeJ + 1), ++ realLen); ++ realPad[j] = src[safeJ] & haveSrc & inBounds; ++ safeJ += (word32)(advance & 1); ++ } ++ } ++ useFake = ctMaskLT(realLen, 1); /* 0xFF if realLen<=0 */ ++ ++ for (i = 0; i < (word32)sizeof(fakeKey); i++) { ++ decryptedKey[i] = ctMaskSel(useFake, fakeKey[i], ++ realPad[i]); ++ } ++ /* Report the real key size on success; on RSA ++ * failure (realLen <= 0) report sizeof(fakeKey). ++ * Constant-time select avoids branching on RSA ++ * padding validity. */ ++ *decryptedKeySz = (word32)ctMaskSelInt(useFake, ++ (int)sizeof(fakeKey), realLen); ++ ForceZero(realPad, sizeof(realPad)); ++ } ++ ForceZero(fakeKey, sizeof(fakeKey)); ++ /* In the non-OAEP path RSA is decrypted in-place via ++ * wc_RsaPrivateDecryptInline, so encryptedKey holds the ++ * plaintext CEK after the unwrap. Zero it before free. */ ++ ForceZero(encryptedKey, (word32)encryptedKeySz); ++ } ++ #else /* NO_HMAC || NO_SHA256: mitigation unavailable */ ++ #if !defined(WOLFSSL_NO_KTRI_ORACLE_WARNING) ++ #warning "PKCS7 KTRI Bleichenbacher mitigation requires HMAC " \ ++ "and SHA256; build without them leaves the RSA unwrap " \ ++ "error path observable to callers. " \ ++ "Define WOLFSSL_NO_KTRI_ORACLE_WARNING to silence." ++ #endif ++ + if (keySz <= 0 || outKey == NULL) { + ForceZero(encryptedKey, (word32)encryptedKeySz); + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT); + WC_FREE_VAR_EX(privKey, pkcs7->heap, + DYNAMIC_TYPE_TMP_BUFFER); +- #ifndef WC_NO_RSA_OAEP ++ #ifndef WC_NO_RSA_OAEP + if (encOID == RSAESOAEPk) { + if (outKey) { ++ ForceZero(outKey, outKeySz); + XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + } +- #endif ++ #endif + return keySz; +- } else { ++ } ++ else { + *decryptedKeySz = (word32)keySz; + XMEMCPY(decryptedKey, outKey, (word32)keySz); + ForceZero(encryptedKey, (word32)encryptedKeySz); + } ++ #endif /* !NO_HMAC && !NO_SHA256 */ + + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT); + WC_FREE_VAR_EX(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + #ifndef WC_NO_RSA_OAEP + if (encOID == RSAESOAEPk) { + if (outKey) { ++ ForceZero(outKey, outKeySz); + XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + } +@@ -11040,6 +11444,14 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari, + if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) + return ASN_PARSE_E; + ++ /* BIT STRING must have at least unused-bits byte + 1 byte of content */ ++ if (length < 2) ++ return ASN_PARSE_E; ++ ++ /* Validate BIT STRING content is within input buffer */ ++ if (*idx > pkiMsgSz || (word32)length > pkiMsgSz - *idx) ++ return ASN_PARSE_E; ++ + if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) + return ASN_EXPECT_0_E; + +@@ -11519,9 +11931,22 @@ static int wc_PKCS7_DecryptOri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + XMEMCPY(oriOID, pkiMsg + *idx, (word32)oriOIDSz); + *idx += (word32)oriOIDSz; + ++ /* Validate OID did not consume more than the SEQUENCE declared */ ++ if ((*idx - tmpIdx) > (word32)seqSz) { ++ WOLFSSL_MSG("ORI oriType OID exceeds SEQUENCE boundary"); ++ return ASN_PARSE_E; ++ } ++ + /* get oriValue, increment idx */ + oriValue = pkiMsg + *idx; + oriValueSz = (word32)seqSz - (*idx - tmpIdx); ++ ++ /* Validate oriValue region is within input buffer */ ++ if (*idx > pkiMsgSz || oriValueSz > pkiMsgSz - *idx) { ++ WOLFSSL_MSG("ORI oriValue exceeds input buffer"); ++ return ASN_PARSE_E; ++ } ++ + *idx += oriValueSz; + + /* pass oriOID and oriValue to user callback, expect back +@@ -11699,6 +12124,12 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + return ASN_PARSE_E; + } + ++ /* Validate IV is within input buffer */ ++ if (*idx > pkiMsgSz || (word32)length > pkiMsgSz - *idx) { ++ XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ return ASN_PARSE_E; ++ } ++ + XMEMCPY(tmpIv, pkiMsg + (*idx), (word32)length); + *idx += (word32)length; + +@@ -11718,6 +12149,12 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + return ASN_PARSE_E; + } + ++ /* Validate EncryptedKey is within input buffer */ ++ if (*idx > pkiMsgSz || (word32)length > pkiMsgSz - *idx) { ++ XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ return ASN_PARSE_E; ++ } ++ + /* allocate temporary space for decrypted key */ + cekSz = (word32)length; + cek = (byte*)XMALLOC(cekSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); +@@ -11740,6 +12177,7 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + iterations, kek, (word32)kekKeySz); + if (ret < 0) { + XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ASN_PARSE_E; +@@ -11752,7 +12190,9 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + pwriEncAlgoId); + if (ret < 0) { + XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(cek, cekSz); + XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ret; + } +@@ -11761,7 +12201,9 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + if (*decryptedKeySz < cekSz) { + WOLFSSL_MSG("Decrypted key buffer too small for CEK"); + XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(cek, cekSz); + XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return BUFFER_E; + } +@@ -11770,7 +12212,9 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + *decryptedKeySz = cekSz; + + XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(kek, (word32)kekKeySz); + XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ ForceZero(cek, cekSz); + XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + + /* mark recipFound, since we only support one RecipientInfo for now */ +@@ -11804,7 +12248,7 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + byte* keyId = NULL; + const byte* datePtr = NULL; + byte dateFormat, tag; +- word32 keyIdSz, kekIdSz, keyWrapOID, localIdx; ++ word32 keyIdSz, kekIdSz, kekIdEnd, keyWrapOID, localIdx; + + int ret = 0; + byte* pkiMsg = in; +@@ -11830,6 +12274,11 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + return ASN_PARSE_E; + + kekIdSz = (word32)length; ++ kekIdEnd = *idx + kekIdSz; ++ ++ /* Validate KEKIdentifier boundary is within input buffer */ ++ if (kekIdEnd < *idx || kekIdEnd > pkiMsgSz) ++ return ASN_PARSE_E; + + if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) + return ASN_PARSE_E; +@@ -11840,6 +12289,10 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) + return ASN_PARSE_E; + ++ /* Validate keyIdentifier is within input buffer */ ++ if (*idx > pkiMsgSz || (word32)length > pkiMsgSz - *idx) ++ return ASN_PARSE_E; ++ + /* save keyIdentifier and length */ + keyId = pkiMsg + *idx; + keyIdSz = (word32)length; +@@ -11847,13 +12300,15 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + + /* may have OPTIONAL GeneralizedTime */ + localIdx = *idx; +- if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag, ++ if ((*idx < kekIdEnd) && GetASNTag(pkiMsg, &localIdx, &tag, + pkiMsgSz) == 0 && tag == ASN_GENERALIZED_TIME) { +- if (wc_GetDateInfo(pkiMsg + *idx, (int)pkiMsgSz, &datePtr, +- &dateFormat, &dateLen) != 0) { ++ if (wc_GetDateInfo(pkiMsg + *idx, (int)(pkiMsgSz - *idx), ++ &datePtr, &dateFormat, &dateLen) != 0) { + return ASN_PARSE_E; + } +- *idx += (word32)(dateLen + 1); ++ /* datePtr points to the start of the date value ++ * within pkiMsg; advance past the full TLV. */ ++ *idx = (word32)(datePtr - pkiMsg) + (word32)dateLen; + } + + if (*idx > pkiMsgSz) { +@@ -11862,7 +12317,7 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + + /* may have OPTIONAL OtherKeyAttribute */ + localIdx = *idx; +- if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag, ++ if ((*idx < kekIdEnd) && GetASNTag(pkiMsg, &localIdx, &tag, + pkiMsgSz) == 0 && tag == (ASN_SEQUENCE | + ASN_CONSTRUCTED)) { + if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) +@@ -11891,6 +12346,10 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, + if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) + return ASN_PARSE_E; + ++ /* Validate EncryptedKey is within input buffer */ ++ if (*idx > pkiMsgSz || (word32)length > pkiMsgSz - *idx) ++ return ASN_PARSE_E; ++ + #ifndef NO_AES + direction = AES_DECRYPTION; + #else +@@ -12644,6 +13103,22 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, + NO_USER_CHECK) < 0) + ret = ASN_PARSE_E; + ++ /* GetSet_ex is called with NO_USER_CHECK, which skips the ++ * (idx + length > maxIdx) bounds check in GetLength_ex. In ++ * non-streaming mode, validate the SET length against the ++ * remaining input buffer; in streaming mode the length flows ++ * into pkcs7->stream->expected and then wc_PKCS7_GrowStream, ++ * where it is capped by WOLFSSL_PKCS7_MAX_STREAM_ALLOC. */ ++ if (ret == 0 && length < 0) ++ ret = ASN_PARSE_E; ++ #ifdef NO_PKCS7_STREAM ++ if (ret == 0 && ++ (*idx > pkiMsgSz || ++ (word32)length > pkiMsgSz - *idx)) { ++ ret = ASN_PARSE_E; ++ } ++ #endif ++ + if (ret < 0) + break; + +@@ -12799,6 +13274,11 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, + DYNAMIC_TYPE_PKCS7); + if (decryptedKey == NULL) + return MEMORY_E; ++ XMEMSET(decryptedKey, 0, MAX_ENCRYPTED_KEY_SZ); ++ #ifdef WOLFSSL_CHECK_MEM_ZERO ++ wc_MemZero_Add("wc_PKCS7 decryptedKey", decryptedKey, ++ MAX_ENCRYPTED_KEY_SZ); ++ #endif + wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_2); + tmpIdx = idx; + recipientSetSz = (word32)ret; +@@ -13018,6 +13498,14 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, + ret = ASN_PARSE_E; + } + ++ #ifdef NO_PKCS7_STREAM ++ if (ret == 0 && encryptedContentTotalSz > (int)(pkiMsgSz - idx)) { ++ /* In non-streaming mode, ensure the content fits in the buffer. ++ * Streaming mode handles this via AddDataToStream. */ ++ ret = BUFFER_E; ++ } ++ #endif ++ + if (ret != 0) + break; + +@@ -13033,10 +13521,18 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, + wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet); + + if (explicitOctet) { +- /* initialize decryption state in preparation */ ++ /* initialize decryption state in preparation. Use ++ * contentSz (blockKeySz from the content algorithm) as ++ * the AES key size rather than aadSz (the unwrapped CEK ++ * length): the two are equal for well-formed messages, ++ * but using blockKeySz avoids BAD_FUNC_ARG on crafted ++ * messages where the CEK length does not match the ++ * content cipher, which would otherwise be a ++ * distinguishable error. */ + if (pkcs7->decryptionCb == NULL) { + ret = wc_PKCS7_DecryptContentInit(pkcs7, encOID, +- pkcs7->stream->aad, pkcs7->stream->aadSz, ++ pkcs7->stream->aad, ++ (word32)pkcs7->stream->contentSz, + pkcs7->stream->tmpIv, expBlockSz, + pkcs7->devId, pkcs7->heap); + if (ret != 0) +@@ -13319,8 +13815,13 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, + + ret = (int)pkcs7->totalEncryptedContentSz - padLen; + #ifndef NO_PKCS7_STREAM +- pkcs7->stream->aad = NULL; +- pkcs7->stream->aadSz = 0; ++ /* decryptedKey (just freed) is the same buffer stream->aad ++ * aliases. Null the stream handle so ResetStream doesn't ++ * double-free it. */ ++ if (pkcs7->stream != NULL) { ++ pkcs7->stream->aad = NULL; ++ pkcs7->stream->aadSz = 0; ++ } + wc_PKCS7_ResetStream(pkcs7); + #endif + wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START); +@@ -13333,6 +13834,16 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, + + #ifndef NO_PKCS7_STREAM + if (ret < 0 && ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) { ++ /* stream->aad aliases the MAX_ENCRYPTED_KEY_SZ decryptedKey ++ * buffer in this flow. ResetStream only zeros aadSz bytes, so ++ * explicitly zero and release the full buffer here to satisfy ++ * WOLFSSL_CHECK_MEM_ZERO and avoid leaking key material. */ ++ if (pkcs7->stream != NULL && pkcs7->stream->aad != NULL) { ++ ForceZero(pkcs7->stream->aad, MAX_ENCRYPTED_KEY_SZ); ++ XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ++ pkcs7->stream->aad = NULL; ++ pkcs7->stream->aadSz = 0; ++ } + wc_PKCS7_ResetStream(pkcs7); + wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START); + if (pkcs7->cachedEncryptedContent != NULL) { +@@ -13343,6 +13854,9 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, + } + } + #else ++ if (ret < 0) { ++ wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START); ++ } + if (decryptedKey != NULL && ret < 0) { + ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ); + XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); +@@ -14103,6 +14617,10 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, + } + else { + XMEMSET(decryptedKey, 0, MAX_ENCRYPTED_KEY_SZ); ++ #ifdef WOLFSSL_CHECK_MEM_ZERO ++ wc_MemZero_Add("wc_PKCS7 decryptedKey", decryptedKey, ++ MAX_ENCRYPTED_KEY_SZ); ++ #endif + } + #ifndef NO_PKCS7_STREAM + pkcs7->stream->key = decryptedKey; +@@ -14238,6 +14756,11 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, + break; + } + pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; ++ ++ /* Restore encOID across WANT_READ re-entries so the nonce ++ * length validation below always sees the content-cipher ++ * algorithm parsed in AUTHENV_3. */ ++ wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz, NULL); + #endif + /* get length of optional parameter sequence */ + if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) { +@@ -14255,6 +14778,46 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, + ret = ASN_PARSE_E; + } + ++ /* Enforce algorithm-specific nonce length bounds at the parser ++ * layer so malformed lengths (notably zero-length, which would ++ * catastrophically break AEAD uniqueness on HW backends that ++ * skip their own checks) cannot reach the cipher engine. ++ * - AES-GCM in CMS: RFC 5084 Sec. 3.2 mandates a 12-octet IV. ++ * - AES-CCM: RFC 3610 Sec. 2.3 requires 7..13 octets. ++ * Any other encOID here is a parser-state invariant violation. */ ++ if (ret == 0) { ++ int nonceMin = 0, nonceMax = 0; ++ switch (encOID) { ++ #ifdef HAVE_AESGCM ++ case AES128GCMb: ++ case AES192GCMb: ++ case AES256GCMb: ++ nonceMin = GCM_NONCE_MID_SZ; ++ nonceMax = GCM_NONCE_MID_SZ; ++ break; ++ #endif ++ #ifdef HAVE_AESCCM ++ case AES128CCMb: ++ case AES192CCMb: ++ case AES256CCMb: ++ nonceMin = CCM_NONCE_MIN_SZ; ++ nonceMax = CCM_NONCE_MAX_SZ; ++ break; ++ #endif ++ default: ++ WOLFSSL_MSG( ++ "AuthEnvelopedData unexpected content cipher"); ++ ret = ALGO_ID_E; ++ break; ++ } ++ if (ret == 0 && ++ (nonceSz < nonceMin || nonceSz > nonceMax)) { ++ WOLFSSL_MSG( ++ "AuthEnvelopedData nonce length invalid for cipher"); ++ ret = ASN_PARSE_E; ++ } ++ } ++ + if (ret == 0) { + XMEMCPY(nonce, &pkiMsg[idx], (word32)nonceSz); + idx += (word32)nonceSz; +@@ -14406,7 +14969,16 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, + if (GetLength_ex(pkiMsg, &idx, &length, pkiMsgSz, 0) <= 0) { + ret = ASN_PARSE_E; + } +- #ifndef NO_PKCS7_STREAM ++ ++ #ifdef NO_PKCS7_STREAM ++ /* In non-streaming mode, validate authenticatedAttributes ++ * length is within the input buffer. The streaming path ++ * handles this via wc_PKCS7_AddDataToStream instead. */ ++ if (ret == 0 && ++ (idx > pkiMsgSz || (word32)length > pkiMsgSz - idx)) { ++ ret = ASN_PARSE_E; ++ } ++ #else + pkcs7->stream->expected = (word32)length; + #endif + encodedAttribSz = (word32)length + (idx - encodedAttribIdx); +@@ -15274,6 +15846,12 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, + pkiMsgSz, NO_USER_CHECK) <= 0) + ret = ASN_PARSE_E; + ++#ifdef NO_PKCS7_STREAM ++ if (ret == 0 && encryptedContentSz > (int)(pkiMsgSz - idx)) { ++ ret = BUFFER_E; ++ } ++#endif ++ + if (ret < 0) + break; + #ifndef NO_PKCS7_STREAM +@@ -15311,7 +15889,8 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, + version = (int)pkcs7->stream->vers; + tmpIv = pkcs7->stream->tmpIv; + #endif +- if (encryptedContentSz <= 0) { ++ if (encryptedContentSz <= 0 || ++ encryptedContentSz > (int)(pkiMsgSz - idx)) { + ret = BUFFER_E; + break; + } +diff --git a/wolfssl/wolfcrypt/wc_encrypt.h b/wolfssl/wolfcrypt/wc_encrypt.h +index da11b5392..7f1c48b63 100644 +--- a/wolfssl/wolfcrypt/wc_encrypt.h ++++ b/wolfssl/wolfcrypt/wc_encrypt.h +@@ -73,6 +73,9 @@ + #ifndef CCM_NONCE_MIN_SZ + #define CCM_NONCE_MIN_SZ 7 + #endif ++ #ifndef CCM_NONCE_MAX_SZ ++ #define CCM_NONCE_MAX_SZ 13 ++ #endif + #endif + + diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 8802202114..5569df4d56 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -28,6 +28,7 @@ SRC_URI = " \ file://CVE-2026-6094-3.patch \ file://CVE-2026-6094-4.patch \ file://CVE-2026-6094-5.patch \ + file://CVE-2026-6291.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97498 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 EFEF0C79F99 for ; Mon, 7 Sep 2026 10:24:59 +0000 (UTC) Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31934.1788776690928682585 for ; Mon, 07 Sep 2026 03:24:50 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=ThFscdHq; spf=pass (domain: gmail.com, ip: 209.85.215.181, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-ca97d139d5fso3120287a12.0 for ; Mon, 07 Sep 2026 03:24:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776690; x=1789381490; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=mQlYGAtHaJZXMEbHQKrgByntMCHVWO72pU3Joy7ZYi4=; b=ThFscdHqUqk504Ym3vEWj6iaEREJ+J6PWIJ9Ei0G9ZAa4xRUGATmXuUTIgGVr8aAe2 uU8N0Iiymgcqz064hykZST48wpcxqyKfc8sv0uEi15zjPirkwmySgGO6WqFrVKfUtEqB 6VjqvS/RHpkDWLELFZeAOzOhX4EoxBIgdJKyegXU1/il4Zckc0xqCqBhl/olGhOIcOar 5yLH53tagOiBbVVVgogYs7ITKrLLKiFJp8jxhan30mDutkV0S1FNwtGD4mqTQVa31p73 Gc5Xt/gPDjvwZqTovExEHyY1vXi2JycA7uo+O2OCl1Y9DjLgZQYEaRdcgWo5oX8NzQgE 1WRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776690; x=1789381490; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=mQlYGAtHaJZXMEbHQKrgByntMCHVWO72pU3Joy7ZYi4=; b=W0Lgz/e4PV7hvAlBzjG3dDYlISHMLA1NysO2v/u/IITfYaG9fOnaqqZh9bxd7Q5ew5 6DVh9GDUJPcxHcTR8b3lZB+Eh/rYyNs2kgaJGQhIFJU+BS7raISMFq7BJNodpJy+T1zX 7MRSUFbgtB/fHJ9NMzkSi9z21YT4npsb3u7kr83NCeUo6IAdDKR3cVlnK39QnqQzCcQ0 FJmzpm51IawzQVaifBw5Na7rg4GlHIyPxSIEwmLOTwhxabYVdNMO2iKhZAjwGPTcKvYK +7rYq+OdgdlZT9wy9tT1PC0gRANXe5fcpOZPDXQ2F3WrRK0qkjKxqNLwGayhtiq1ThVr aKCQ== X-Gm-Message-State: AFuF++m+aiAFedgNTiduHHxRcEYST+LewaIwVq/ydqp+H3JVbOzQU41H ovLw4a7Vgv5YB+vdIsPanHsAUSxoMotq21106xuEYAiAPy1Sc+BdM8+EbkBLphSz X-Gm-Gg: AYBFou2r8AHPgmkN9JBfeQLAZ1cinwc6Bk5kl6kSoUBVaAAYmJD+Ybhn4FooISmS5AF 3E1Fzw1TIbv57PwmC0aZAQvRd9C1BT8TtUuGRqU9zgXWJ0EBOkZvmnXIDuV8PH9fW9DZaH787o1 sVeH/0TKGWRpym/F4GPA7RpcotCrffBVp/rQe7OxX93RhWxryO8hJddiOVBjYz2kTMuUt/3DQIB 2fAZcnmo3v4et0uc78fkSk2F7Pmi77X7XyLYlRCHU1y2wNq/VN0St6mk9YMm6z2WtB0qDMenSG8 OhDB1L1Y63cwIjMP5E85o7DBkR2oMp6OzGG5+1mQNmCp4YO2kWzE/g9Gu77WqW/+/ai/Pjs3txc XjTWGuD9N5Bdb2JiVe876fyN1U2SZ/RWczBCq5ktTPKqXvwQGw0/ULcIgl720k+slVPASKVZU6e DyLVY3WvvAXvFBfBBkK6W1alMVjRH6oAy/OToBpYgkmCpW13qD24KHlk9dDC9l/9NE5jEzzFGo X-Received: by 2002:a05:6a21:e081:b0:3b4:61f:1fec with SMTP id adf61e73a8af0-3da39bb593dmr33455823637.2.1788776689947; Mon, 07 Sep 2026 03:24:49 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:49 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 29/33] wolfssl: patch CVE-2026-6325 Date: Mon, 7 Sep 2026 22:23:13 +1200 Message-ID: <20260907102318.2459883-29-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129841 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-6325 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-6325.patch | 123 ++++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 1 + 2 files changed, 124 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6325.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6325.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6325.patch new file mode 100644 index 0000000000..5a67a30dc0 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6325.patch @@ -0,0 +1,123 @@ +From b47170ed386de50deb3f1ce7c9f39cdb17630fc0 Mon Sep 17 00:00:00 2001 +From: Sean Parkinson +Date: Wed, 15 Apr 2026 11:39:26 +1000 +Subject: [PATCH] Merge pull request #10204 from mattia-moffa/20260413-fixes + +SetSuitesHashSigAlgo fix + +(cherry picked from commit 6ac0f82b8589736e15683b7d94a822681b8949fc) + +CVE: CVE-2026-6325 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/6ac0f82b8589736e15683b7d94a822681b8949fc] + +Signed-off-by: Ankur Tyagi +--- + src/internal.c | 11 ++++++++++ + tests/api.c | 58 +++++++++++++++++++++++++++----------------------- + 2 files changed, 42 insertions(+), 27 deletions(-) + +diff --git a/src/internal.c b/src/internal.c +index 267c75a5d..769ba6764 100644 +--- a/src/internal.c ++++ b/src/internal.c +@@ -29546,6 +29546,17 @@ int SetSuitesHashSigAlgo(Suites* suites, const char* list) + break; + } + } ++ { ++ word32 needed = 2; ++#if defined(WC_RSA_PSS) && defined(WOLFSSL_TLS13) ++ if (sig_alg == rsa_pss_sa_algo) ++ needed = 4; ++#endif ++ if ((word32)idx + needed > WOLFSSL_MAX_SIGALGO) { ++ ret = 0; ++ break; ++ } ++ } + AddSuiteHashSigAlgo(suites->hashSigAlgo, mac_alg, sig_alg, 0, &idx); + sig_alg = 0; + mac_alg = no_mac; +diff --git a/tests/api.c b/tests/api.c +index 78fcf13ce..739cf0c68 100644 +--- a/tests/api.c ++++ b/tests/api.c +@@ -15878,6 +15878,33 @@ static int test_wolfSSL_set1_sigalgs_list(void) + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA+SHA256+RSA"), + WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); ++ ++ { ++ const char entry[] = "RSA+SHA256"; ++ const int entryLen = (int)sizeof(entry) - 1; ++ const int entries = WOLFSSL_MAX_SIGALGO + 1; ++ int listSz = entries * (entryLen + 1); ++ char* longList = (char*)XMALLOC(listSz, NULL, ++ DYNAMIC_TYPE_TMP_BUFFER); ++ int i; ++ int pos = 0; ++ ++ ExpectNotNull(longList); ++ if (longList != NULL) { ++ for (i = 0; i < entries; i++) { ++ if (i != 0) ++ longList[pos++] = ':'; ++ XMEMCPY(longList + pos, entry, entryLen); ++ pos += entryLen; ++ } ++ longList[pos] = '\0'; ++ ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, longList), ++ WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); ++ ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, longList), ++ WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); ++ XFREE(longList, NULL, DYNAMIC_TYPE_TMP_BUFFER); ++ } ++ } + #endif + #endif + #ifdef HAVE_ECC +@@ -35744,7 +35771,6 @@ static int test_pkcs7_padding(void) + int outSz; + int ctOff = -1; + int ctLen = 0; +- int i; + + XMEMSET(key, 0xAA, sizeof(key)); + XMEMSET(plaintext, 'X', sizeof(plaintext)); +@@ -35767,32 +35793,10 @@ static int test_pkcs7_padding(void) + (word32)encodedSz, output, sizeof(output)), (int)sizeof(plaintext)); + wc_PKCS7_Free(&pkcs7); + +- /* Find ciphertext block in encoded DER */ +- if (EXPECT_SUCCESS()) { +- for (i = encodedSz - 10; i > 10; i--) { +- if (encoded[i] == 0x04 || encoded[i] == 0x80) { +- int len, lbytes; +- +- if (encoded[i+1] < 0x80) { +- len = encoded[i+1]; lbytes = 1; +- } +- else if (encoded[i+1] == 0x81) { +- len = encoded[i+2]; lbytes = 2; +- } +- else { +- continue; +- } +- if (len > 0 && len % 16 == 0 && +- i + 1 + lbytes + len <= encodedSz) { +- ctOff = i + 1 + lbytes; +- ctLen = len; +- break; +- } +- } +- } +- } +- ExpectIntGT(ctOff, 0); +- ExpectIntGE(ctLen, 32); ++ /* encryptedContent is the last element in the DER, so it ends at encodedSz; ++ * 27-byte plaintext -> 32-byte AES-256-CBC ciphertext. */ ++ ctLen = 32; ++ ctOff = encodedSz - ctLen; + + /* Corrupt an interior padding byte via CBC bit-flip */ + if (EXPECT_SUCCESS()) { diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 5569df4d56..843d5071b4 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -29,6 +29,7 @@ SRC_URI = " \ file://CVE-2026-6094-4.patch \ file://CVE-2026-6094-5.patch \ file://CVE-2026-6291.patch \ + file://CVE-2026-6325.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97496 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 E3A01C79F9E for ; Mon, 7 Sep 2026 10:24:59 +0000 (UTC) Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31936.1788776693797183540 for ; Mon, 07 Sep 2026 03:24:53 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=GkfSLd/z; spf=pass (domain: gmail.com, ip: 209.85.216.45, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f45.google.com with SMTP id 98e67ed59e1d1-38e58034d05so2702097a91.2 for ; Mon, 07 Sep 2026 03:24:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776693; x=1789381493; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3Q0AnwnnzA5EhZWeGFmkxu3nw2tc44QV4zSf60KTbJ0=; b=GkfSLd/zEOaYJDh435aIAWWXljf/x40fjADsWkbk42V2oxtOqemhXzewWLEZ4wMZNv STlCvBnK6oQo/DsKd0Qgbr6MjjV94tYKDPyWvi8D7yWXR0+g47suyiZ7+q4jlfnIvXc+ jHJ+3VpNCACkhuB8MjIBmi/RlVkbmTZfsJZhyJiAyUK2fT/rJEACybsEGAeXr5g1SO0v XA/wCeetP8QEwlO8eGtqRZivCdOvcsQ56hSC7gvJJBh6BRUxfG9ZBr3UyPjuhCxZd6jy K95uo9iqfB8D/y3IND6/2Yi03cTITATbwBNkQLJF4IIpsApi+MP7LuTYYkjnBWCW9bTF WklQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776693; x=1789381493; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=3Q0AnwnnzA5EhZWeGFmkxu3nw2tc44QV4zSf60KTbJ0=; b=PxDeDLRd08juTTS2oWwzGdYLL+2vGUmvQMqMLRndJ3nAsLTJXmV5bp9gsvDqWrAvyM n/lvlJktBY8DR4BKXUsjtBGuWi3QeT0rIj/rBh5tqd5scD/N2TtDl3g0wJuhrq7vEE/m EQhAiy/na9tJ/cKsOCFBgOh2Zxj+ig5W5KotYR/rnQzYisJi69Reo3PKVAjqzeFNwep7 Dy1Et/6pfRf1gyX0EAvakGC+jy8dz9bHw4bnTcHuWtgwhWjeWUD2noKILvFvPTPdrYbi qW25Y/BDn+YwRXqKHtxkxA+q26w4GgpUFDnw3/rImftA5GYRoVb6iAqGiFyz4tLd7eCv m9aw== X-Gm-Message-State: AFuF++ljR0BUCehzlT1jgAe+aAvbIXBnSWsbcEKGx8xLGgDe+H1WjkZR khyBnA5B3FS5D7Skd0PWD+T3xra4guQXbxJUz3COJuECWzXcp6aJ1rmVLgIG1j/j X-Gm-Gg: AYBFou0+StpkLYuFe/mH08fLitUqmExx3J+6qnkKdPoaYXiYJ/G3u0d+Qsq3InFk+8u w/gIbwhxWYsXv8RlALxMivlcmKqdfAON1IffBxiedQwKRHtkewBipVZjMs9XM7ECEsDJ/rDD6JC prnSa82f4Xk6hKdcTJU4tig516Q8MQ3TJb+D75vXAncRzWt8cJzgl7kG92dxNQ5gUhtJYmGladw mG+rE6lHrdTnBY28qzcHTp41yom7Zgysk40N9e90OrfbMXWNcp10AUUpo1doSEWG7I+nLFeTkCw TnTlFAEL6K3a74gMFHOeTTAb4hjH3rqmrfn5D0BvReSj4h6g7af1UnG+OGTYJmSikplROKcHCpV jrYRpOpGNHpwIi+VDbvsUZKH3n5rT4lg+L79WVnrcrWBG/to+lB5+HkD2gZAZxd/50Hxi6uRNcE n/VOHVdojCadcMXSbE8qjK0aPuoXx/arLQqV+53sNH3yIKgfXxoIHwyys40G5PgrzC/vlB7if6 X-Received: by 2002:a17:90b:510c:b0:398:9be6:f999 with SMTP id 98e67ed59e1d1-39b262e27a9mr36574485a91.24.1788776693031; Mon, 07 Sep 2026 03:24:53 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:52 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 30/33] wolfssl: patch CVE-2026-6412 Date: Mon, 7 Sep 2026 22:23:14 +1200 Message-ID: <20260907102318.2459883-30-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129842 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-6412 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-6412-1.patch | 159 ++++++++++++++++++ .../wolfssl/files/CVE-2026-6412-2.patch | 56 ++++++ .../wolfssl/wolfssl_5.9.1.bb | 2 + 3 files changed, 217 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6412-1.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6412-2.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6412-1.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6412-1.patch new file mode 100644 index 0000000000..4d1d3b71cb --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6412-1.patch @@ -0,0 +1,159 @@ +From eda0a3001ebe036da39f8911a347174a759ffce0 Mon Sep 17 00:00:00 2001 +From: Eric Blankenhorn +Date: Tue, 14 Apr 2026 12:26:45 -0500 +Subject: [PATCH] Report cert verify failure with MD5 + +(cherry picked from commit 4a13896b2ea6d6080d41cd32539193713e69935f) + +CVE: CVE-2026-6412 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/4a13896b2ea6d6080d41cd32539193713e69935f] + +Signed-off-by: Ankur Tyagi +--- + .wolfssl_known_macro_extras | 1 + + tests/api/test_certman.c | 81 +++++++++++++++++++++++++++++++++++++ + tests/api/test_certman.h | 4 +- + wolfcrypt/src/asn.c | 7 ++++ + 4 files changed, 92 insertions(+), 1 deletion(-) + +diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras +index 3e411ca86..3233644ba 100644 +--- a/.wolfssl_known_macro_extras ++++ b/.wolfssl_known_macro_extras +@@ -680,6 +680,7 @@ WOLFSSL_ALLOW_CRIT_AIA + WOLFSSL_ALLOW_CRIT_AKID + WOLFSSL_ALLOW_CRIT_SKID + WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST ++WOLFSSL_ALLOW_MD5_CERT_SIGS + WOLFSSL_ALLOW_NO_CN_IN_SAN + WOLFSSL_ALLOW_NO_SUITES + WOLFSSL_ALLOW_SERVER_SC_EXT +diff --git a/tests/api/test_certman.c b/tests/api/test_certman.c +index dfce12334..9f87f4535 100644 +--- a/tests/api/test_certman.c ++++ b/tests/api/test_certman.c +@@ -2540,3 +2540,84 @@ int test_various_pathlen_chains(void) + #endif + return EXPECT_RESULT(); + } ++ ++/* Verify that certificates signed with MD5 (md5WithRSAEncryption) are ++ * rejected during chain verification. MD5 must not be acceptable as a ++ * certificate signature hash, even when MD5 is compiled in (e.g. for TLS ++ * 1.0 PRF or HMAC uses). Trust anchors are exempt from this check because ++ * ParseCertRelative skips ConfirmSignature for CA_TYPE. */ ++int test_wolfSSL_CertManagerRejectMD5Cert(void) ++{ ++ EXPECT_DECLS; ++#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(NO_MD5) && \ ++ !defined(WOLFSSL_ALLOW_MD5_CERT_SIGS) && defined(WOLFSSL_CERT_GEN) && \ ++ !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_ASN_CRYPT) && \ ++ !defined(USE_CERT_BUFFERS_1024) ++ WOLFSSL_CERT_MANAGER* cm = NULL; ++ RsaKey caKey; ++ WC_RNG rng; ++ Cert leaf; ++ byte* der = NULL; ++ int derSz = 0; ++ word32 idx = 0; ++ int caKeyInit = 0; ++ int rngInit = 0; ++ ++ XMEMSET(&caKey, 0, sizeof(caKey)); ++ XMEMSET(&rng, 0, sizeof(rng)); ++ ++ ExpectIntEQ(wc_InitRng(&rng), 0); ++ if (EXPECT_SUCCESS()) rngInit = 1; ++ ++ ExpectIntEQ(wc_InitRsaKey_ex(&caKey, HEAP_HINT, testDevId), 0); ++ if (EXPECT_SUCCESS()) caKeyInit = 1; ++ ExpectIntEQ(wc_RsaPrivateKeyDecode(ca_key_der_2048, &idx, &caKey, ++ sizeof_ca_key_der_2048), 0); ++ ++ ExpectNotNull(der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, ++ DYNAMIC_TYPE_TMP_BUFFER)); ++ ++ /* Build a leaf certificate whose issuer is the built-in 2048-bit ++ * wolfSSL test CA and sign it with MD5+RSA using the matching CA ++ * private key. */ ++ ExpectIntEQ(wc_InitCert(&leaf), 0); ++ leaf.sigType = CTC_MD5wRSA; ++ leaf.isCA = 0; ++ XSTRNCPY(leaf.subject.country, "US", CTC_NAME_SIZE); ++ XSTRNCPY(leaf.subject.state, "MT", CTC_NAME_SIZE); ++ XSTRNCPY(leaf.subject.locality, "Bozeman", CTC_NAME_SIZE); ++ XSTRNCPY(leaf.subject.org, "wolfSSL", CTC_NAME_SIZE); ++ XSTRNCPY(leaf.subject.unit, "Test", CTC_NAME_SIZE); ++ XSTRNCPY(leaf.subject.commonName, "md5-leaf", CTC_NAME_SIZE); ++ XSTRNCPY(leaf.subject.email, "info@wolfssl.com", CTC_NAME_SIZE); ++ ++ ExpectIntEQ(wc_SetIssuerBuffer(&leaf, ca_cert_der_2048, ++ sizeof_ca_cert_der_2048), 0); ++ ++ /* wc_MakeCert needs an RSA public key for the subject; reuse caKey ++ * for simplicity (we only care about signature-side verification). */ ++ ExpectIntGT((derSz = wc_MakeCert(&leaf, der, FOURK_BUF, &caKey, NULL, ++ &rng)), 0); ++ ExpectIntGT((derSz = wc_SignCert(leaf.bodySz, leaf.sigType, der, ++ FOURK_BUF, &caKey, NULL, &rng)), 0); ++ ++ /* Load the SHA-256 signed CA cert as a trust anchor and attempt ++ * to verify the MD5-signed leaf: it must be rejected because ++ * HashForSignature() now returns HASH_TYPE_E for MD5 in verify mode, ++ * which surfaces as ASN_SIG_CONFIRM_E from ConfirmSignature(). */ ++ ExpectNotNull(cm = wolfSSL_CertManagerNew()); ++ ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, ca_cert_der_2048, ++ sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1), ++ WOLFSSL_SUCCESS); ++ ++ ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz, ++ WOLFSSL_FILETYPE_ASN1), ++ WC_NO_ERR_TRACE(HASH_TYPE_E)); ++ ++ wolfSSL_CertManagerFree(cm); ++ XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); ++ if (caKeyInit) wc_FreeRsaKey(&caKey); ++ if (rngInit) wc_FreeRng(&rng); ++#endif ++ return EXPECT_RESULT(); ++} +diff --git a/tests/api/test_certman.h b/tests/api/test_certman.h +index 1588c81ec..a0b5d9548 100644 +--- a/tests/api/test_certman.h ++++ b/tests/api/test_certman.h +@@ -41,6 +41,7 @@ int test_wolfSSL_CRL_static_revoked_list(void); + int test_wolfSSL_CRL_duplicate_extensions(void); + int test_wolfSSL_CertManagerCheckOCSPResponse(void); + int test_various_pathlen_chains(void); ++int test_wolfSSL_CertManagerRejectMD5Cert(void); + + #define TEST_CERTMAN_DECLS \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerAPI), \ +@@ -59,7 +60,8 @@ int test_various_pathlen_chains(void); + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_static_revoked_list), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_duplicate_extensions), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerCheckOCSPResponse), \ +- TEST_DECL_GROUP("certman", test_various_pathlen_chains) ++ TEST_DECL_GROUP("certman", test_various_pathlen_chains), \ ++ TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerRejectMD5Cert) + + #endif /* WOLFCRYPT_TEST_CERTMAN_H */ + +diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c +index fea449863..8d4f40a70 100644 +--- a/wolfcrypt/src/asn.c ++++ b/wolfcrypt/src/asn.c +@@ -15880,6 +15880,13 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID, + #endif + #ifndef NO_MD5 + case CTC_MD5wRSA: ++ #ifndef WOLFSSL_ALLOW_MD5_CERT_SIGS ++ if (verify) { ++ ret = HASH_TYPE_E; ++ WOLFSSL_MSG("MD5 not supported for certificate verification"); ++ break; ++ } ++ #endif + if ((ret = wc_Md5Hash_ex(buf, bufSz, digest, heap, devId)) == 0) { + *typeH = MD5h; + *digestSz = WC_MD5_DIGEST_SIZE; diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6412-2.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6412-2.patch new file mode 100644 index 0000000000..0747e9dd99 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6412-2.patch @@ -0,0 +1,56 @@ +From ab4cfd06ce09ca6aa33e06ca12bcfc1186c9f357 Mon Sep 17 00:00:00 2001 +From: Eric Blankenhorn +Date: Tue, 14 Apr 2026 13:39:17 -0500 +Subject: [PATCH] Fix from review + +(cherry picked from commit a8ea8a898c45a4199ac196044ac14314dc82d981) + +CVE: CVE-2026-6412 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/a8ea8a898c45a4199ac196044ac14314dc82d981] + +Signed-off-by: Ankur Tyagi +--- + tests/api/test_certman.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/tests/api/test_certman.c b/tests/api/test_certman.c +index 9f87f4535..6c5875dc5 100644 +--- a/tests/api/test_certman.c ++++ b/tests/api/test_certman.c +@@ -2576,6 +2576,9 @@ int test_wolfSSL_CertManagerRejectMD5Cert(void) + + ExpectNotNull(der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, + DYNAMIC_TYPE_TMP_BUFFER)); ++ if (der == NULL) { ++ goto cleanup; ++ } + + /* Build a leaf certificate whose issuer is the built-in 2048-bit + * wolfSSL test CA and sign it with MD5+RSA using the matching CA +@@ -2604,16 +2607,19 @@ int test_wolfSSL_CertManagerRejectMD5Cert(void) + /* Load the SHA-256 signed CA cert as a trust anchor and attempt + * to verify the MD5-signed leaf: it must be rejected because + * HashForSignature() now returns HASH_TYPE_E for MD5 in verify mode, +- * which surfaces as ASN_SIG_CONFIRM_E from ConfirmSignature(). */ ++ * and wolfSSL_CertManagerVerifyBuffer() returns that error. */ + ExpectNotNull(cm = wolfSSL_CertManagerNew()); +- ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, ca_cert_der_2048, +- sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1), +- WOLFSSL_SUCCESS); ++ if (cm != NULL) { ++ ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, ca_cert_der_2048, ++ sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1), ++ WOLFSSL_SUCCESS); + +- ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz, +- WOLFSSL_FILETYPE_ASN1), +- WC_NO_ERR_TRACE(HASH_TYPE_E)); ++ ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz, ++ WOLFSSL_FILETYPE_ASN1), ++ WC_NO_ERR_TRACE(HASH_TYPE_E)); ++ } + ++cleanup: + wolfSSL_CertManagerFree(cm); + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (caKeyInit) wc_FreeRsaKey(&caKey); diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 843d5071b4..4ca330b029 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -30,6 +30,8 @@ SRC_URI = " \ file://CVE-2026-6094-5.patch \ file://CVE-2026-6291.patch \ file://CVE-2026-6325.patch \ + file://CVE-2026-6412-1.patch \ + file://CVE-2026-6412-2.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97497 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 DA79FC79F89 for ; Mon, 7 Sep 2026 10:24:59 +0000 (UTC) Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31937.1788776697551896171 for ; Mon, 07 Sep 2026 03:24:57 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=svTCuDIN; spf=pass (domain: gmail.com, ip: 209.85.215.179, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-cc439bfb2d8so2062043a12.2 for ; Mon, 07 Sep 2026 03:24:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776697; x=1789381497; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=tjzh77E/Rpe2xgYO3ANHSZG+5Pkepzyjgmd9Btc6eFc=; b=svTCuDINLKE93T95hU2nvBOJN2fyLI9YaRq0XrQc167irUYfnDVTzEjZcUACOmmL+K /WdVcql/CyB2C8ZkcOFRNjdnyuv1gF9Oz9Pn5XPmcB6SAcoESbSG0vDSTI7fxwv6rUK2 X8F8Bre0rrgkW3KKiRB42RBZqrBi9Y6jADa2ttBEw1KubJrfQoL+SEYjcN+Zh5PlJpgN vRbu/8IIljv5/VGOCNUD17OkSfD2IZeF9VZOS/S9OF0vAEjV7YpnxrFgpZ32ZcRPT37W 49eh5pNfYHfGIZm+C9G1arv1kIXA/NgomX2T3Lxi57mW9waAwE/wosHjGLN0u6DlYC4n Be+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776697; x=1789381497; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=tjzh77E/Rpe2xgYO3ANHSZG+5Pkepzyjgmd9Btc6eFc=; b=E8/4RsoRJMuSpUpUe8m7OkxXxYYVYb/LoyNDVWqCp7zPh+j0RBXDDrZTXa76DgQgcu ntG+5O80xXdjuqufWmiyB1JEskc253RPIoz1MNcrTf42gcwtv7vzUlauwPGCHeXhMF49 7UY5IzlfHURe/OiHBOCKsbdMwutjX5OmtpB/Tj56m919W4UZkdcaMJnW9PSYPYnV7cqe Vjv7XcS9PSyVIAmetUKEm3OS+b+tzLL5PCrLCsmfIi1nimDx/gULl9m/95ymegvWHwyB 5yv1OCT2Tc4I66XnQnKG9jE6jMjlijk3No41UxJRUmoiQrg0sFNJ8slhkGh9PTmaTx6M k3AQ== X-Gm-Message-State: AFuF++lq7lOr2yWsWvNSFvFr3F98g2dpYj4pp+ts/FDTUdHjM59g2C6N L2rs3iSOyMkyiUfsRY6xZPKh2B4VfSPDVbDpPuLhDLSpxl6jFj5K0Id6/8kKgg== X-Gm-Gg: AYBFou2COh4dec414GXDV5z92K4IO4JPsDYQR6KFrcDsE4nnOXnXgIeDzp/u2XLJzbo +6JmHebJUbMk7sNfQ3nRFoEIlY762JlBpnZQutPLhUvdIuhLP/p2afU8/u+zVRiKCu+BA26a4Aa P1JkwyS8HJ8F8xbtFTZ5C05CtXhCrDrjZgNufrgPldAXIQNSCMs54xzVhBp6hvpswPYgKjCojLV exES9lvT15ggoyES7R3IgzIMm1/ofngw8jZLHDprjwW5tbI9mkE4E2iaRXCt6wQYYyO9k5Mx9SW xHzulg1mZA5v0xrM7ow7OsIK4oJSCZOrR5YxKOZCvbd7S20HzoFXluCnzBxopS4+Nl+uzXqcl7d P3vB4pWJcHtSVirMi6BnrMiCDwg3DL2bnfeKX6WfC5he7bbtckem3h83lBulpr02APUIdOY/fRS LbP8MsfsPdtN3/8G74hUSMcGpPdFGp0pxCQ9qZsb7VYqfXAa8i3eIeUX3c2o4OdxJzumbZjqtz X-Received: by 2002:a17:90b:33c1:b0:398:9bd1:3214 with SMTP id 98e67ed59e1d1-39b262dfa81mr30756334a91.21.1788776696170; Mon, 07 Sep 2026 03:24:56 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:55 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 31/33] wolfssl: patch CVE-2026-6450 Date: Mon, 7 Sep 2026 22:23:15 +1200 Message-ID: <20260907102318.2459883-31-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:24:59 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129843 From: Ankur Tyagi Also backport follow-up PR[1] to the initial PR mentioned in the NVD. Details: https://nvd.nist.gov/vuln/detail/cve-2026-6450 [1]https://github.com/wolfSSL/wolfssl/pull/10274 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-6450-1.patch | 456 ++++++++++++++++++ .../wolfssl/files/CVE-2026-6450-2.patch | 404 ++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 2 + 3 files changed, 862 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6450-1.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6450-2.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6450-1.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6450-1.patch new file mode 100644 index 0000000000..a754fc3e33 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6450-1.patch @@ -0,0 +1,456 @@ +From b60e4b6fc0d757f5983a803ad02a1a57c0d0a463 Mon Sep 17 00:00:00 2001 +From: Reda Chouk +Date: Thu, 16 Apr 2026 19:45:09 +0200 +Subject: [PATCH] reject crls with unrecognized critical extensions per rfc + 5280 section 5.2 + +(cherry picked from commit 857141da35b67a14a580fb26ec57af1efa68a1d9) + +CVE: CVE-2026-6450 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/857141da35b67a14a580fb26ec57af1efa68a1d9] + +Signed-off-by: Ankur Tyagi +--- + tests/api/test_certman.c | 342 +++++++++++++++++++++++++++++++++++++++ + tests/api/test_certman.h | 4 + + wolfcrypt/src/asn.c | 7 +- + wolfcrypt/src/asn_orig.c | 9 +- + 4 files changed, 359 insertions(+), 3 deletions(-) + +diff --git a/tests/api/test_certman.c b/tests/api/test_certman.c +index 6c5875dc5..7405f4bff 100644 +--- a/tests/api/test_certman.c ++++ b/tests/api/test_certman.c +@@ -1964,6 +1964,348 @@ int test_wolfSSL_CRL_duplicate_extensions(void) + return EXPECT_RESULT(); + } + ++int test_wolfSSL_CRL_critical_idp(void) ++{ ++ EXPECT_DECLS; ++#if !defined(NO_CERTS) && defined(HAVE_CRL) && !defined(NO_RSA) ++ ++ /* CA cert (CN=claim-root), self-signed, 799 bytes DER */ ++ static const unsigned char ca_cert_idp[] = { ++ 0x30, 0x82, 0x03, 0x1b, 0x30, 0x82, 0x02, 0x03, 0xa0, 0x03, 0x02, ++ 0x01, 0x02, 0x02, 0x14, 0x1e, 0x25, 0xc1, 0x5d, 0x6f, 0x02, 0x21, ++ 0xa0, 0xf0, 0x14, 0x15, 0x9c, 0x3b, 0x4d, 0x1d, 0x73, 0x16, 0x00, ++ 0xe4, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, ++ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, ++ 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x63, 0x6c, 0x61, ++ 0x69, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, ++ 0x32, 0x36, 0x30, 0x34, 0x31, 0x36, 0x31, 0x31, 0x33, 0x38, 0x35, ++ 0x35, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x34, 0x31, 0x33, 0x31, ++ 0x31, 0x33, 0x38, 0x35, 0x35, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, ++ 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x63, 0x6c, 0x61, ++ 0x69, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x82, 0x01, 0x22, ++ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, ++ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, ++ 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xba, 0x49, 0x8c, 0xb5, ++ 0x17, 0xc1, 0x01, 0x24, 0x6f, 0x56, 0x1a, 0xa9, 0x3b, 0x03, 0xe2, ++ 0x9f, 0x24, 0xb1, 0x25, 0x98, 0xfb, 0x38, 0x82, 0x78, 0x54, 0xa7, ++ 0x1f, 0x69, 0x87, 0xe4, 0x96, 0x1b, 0x81, 0x18, 0x10, 0xb0, 0xc0, ++ 0x5b, 0x4b, 0xbf, 0xb8, 0x1d, 0xf4, 0xee, 0x75, 0x0f, 0xb5, 0x45, ++ 0x72, 0x70, 0xce, 0x65, 0x84, 0x44, 0x3e, 0x30, 0x78, 0xc4, 0xf3, ++ 0xec, 0xba, 0x96, 0x78, 0xa4, 0x65, 0xfc, 0x62, 0x8d, 0xf5, 0x29, ++ 0xf9, 0x7c, 0x3d, 0x78, 0x6c, 0x1d, 0x4a, 0x4c, 0xc9, 0x15, 0x2d, ++ 0x22, 0x10, 0xea, 0x93, 0x26, 0xb8, 0xa6, 0x17, 0xd3, 0x0e, 0xbc, ++ 0x0c, 0xab, 0x83, 0x63, 0xf6, 0x1c, 0xcc, 0x83, 0x73, 0x29, 0x7e, ++ 0x7f, 0x83, 0x7f, 0xbd, 0x63, 0xaa, 0x8d, 0xfa, 0x78, 0x85, 0xd2, ++ 0x3e, 0x60, 0x95, 0x5a, 0x8d, 0xfa, 0x8f, 0xcd, 0x94, 0x3f, 0x13, ++ 0x28, 0xd9, 0xd0, 0x87, 0x28, 0x17, 0x78, 0xe2, 0x61, 0x8d, 0x79, ++ 0x97, 0x01, 0xa9, 0x7c, 0x84, 0xc0, 0x1c, 0xbe, 0x5f, 0x5d, 0xca, ++ 0x28, 0x6b, 0x5e, 0xdd, 0x83, 0xa5, 0x55, 0x34, 0x11, 0xba, 0xfa, ++ 0x8b, 0x92, 0xa3, 0xde, 0xb6, 0xf3, 0xba, 0xab, 0x7f, 0x1a, 0x67, ++ 0xfd, 0x6f, 0x20, 0x85, 0x4c, 0x77, 0xa7, 0x8e, 0xbe, 0xb8, 0xf8, ++ 0x8f, 0x70, 0xe3, 0x5a, 0xd3, 0x77, 0xc9, 0x9e, 0x10, 0x60, 0xb4, ++ 0xdb, 0x0c, 0xc5, 0x05, 0xe1, 0x1f, 0xbd, 0xe6, 0x79, 0xee, 0x82, ++ 0x3f, 0x51, 0x76, 0xe2, 0x7f, 0x5c, 0x11, 0x6d, 0xd3, 0x21, 0x69, ++ 0xec, 0x05, 0x11, 0x8b, 0xc8, 0x39, 0xb3, 0x2c, 0xa6, 0x83, 0xb4, ++ 0x6f, 0xac, 0x19, 0xd6, 0x6a, 0x65, 0x0d, 0x08, 0x94, 0x58, 0xde, ++ 0x3d, 0xc9, 0x0c, 0x54, 0x03, 0x73, 0x0c, 0x8d, 0x24, 0x09, 0xf3, ++ 0xb1, 0x5d, 0xd2, 0xe3, 0xeb, 0x56, 0xd6, 0x28, 0x66, 0x5b, 0x02, ++ 0x03, 0x01, 0x00, 0x01, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x0f, 0x06, ++ 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, ++ 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, ++ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, ++ 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x52, 0x97, 0x58, ++ 0x47, 0x98, 0xca, 0xf8, 0x99, 0xa0, 0x7e, 0x8e, 0x1c, 0x38, 0x2e, ++ 0xea, 0xbb, 0xea, 0x9b, 0x74, 0x30, 0x30, 0x1f, 0x06, 0x03, 0x55, ++ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x52, 0x97, 0x58, ++ 0x47, 0x98, 0xca, 0xf8, 0x99, 0xa0, 0x7e, 0x8e, 0x1c, 0x38, 0x2e, ++ 0xea, 0xbb, 0xea, 0x9b, 0x74, 0x30, 0x30, 0x0d, 0x06, 0x09, 0x2a, ++ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, ++ 0x82, 0x01, 0x01, 0x00, 0x7d, 0x30, 0xd4, 0x6a, 0x01, 0x89, 0x3b, ++ 0x62, 0xed, 0x16, 0x46, 0x59, 0x0f, 0xf2, 0x3b, 0xb5, 0xde, 0x89, ++ 0x08, 0x17, 0x68, 0xcb, 0x46, 0xdc, 0x39, 0xa6, 0xcb, 0x56, 0xb0, ++ 0x91, 0xeb, 0x03, 0xb2, 0x15, 0xc4, 0x3b, 0x4d, 0x63, 0x55, 0x22, ++ 0x0a, 0x26, 0xe6, 0x64, 0x46, 0xe8, 0x0f, 0xa8, 0xf3, 0xde, 0xe1, ++ 0x43, 0x54, 0xe6, 0xd7, 0x8a, 0xf4, 0x4f, 0xab, 0x56, 0x93, 0x12, ++ 0x71, 0x4b, 0x25, 0x71, 0x0a, 0x31, 0x18, 0x79, 0xee, 0x45, 0xa4, ++ 0xf5, 0x72, 0x67, 0xfa, 0x41, 0xd9, 0x87, 0x97, 0x09, 0xef, 0x55, ++ 0xad, 0x6f, 0x47, 0x1d, 0x5a, 0xb2, 0xe9, 0xf7, 0x22, 0x05, 0x2d, ++ 0x5a, 0x81, 0xa8, 0xe8, 0x53, 0xb0, 0x94, 0xf6, 0x63, 0xff, 0x3f, ++ 0x51, 0x7a, 0x08, 0xac, 0x27, 0x9a, 0x57, 0x11, 0x22, 0xa4, 0x00, ++ 0x84, 0x70, 0x86, 0x76, 0x39, 0x0f, 0x4f, 0x57, 0xcf, 0x8e, 0x94, ++ 0xd2, 0x8e, 0x43, 0xc0, 0xd5, 0x34, 0x7d, 0xf5, 0xa1, 0x45, 0x1e, ++ 0xb7, 0xc8, 0x7e, 0x7c, 0xfe, 0x5d, 0x4d, 0x53, 0x43, 0x25, 0x15, ++ 0x9e, 0x08, 0x01, 0x56, 0xa4, 0xff, 0x79, 0x59, 0x25, 0xc9, 0x23, ++ 0x98, 0xaf, 0x05, 0xaf, 0xc1, 0x0b, 0x29, 0xf1, 0xe2, 0xc4, 0x36, ++ 0x31, 0x91, 0xfa, 0xf2, 0xbb, 0x12, 0xe8, 0x67, 0xf9, 0xc7, 0xa1, ++ 0x5e, 0x8c, 0xed, 0x92, 0x12, 0xa3, 0x2b, 0xe1, 0xc2, 0xe1, 0xa0, ++ 0xb0, 0x0e, 0x12, 0xa7, 0xd0, 0xa2, 0xae, 0xd6, 0xfa, 0x30, 0x21, ++ 0x0f, 0x73, 0xfe, 0x24, 0x21, 0x5f, 0x03, 0x86, 0x69, 0xcd, 0xec, ++ 0x76, 0x18, 0xe1, 0xfd, 0xb6, 0x64, 0x90, 0xa6, 0x06, 0x2e, 0x19, ++ 0x40, 0x93, 0x50, 0x37, 0xe4, 0x90, 0xe3, 0x1f, 0x07, 0xae, 0xfb, ++ 0x89, 0xc3, 0xf6, 0xc4, 0x90, 0xab, 0x40, 0x67, 0x4c, 0x43, 0x2c, ++ 0xa2, 0xb0, 0x3e, 0x61, 0x16, 0x69, 0x8f ++ }; ++ ++ /* CRL with critical IDP onlyuser=TRUE, revokes serial 0x1000, 480 bytes */ ++ static const unsigned char crl_user_idp[] = { ++ 0x30, 0x82, 0x01, 0xdc, 0x30, 0x81, 0xc5, 0x02, 0x01, 0x01, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, ++ 0x0b, 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, ++ 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2d, ++ 0x72, 0x6f, 0x6f, 0x74, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x34, 0x31, ++ 0x36, 0x31, 0x31, 0x33, 0x38, 0x35, 0x35, 0x5a, 0x17, 0x0d, 0x33, ++ 0x36, 0x30, 0x34, 0x31, 0x33, 0x31, 0x31, 0x33, 0x38, 0x35, 0x35, ++ 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x02, 0x10, 0x00, 0x17, 0x0d, ++ 0x32, 0x36, 0x30, 0x34, 0x31, 0x36, 0x31, 0x31, 0x33, 0x38, 0x35, ++ 0x35, 0x5a, 0xa0, 0x65, 0x30, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, ++ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x52, 0x97, 0x58, ++ 0x47, 0x98, 0xca, 0xf8, 0x99, 0xa0, 0x7e, 0x8e, 0x1c, 0x38, 0x2e, ++ 0xea, 0xbb, 0xea, 0x9b, 0x74, 0x30, 0x30, 0x33, 0x06, 0x03, 0x55, ++ 0x1d, 0x1c, 0x01, 0x01, 0xff, 0x04, 0x29, 0x30, 0x27, 0xa0, 0x22, ++ 0xa0, 0x20, 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, ++ 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2f, ++ 0x63, 0x72, 0x6c, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x65, ++ 0x6d, 0x81, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x14, ++ 0x04, 0x04, 0x02, 0x02, 0x20, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, ++ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, ++ 0x82, 0x01, 0x01, 0x00, 0x9b, 0x1a, 0x70, 0xba, 0xf8, 0x38, 0xff, ++ 0xc6, 0x36, 0x59, 0x6e, 0xab, 0x87, 0x74, 0x04, 0xe3, 0x17, 0xb3, ++ 0xdd, 0x62, 0x03, 0x25, 0x9e, 0xff, 0x53, 0xf7, 0xde, 0x48, 0xb0, ++ 0x56, 0x0c, 0x19, 0xea, 0x86, 0x30, 0x21, 0x01, 0x63, 0xd6, 0xd2, ++ 0xef, 0xd1, 0x0e, 0x1d, 0xde, 0xc1, 0x18, 0x33, 0xd2, 0x1b, 0x79, ++ 0x2e, 0xa1, 0xd5, 0x51, 0xcc, 0x31, 0x35, 0x28, 0xa6, 0x6f, 0xc0, ++ 0xcf, 0x78, 0xbf, 0x5d, 0xdd, 0x66, 0x81, 0x71, 0xa3, 0x52, 0xb5, ++ 0x48, 0x81, 0x1a, 0x34, 0xf1, 0x03, 0x37, 0x3a, 0x97, 0x02, 0xd6, ++ 0x56, 0x4a, 0x24, 0xeb, 0x93, 0x47, 0xb6, 0xc3, 0x69, 0xc6, 0x2b, ++ 0xd8, 0xfc, 0xf9, 0x9f, 0x85, 0xab, 0xe2, 0x81, 0x66, 0x8f, 0xcf, ++ 0x7a, 0x81, 0xd7, 0x46, 0xb4, 0x8d, 0x44, 0x05, 0x40, 0xd2, 0x3b, ++ 0x1c, 0xb8, 0x4a, 0x88, 0xb8, 0x65, 0x69, 0x5e, 0x7f, 0x6c, 0x43, ++ 0x1c, 0x4f, 0xbf, 0x48, 0x55, 0x6b, 0xb0, 0xb3, 0x70, 0x49, 0x1a, ++ 0xfa, 0xd1, 0x55, 0xe7, 0xb9, 0x5d, 0x4f, 0x2d, 0x7e, 0xc1, 0xa5, ++ 0x5f, 0x5e, 0x38, 0xef, 0x74, 0xe8, 0x72, 0x89, 0x9c, 0x86, 0x24, ++ 0x65, 0x2d, 0x38, 0x88, 0x53, 0x81, 0x48, 0x8a, 0x7d, 0xc3, 0x0d, ++ 0x87, 0xaf, 0xd3, 0xf7, 0x39, 0xeb, 0xac, 0x36, 0xc2, 0xc9, 0x1f, ++ 0x78, 0xa9, 0x53, 0x1c, 0x4a, 0xa6, 0xba, 0x63, 0xd1, 0xc2, 0x62, ++ 0x81, 0x00, 0x39, 0xb1, 0x1c, 0x1c, 0xad, 0x96, 0x83, 0xf7, 0x99, ++ 0x34, 0xc6, 0x9c, 0x93, 0xbb, 0x6a, 0x7c, 0xf5, 0x18, 0xed, 0xbd, ++ 0x29, 0xe4, 0x29, 0x50, 0x3c, 0xcb, 0x94, 0x72, 0x8f, 0xad, 0x15, ++ 0x91, 0x38, 0x4a, 0xb4, 0xde, 0x98, 0x3e, 0xd6, 0xb2, 0xd1, 0x2a, ++ 0x8c, 0xa2, 0xc9, 0x0f, 0x2f, 0x7c, 0x4a, 0xd6, 0x56, 0x02, 0x9f, ++ 0x6c, 0xda, 0xa9, 0x4c, 0x04, 0x64, 0x7c ++ }; ++ ++ /* CRL with critical IDP onlyCA=TRUE, empty revocation list, 459 bytes */ ++ static const unsigned char crl_caonly_idp[] = { ++ 0x30, 0x82, 0x01, 0xc7, 0x30, 0x81, 0xb0, 0x02, 0x01, 0x01, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, ++ 0x0b, 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, ++ 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2d, ++ 0x72, 0x6f, 0x6f, 0x74, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x34, 0x31, ++ 0x36, 0x31, 0x31, 0x33, 0x38, 0x35, 0x35, 0x5a, 0x17, 0x0d, 0x33, ++ 0x36, 0x30, 0x34, 0x31, 0x33, 0x31, 0x31, 0x33, 0x38, 0x35, 0x35, ++ 0x5a, 0xa0, 0x67, 0x30, 0x65, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, ++ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x52, 0x97, 0x58, 0x47, ++ 0x98, 0xca, 0xf8, 0x99, 0xa0, 0x7e, 0x8e, 0x1c, 0x38, 0x2e, 0xea, ++ 0xbb, 0xea, 0x9b, 0x74, 0x30, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, ++ 0x1c, 0x01, 0x01, 0xff, 0x04, 0x2b, 0x30, 0x29, 0xa0, 0x24, 0xa0, ++ 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, ++ 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x63, ++ 0x72, 0x6c, 0x2d, 0x63, 0x61, 0x6f, 0x6e, 0x6c, 0x79, 0x2e, 0x70, ++ 0x65, 0x6d, 0x82, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, ++ 0x14, 0x04, 0x04, 0x02, 0x02, 0x20, 0x01, 0x30, 0x0d, 0x06, 0x09, ++ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, ++ 0x03, 0x82, 0x01, 0x01, 0x00, 0x9d, 0x6e, 0x0d, 0x93, 0x89, 0xab, ++ 0x6e, 0x74, 0x52, 0x2c, 0xe6, 0x89, 0xcb, 0x72, 0x49, 0x90, 0x0d, ++ 0x91, 0x80, 0xb5, 0xca, 0x7b, 0x95, 0x0d, 0xa8, 0x05, 0x31, 0x04, ++ 0x50, 0xb8, 0xf3, 0xce, 0x9c, 0xbb, 0x05, 0x38, 0x0a, 0x64, 0x1a, ++ 0x61, 0x68, 0xa7, 0xa8, 0xa0, 0x69, 0x2a, 0x79, 0x01, 0x42, 0x67, ++ 0xf5, 0x72, 0xdf, 0x37, 0x5b, 0x42, 0x6d, 0x3c, 0x59, 0x95, 0x09, ++ 0x34, 0xb3, 0xb6, 0x8b, 0x2b, 0xd8, 0xab, 0xb6, 0x8b, 0xff, 0x8e, ++ 0xae, 0xd0, 0xc6, 0x9a, 0xbe, 0x7e, 0x29, 0xbc, 0x4d, 0xfb, 0xe1, ++ 0xac, 0xd8, 0x23, 0x1a, 0xec, 0x0d, 0xa1, 0xa0, 0xf6, 0x52, 0x8e, ++ 0x64, 0xc4, 0x11, 0x0f, 0x7c, 0x5b, 0x9f, 0x65, 0x4f, 0x5a, 0xd6, ++ 0x64, 0xe0, 0x64, 0xf6, 0xac, 0x9d, 0xdc, 0x21, 0x3f, 0xa8, 0x5c, ++ 0xd2, 0xf5, 0x87, 0xec, 0x49, 0x19, 0xff, 0x01, 0x9e, 0x8d, 0x83, ++ 0x08, 0xd2, 0xdc, 0x83, 0xf6, 0x03, 0xc4, 0x6f, 0xf6, 0xa2, 0x13, ++ 0x41, 0xfe, 0x66, 0xcd, 0xeb, 0xe8, 0x0f, 0x28, 0x7d, 0xd2, 0xcd, ++ 0xfa, 0x7a, 0xd7, 0xae, 0x08, 0xa1, 0x31, 0x17, 0x60, 0x59, 0x39, ++ 0x98, 0x85, 0xe1, 0xa4, 0xd2, 0x35, 0x70, 0xb7, 0xff, 0xf3, 0x2f, ++ 0xee, 0x45, 0x9c, 0xbe, 0xcc, 0x18, 0x49, 0x94, 0xe9, 0xf6, 0xd0, ++ 0x45, 0x54, 0x6f, 0xe4, 0xe8, 0x3a, 0x0d, 0x5b, 0x05, 0xe8, 0x02, ++ 0x51, 0x5b, 0x63, 0xb5, 0xf2, 0x47, 0x86, 0x9b, 0xf3, 0x07, 0xc2, ++ 0x49, 0x26, 0xa0, 0x77, 0x94, 0xe7, 0x4f, 0xbc, 0x5f, 0x9f, 0xf9, ++ 0x06, 0x0e, 0xcb, 0x45, 0x9c, 0x02, 0x11, 0xfc, 0xcb, 0x12, 0x7f, ++ 0xba, 0x7d, 0x93, 0x5b, 0x57, 0x6a, 0x15, 0x5e, 0xd2, 0xc1, 0x97, ++ 0xb2, 0xbb, 0x00, 0x2c, 0xdd, 0x41, 0x97, 0x2a, 0xe4, 0x53, 0x40, ++ 0xf8, 0xb5, 0x56, 0xf2, 0x9a, 0x04, 0xe6, 0x89 ++ }; ++ ++ WOLFSSL_CERT_MANAGER* cm = NULL; ++ ++ ExpectNotNull(cm = wolfSSL_CertManagerNew()); ++ ++ ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, ca_cert_idp, ++ sizeof(ca_cert_idp), WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); ++ ++ ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECKALL), ++ WOLFSSL_SUCCESS); ++ ++ /* User-scope CRL has a critical IDP extension, must be rejected */ ++ ExpectIntNE(wolfSSL_CertManagerLoadCRLBuffer(cm, crl_user_idp, ++ sizeof(crl_user_idp), WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); ++ ++ /* CA-only CRL also has a critical IDP extension, must be rejected */ ++ ExpectIntNE(wolfSSL_CertManagerLoadCRLBuffer(cm, crl_caonly_idp, ++ sizeof(crl_caonly_idp), WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); ++ ++ wolfSSL_CertManagerFree(cm); ++#endif ++ return EXPECT_RESULT(); ++} ++ ++int test_wolfSSL_CRL_unknown_critical_ext(void) ++{ ++ EXPECT_DECLS; ++#if !defined(NO_CERTS) && defined(HAVE_CRL) && !defined(NO_RSA) ++ ++ static const unsigned char ca_cert[] = { ++ 0x30, 0x82, 0x03, 0x1b, 0x30, 0x82, 0x02, 0x03, 0xa0, 0x03, 0x02, ++ 0x01, 0x02, 0x02, 0x14, 0x1e, 0x25, 0xc1, 0x5d, 0x6f, 0x02, 0x21, ++ 0xa0, 0xf0, 0x14, 0x15, 0x9c, 0x3b, 0x4d, 0x1d, 0x73, 0x16, 0x00, ++ 0xe4, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, ++ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, ++ 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x63, 0x6c, 0x61, ++ 0x69, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, ++ 0x32, 0x36, 0x30, 0x34, 0x31, 0x36, 0x31, 0x31, 0x33, 0x38, 0x35, ++ 0x35, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x34, 0x31, 0x33, 0x31, ++ 0x31, 0x33, 0x38, 0x35, 0x35, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, ++ 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x63, 0x6c, 0x61, ++ 0x69, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x82, 0x01, 0x22, ++ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, ++ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, ++ 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xba, 0x49, 0x8c, 0xb5, ++ 0x17, 0xc1, 0x01, 0x24, 0x6f, 0x56, 0x1a, 0xa9, 0x3b, 0x03, 0xe2, ++ 0x9f, 0x24, 0xb1, 0x25, 0x98, 0xfb, 0x38, 0x82, 0x78, 0x54, 0xa7, ++ 0x1f, 0x69, 0x87, 0xe4, 0x96, 0x1b, 0x81, 0x18, 0x10, 0xb0, 0xc0, ++ 0x5b, 0x4b, 0xbf, 0xb8, 0x1d, 0xf4, 0xee, 0x75, 0x0f, 0xb5, 0x45, ++ 0x72, 0x70, 0xce, 0x65, 0x84, 0x44, 0x3e, 0x30, 0x78, 0xc4, 0xf3, ++ 0xec, 0xba, 0x96, 0x78, 0xa4, 0x65, 0xfc, 0x62, 0x8d, 0xf5, 0x29, ++ 0xf9, 0x7c, 0x3d, 0x78, 0x6c, 0x1d, 0x4a, 0x4c, 0xc9, 0x15, 0x2d, ++ 0x22, 0x10, 0xea, 0x93, 0x26, 0xb8, 0xa6, 0x17, 0xd3, 0x0e, 0xbc, ++ 0x0c, 0xab, 0x83, 0x63, 0xf6, 0x1c, 0xcc, 0x83, 0x73, 0x29, 0x7e, ++ 0x7f, 0x83, 0x7f, 0xbd, 0x63, 0xaa, 0x8d, 0xfa, 0x78, 0x85, 0xd2, ++ 0x3e, 0x60, 0x95, 0x5a, 0x8d, 0xfa, 0x8f, 0xcd, 0x94, 0x3f, 0x13, ++ 0x28, 0xd9, 0xd0, 0x87, 0x28, 0x17, 0x78, 0xe2, 0x61, 0x8d, 0x79, ++ 0x97, 0x01, 0xa9, 0x7c, 0x84, 0xc0, 0x1c, 0xbe, 0x5f, 0x5d, 0xca, ++ 0x28, 0x6b, 0x5e, 0xdd, 0x83, 0xa5, 0x55, 0x34, 0x11, 0xba, 0xfa, ++ 0x8b, 0x92, 0xa3, 0xde, 0xb6, 0xf3, 0xba, 0xab, 0x7f, 0x1a, 0x67, ++ 0xfd, 0x6f, 0x20, 0x85, 0x4c, 0x77, 0xa7, 0x8e, 0xbe, 0xb8, 0xf8, ++ 0x8f, 0x70, 0xe3, 0x5a, 0xd3, 0x77, 0xc9, 0x9e, 0x10, 0x60, 0xb4, ++ 0xdb, 0x0c, 0xc5, 0x05, 0xe1, 0x1f, 0xbd, 0xe6, 0x79, 0xee, 0x82, ++ 0x3f, 0x51, 0x76, 0xe2, 0x7f, 0x5c, 0x11, 0x6d, 0xd3, 0x21, 0x69, ++ 0xec, 0x05, 0x11, 0x8b, 0xc8, 0x39, 0xb3, 0x2c, 0xa6, 0x83, 0xb4, ++ 0x6f, 0xac, 0x19, 0xd6, 0x6a, 0x65, 0x0d, 0x08, 0x94, 0x58, 0xde, ++ 0x3d, 0xc9, 0x0c, 0x54, 0x03, 0x73, 0x0c, 0x8d, 0x24, 0x09, 0xf3, ++ 0xb1, 0x5d, 0xd2, 0xe3, 0xeb, 0x56, 0xd6, 0x28, 0x66, 0x5b, 0x02, ++ 0x03, 0x01, 0x00, 0x01, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x0f, 0x06, ++ 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, ++ 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, ++ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, ++ 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x52, 0x97, 0x58, ++ 0x47, 0x98, 0xca, 0xf8, 0x99, 0xa0, 0x7e, 0x8e, 0x1c, 0x38, 0x2e, ++ 0xea, 0xbb, 0xea, 0x9b, 0x74, 0x30, 0x30, 0x1f, 0x06, 0x03, 0x55, ++ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x52, 0x97, 0x58, ++ 0x47, 0x98, 0xca, 0xf8, 0x99, 0xa0, 0x7e, 0x8e, 0x1c, 0x38, 0x2e, ++ 0xea, 0xbb, 0xea, 0x9b, 0x74, 0x30, 0x30, 0x0d, 0x06, 0x09, 0x2a, ++ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, ++ 0x82, 0x01, 0x01, 0x00, 0x7d, 0x30, 0xd4, 0x6a, 0x01, 0x89, 0x3b, ++ 0x62, 0xed, 0x16, 0x46, 0x59, 0x0f, 0xf2, 0x3b, 0xb5, 0xde, 0x89, ++ 0x08, 0x17, 0x68, 0xcb, 0x46, 0xdc, 0x39, 0xa6, 0xcb, 0x56, 0xb0, ++ 0x91, 0xeb, 0x03, 0xb2, 0x15, 0xc4, 0x3b, 0x4d, 0x63, 0x55, 0x22, ++ 0x0a, 0x26, 0xe6, 0x64, 0x46, 0xe8, 0x0f, 0xa8, 0xf3, 0xde, 0xe1, ++ 0x43, 0x54, 0xe6, 0xd7, 0x8a, 0xf4, 0x4f, 0xab, 0x56, 0x93, 0x12, ++ 0x71, 0x4b, 0x25, 0x71, 0x0a, 0x31, 0x18, 0x79, 0xee, 0x45, 0xa4, ++ 0xf5, 0x72, 0x67, 0xfa, 0x41, 0xd9, 0x87, 0x97, 0x09, 0xef, 0x55, ++ 0xad, 0x6f, 0x47, 0x1d, 0x5a, 0xb2, 0xe9, 0xf7, 0x22, 0x05, 0x2d, ++ 0x5a, 0x81, 0xa8, 0xe8, 0x53, 0xb0, 0x94, 0xf6, 0x63, 0xff, 0x3f, ++ 0x51, 0x7a, 0x08, 0xac, 0x27, 0x9a, 0x57, 0x11, 0x22, 0xa4, 0x00, ++ 0x84, 0x70, 0x86, 0x76, 0x39, 0x0f, 0x4f, 0x57, 0xcf, 0x8e, 0x94, ++ 0xd2, 0x8e, 0x43, 0xc0, 0xd5, 0x34, 0x7d, 0xf5, 0xa1, 0x45, 0x1e, ++ 0xb7, 0xc8, 0x7e, 0x7c, 0xfe, 0x5d, 0x4d, 0x53, 0x43, 0x25, 0x15, ++ 0x9e, 0x08, 0x01, 0x56, 0xa4, 0xff, 0x79, 0x59, 0x25, 0xc9, 0x23, ++ 0x98, 0xaf, 0x05, 0xaf, 0xc1, 0x0b, 0x29, 0xf1, 0xe2, 0xc4, 0x36, ++ 0x31, 0x91, 0xfa, 0xf2, 0xbb, 0x12, 0xe8, 0x67, 0xf9, 0xc7, 0xa1, ++ 0x5e, 0x8c, 0xed, 0x92, 0x12, 0xa3, 0x2b, 0xe1, 0xc2, 0xe1, 0xa0, ++ 0xb0, 0x0e, 0x12, 0xa7, 0xd0, 0xa2, 0xae, 0xd6, 0xfa, 0x30, 0x21, ++ 0x0f, 0x73, 0xfe, 0x24, 0x21, 0x5f, 0x03, 0x86, 0x69, 0xcd, 0xec, ++ 0x76, 0x18, 0xe1, 0xfd, 0xb6, 0x64, 0x90, 0xa6, 0x06, 0x2e, 0x19, ++ 0x40, 0x93, 0x50, 0x37, 0xe4, 0x90, 0xe3, 0x1f, 0x07, 0xae, 0xfb, ++ 0x89, 0xc3, 0xf6, 0xc4, 0x90, 0xab, 0x40, 0x67, 0x4c, 0x43, 0x2c, ++ 0xa2, 0xb0, 0x3e, 0x61, 0x16, 0x69, 0x8f ++ }; ++ ++ /* CRL with critical obsolete extension OID 2.5.29.1, 422 bytes DER. ++ * OID 2.5.29.1 is the old X.509v2 Authority Key Identifier, permanently ++ * superseded by 2.5.29.35. No implementation will ever support it. */ ++ static const unsigned char crl_obsolete_critical[] = { ++ 0x30, 0x82, 0x01, 0xa6, 0x30, 0x81, 0x8f, 0x02, 0x01, 0x01, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, ++ 0x0b, 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, ++ 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2d, ++ 0x72, 0x6f, 0x6f, 0x74, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x34, 0x31, ++ 0x36, 0x31, 0x35, 0x32, 0x31, 0x30, 0x37, 0x5a, 0x17, 0x0d, 0x33, ++ 0x36, 0x30, 0x34, 0x31, 0x33, 0x31, 0x35, 0x32, 0x31, 0x30, 0x37, ++ 0x5a, 0xa0, 0x46, 0x30, 0x44, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, ++ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x52, 0x97, 0x58, 0x47, ++ 0x98, 0xca, 0xf8, 0x99, 0xa0, 0x7e, 0x8e, 0x1c, 0x38, 0x2e, 0xea, ++ 0xbb, 0xea, 0x9b, 0x74, 0x30, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d, ++ 0x01, 0x01, 0x01, 0xff, 0x04, 0x0a, 0x0c, 0x08, 0x6f, 0x62, 0x73, ++ 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, ++ 0x14, 0x04, 0x04, 0x02, 0x02, 0x20, 0x02, 0x30, 0x0d, 0x06, 0x09, ++ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, ++ 0x03, 0x82, 0x01, 0x01, 0x00, 0x05, 0xf3, 0x8f, 0xdb, 0x7f, 0x75, ++ 0x2c, 0x34, 0x4b, 0x7e, 0x70, 0x17, 0x5e, 0x34, 0xc6, 0xdb, 0xcb, ++ 0x54, 0x33, 0x06, 0x58, 0x6d, 0xae, 0x9c, 0xc8, 0xe3, 0xaf, 0x82, ++ 0xe5, 0xf6, 0x86, 0x42, 0xb3, 0x01, 0x72, 0x1a, 0xca, 0xf9, 0x10, ++ 0x5d, 0x14, 0xe6, 0x84, 0x34, 0x56, 0x55, 0x74, 0xb5, 0x06, 0x64, ++ 0x49, 0x1d, 0xb3, 0xb0, 0x13, 0xff, 0x1c, 0x05, 0x4f, 0x43, 0x29, ++ 0xbc, 0xfe, 0xb5, 0x92, 0x54, 0xf6, 0x9b, 0x81, 0x07, 0x5e, 0x2e, ++ 0x75, 0xd8, 0xfd, 0x9b, 0x5b, 0xc9, 0xd3, 0xc2, 0x15, 0xa7, 0x6e, ++ 0x2f, 0x4b, 0x3a, 0x27, 0x57, 0xef, 0x40, 0x61, 0x8c, 0x11, 0x9d, ++ 0x0a, 0xb1, 0x2b, 0x0e, 0xed, 0x5d, 0xf2, 0xf5, 0x1a, 0xce, 0xdc, ++ 0xd7, 0x75, 0xc6, 0x25, 0x22, 0xe4, 0x70, 0xad, 0x93, 0xff, 0x36, ++ 0xa1, 0xa2, 0xa0, 0xd9, 0x82, 0x23, 0x6e, 0xc8, 0x3a, 0x80, 0x82, ++ 0xbf, 0x12, 0xac, 0xa1, 0xf9, 0x03, 0x9c, 0xb9, 0x20, 0x91, 0x33, ++ 0x80, 0x7b, 0xb7, 0x6e, 0xa5, 0x32, 0x98, 0xd6, 0x2c, 0x5d, 0x9d, ++ 0x3b, 0x64, 0x3b, 0xb4, 0xea, 0x03, 0x2d, 0x65, 0xcf, 0x7f, 0x0f, ++ 0x97, 0xef, 0x5b, 0x17, 0x8c, 0xcf, 0x98, 0x69, 0xba, 0x2d, 0x62, ++ 0xe9, 0x40, 0xe2, 0x3d, 0xbd, 0xd2, 0x0f, 0x4a, 0xf8, 0xb0, 0xa7, ++ 0xdb, 0x80, 0xa3, 0x47, 0x56, 0xe5, 0xe6, 0x6f, 0x93, 0x5c, 0x6f, ++ 0xdd, 0x62, 0x43, 0x28, 0x5c, 0xe5, 0x8f, 0x0e, 0x11, 0xa6, 0x1f, ++ 0x61, 0xaf, 0x39, 0x15, 0x40, 0xf4, 0x6e, 0x79, 0x40, 0xf6, 0x28, ++ 0xf3, 0xd4, 0x30, 0x3b, 0x25, 0xb6, 0xf0, 0x4a, 0x51, 0xc3, 0x18, ++ 0xff, 0xad, 0x4d, 0x6e, 0x10, 0x73, 0x68, 0xfa, 0x54, 0x9e, 0xdc, ++ 0x34, 0x70, 0xe4, 0x5d, 0x9e, 0x7c, 0xfa, 0x59, 0x97, 0xde, 0x35, ++ 0x17, 0xbb, 0xaf, 0xa0, 0x28, 0x78, 0x13, 0xbf ++ }; ++ ++ WOLFSSL_CERT_MANAGER* cm = NULL; ++ ++ ExpectNotNull(cm = wolfSSL_CertManagerNew()); ++ ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, ca_cert, ++ sizeof(ca_cert), WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECKALL), ++ WOLFSSL_SUCCESS); ++ ++ ExpectIntNE(wolfSSL_CertManagerLoadCRLBuffer(cm, crl_obsolete_critical, ++ sizeof(crl_obsolete_critical), WOLFSSL_FILETYPE_ASN1), ++ WOLFSSL_SUCCESS); ++ ++ wolfSSL_CertManagerFree(cm); ++#endif ++ return EXPECT_RESULT(); ++} ++ + int test_wolfSSL_CertManagerCheckOCSPResponse(void) + { + EXPECT_DECLS; +diff --git a/tests/api/test_certman.h b/tests/api/test_certman.h +index a0b5d9548..3b6afd0fc 100644 +--- a/tests/api/test_certman.h ++++ b/tests/api/test_certman.h +@@ -39,6 +39,8 @@ int test_wolfSSL_CertManagerCRL(void); + int test_wolfSSL_CRL_reason_extensions_cleanup(void); + int test_wolfSSL_CRL_static_revoked_list(void); + int test_wolfSSL_CRL_duplicate_extensions(void); ++int test_wolfSSL_CRL_critical_idp(void); ++int test_wolfSSL_CRL_unknown_critical_ext(void); + int test_wolfSSL_CertManagerCheckOCSPResponse(void); + int test_various_pathlen_chains(void); + int test_wolfSSL_CertManagerRejectMD5Cert(void); +@@ -59,6 +61,8 @@ int test_wolfSSL_CertManagerRejectMD5Cert(void); + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_reason_extensions_cleanup), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_static_revoked_list), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_duplicate_extensions), \ ++ TEST_DECL_GROUP("certman", test_wolfSSL_CRL_critical_idp), \ ++ TEST_DECL_GROUP("certman", test_wolfSSL_CRL_unknown_critical_ext), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerCheckOCSPResponse), \ + TEST_DECL_GROUP("certman", test_various_pathlen_chains), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerRejectMD5Cert) +diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c +index 8d4f40a70..f8db5c457 100644 +--- a/wolfcrypt/src/asn.c ++++ b/wolfcrypt/src/asn.c +@@ -34497,14 +34497,17 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx, + mp_free(m); + FREE_MP_INT_SIZE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } ++ else if (critical) { ++ WOLFSSL_MSG("Unknown critical CRL extension"); ++ ret = ASN_CRIT_EXT_E; ++ } + } +- /* TODO: check criticality */ + /* Move index on to next extension. */ + idx += (word32)length; + } + } + +- if (ret < 0) { ++ if (ret < 0 && ret != WC_NO_ERR_TRACE(ASN_CRIT_EXT_E)) { + ret = ASN_PARSE_E; + } + +diff --git a/wolfcrypt/src/asn_orig.c b/wolfcrypt/src/asn_orig.c +index 9ecb821d3..d6568aa5d 100644 +--- a/wolfcrypt/src/asn_orig.c ++++ b/wolfcrypt/src/asn_orig.c +@@ -9327,6 +9327,7 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, + while (idx < (word32)ext_bound) { + word32 localIdx; + int ret; ++ int critical = 0; + + if (GetSequence(buf, &idx, &length, sz) < 0) { + WOLFSSL_MSG("\tfail: should be a SEQUENCE"); +@@ -9346,11 +9347,13 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, + } + + localIdx = idx; +- if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) { ++ if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && ++ tag == ASN_BOOLEAN) { + WOLFSSL_MSG("\tfound optional critical flag, moving past"); + ret = GetBoolean(buf, &idx, sz); + if (ret < 0) + return ret; ++ critical = ret; + } + + ret = GetOctetString(buf, &idx, &length, sz); +@@ -9428,6 +9431,10 @@ static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, + } + } + } ++ else if (critical) { ++ WOLFSSL_MSG("Unknown critical CRL extension"); ++ return ASN_CRIT_EXT_E; ++ } + + idx += length; + } diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6450-2.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6450-2.patch new file mode 100644 index 0000000000..0118a8d1ab --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6450-2.patch @@ -0,0 +1,404 @@ +From 501762b4913f744f42605f8cdb3e3ac6dd37916e Mon Sep 17 00:00:00 2001 +From: Reda Chouk +Date: Tue, 21 Apr 2026 16:53:59 +0200 +Subject: [PATCH] reject crls with unrecognized critical entry extensions per + rfc 5280 section 5.3 + +(cherry picked from commit 6111c60ea69fa02e1a74cf432c20bd6b789eae67) + +CVE: CVE-2026-6450 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/6111c60ea69fa02e1a74cf432c20bd6b789eae67] + +Signed-off-by: Ankur Tyagi +--- + certs/crl/extra-crls/claim-root.pem | 19 +++ + certs/crl/extra-crls/crl_critical_entry.pem | 11 ++ + certs/crl/include.am | 4 +- + tests/api/test_certman.c | 25 ++++ + tests/api/test_certman.h | 2 + + wolfcrypt/src/asn.c | 133 +++++++++++++------- + wolfcrypt/src/asn_orig.c | 28 ++++- + 7 files changed, 171 insertions(+), 51 deletions(-) + create mode 100644 certs/crl/extra-crls/claim-root.pem + create mode 100644 certs/crl/extra-crls/crl_critical_entry.pem + +diff --git a/certs/crl/extra-crls/claim-root.pem b/certs/crl/extra-crls/claim-root.pem +new file mode 100644 +index 000000000..a212501aa +--- /dev/null ++++ b/certs/crl/extra-crls/claim-root.pem +@@ -0,0 +1,19 @@ ++-----BEGIN CERTIFICATE----- ++MIIDGzCCAgOgAwIBAgIUHiXBXW8CIaDwFBWcO00dcxYA5FEwDQYJKoZIhvcNAQEL ++BQAwFTETMBEGA1UEAwwKY2xhaW0tcm9vdDAeFw0yNjA0MTYxMTM4NTVaFw0zNjA0 ++MTMxMTM4NTVaMBUxEzARBgNVBAMMCmNsYWltLXJvb3QwggEiMA0GCSqGSIb3DQEB ++AQUAA4IBDwAwggEKAoIBAQC6SYy1F8EBJG9WGqk7A+KfJLElmPs4gnhUpx9ph+SW ++G4EYELDAW0u/uB307nUPtUVycM5lhEQ+MHjE8+y6lnikZfxijfUp+Xw9eGwdSkzJ ++FS0iEOqTJrimF9MOvAyrg2P2HMyDcyl+f4N/vWOqjfp4hdI+YJVajfqPzZQ/EyjZ ++0IcoF3jiYY15lwGpfITAHL5fXcooa17dg6VVNBG6+ouSo96287qrfxpn/W8ghUx3 ++p46+uPiPcONa03fJnhBgtNsMxQXhH73mee6CP1F24n9cEW3TIWnsBRGLyDmzLKaD ++tG+sGdZqZQ0IlFjePckMVANzDI0kCfOxXdLj61bWKGZbAgMBAAGjYzBhMA8GA1Ud ++EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRSl1hHmMr4maB+ ++jhw4Luq76pt0MDAfBgNVHSMEGDAWgBRSl1hHmMr4maB+jhw4Luq76pt0MDANBgkq ++hkiG9w0BAQsFAAOCAQEAfTDUagGJO2LtFkZZD/I7td6JCBdoy0bcOabLVrCR6wOy ++FcQ7TWNVIgom5mRG6A+o897hQ1Tm14r0T6tWkxJxSyVxCjEYee5FpPVyZ/pB2YeX ++Ce9VrW9HHVqy6fciBS1agajoU7CU9mP/P1F6CKwnmlcRIqQAhHCGdjkPT1fPjpTS ++jkPA1TR99aFFHrfIfnz+XU1TQyUVnggBVqT/eVklySOYrwWvwQsp8eLENjGR+vK7 ++Euhn+cehXoztkhKjK+HC4aCwDhKn0KKu1vowIQ9z/iQhXwOGac3sdhjh/bZkkKYG ++LhlAk1A35JDjHweu+4nD9sSQq0BnTEMsorA+YRZpjw== ++-----END CERTIFICATE----- +diff --git a/certs/crl/extra-crls/crl_critical_entry.pem b/certs/crl/extra-crls/crl_critical_entry.pem +new file mode 100644 +index 000000000..11d9d31ab +--- /dev/null ++++ b/certs/crl/extra-crls/crl_critical_entry.pem +@@ -0,0 +1,11 @@ ++-----BEGIN X509 CRL----- ++MIIBjDB2AgEBMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNVBAMMCmNsYWltLXJvb3QX ++DTI2MDQyMTEyMzM0OFoXDTM2MDQxODEyMzM0OFowLTArAgIQABcNMjYwNDIxMTIz ++MzQ4WjAWMBQGA1UdAQEB/wQKDAhvYnNvbGV0ZTANBgkqhkiG9w0BAQsFAAOCAQEA ++PPG5bodrM2jK+6KcqRh9vEkWhLyxCkJij1om7R8BMO5bpvxZFOSqdN9GvIqYANYT ++ZNQzZZOer9DSXc1I9Cha179dyGnBsX33geSdhF99JxA/kZUVynfOn56El7iywkPQ ++yEpuY7uQQRfcp7D7tGz8S7mNhOMAeaN+jR2Psmn8q1Yc3W01vwYZos3qjHG1xDZ6 ++97QVFX6tbnbeu/hBsF87oiAyCbXnhRQOvrVsKqjrZXGkfRKfJ1deHc1vWgio7fhr ++A1/Hb4sdfTWZUwtduTRI9Vyaw1IL41d+0ExdzTshIHbddB/dyByrRqlIzJdeiigt ++d1Gcf1EYSoWiV8Xaj9SFng== ++-----END X509 CRL----- +diff --git a/certs/crl/include.am b/certs/crl/include.am +index 46d0ed3e7..a0c526d91 100644 +--- a/certs/crl/include.am ++++ b/certs/crl/include.am +@@ -27,7 +27,9 @@ EXTRA_DIST += \ + certs/crl/extra-crls/large_crlnum.pem \ + certs/crl/extra-crls/large_crlnum2.pem \ + certs/crl/extra-crls/crlnum_57oct.pem \ +- certs/crl/extra-crls/crlnum_64oct.pem ++ certs/crl/extra-crls/crlnum_64oct.pem \ ++ certs/crl/extra-crls/claim-root.pem \ ++ certs/crl/extra-crls/crl_critical_entry.pem + + # Intermediate cert CRL's + EXTRA_DIST += \ +diff --git a/tests/api/test_certman.c b/tests/api/test_certman.c +index 7405f4bff..d9000c7cf 100644 +--- a/tests/api/test_certman.c ++++ b/tests/api/test_certman.c +@@ -2306,6 +2306,31 @@ int test_wolfSSL_CRL_unknown_critical_ext(void) + return EXPECT_RESULT(); + } + ++int test_wolfSSL_CRL_unknown_critical_entry_ext(void) ++{ ++ EXPECT_DECLS; ++#if !defined(NO_CERTS) && defined(HAVE_CRL) && !defined(NO_RSA) && \ ++ !defined(NO_FILESYSTEM) ++ WOLFSSL_CERT_MANAGER* cm = NULL; ++ ++ ExpectNotNull(cm = wolfSSL_CertManagerNew()); ++ ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, ++ "./certs/crl/extra-crls/claim-root.pem", NULL), WOLFSSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECKALL), ++ WOLFSSL_SUCCESS); ++ ++ /* CRL with a revoked entry that carries a critical unknown extension ++ * (OID 2.5.29.1, old X.509v2 AKI, permanently superseded). ++ * Per RFC 5280 Section 5.3, the CRL must not be used. */ ++ ExpectIntNE(wolfSSL_CertManagerLoadCRLFile(cm, ++ "./certs/crl/extra-crls/crl_critical_entry.pem", WOLFSSL_FILETYPE_PEM), ++ WOLFSSL_SUCCESS); ++ ++ wolfSSL_CertManagerFree(cm); ++#endif ++ return EXPECT_RESULT(); ++} ++ + int test_wolfSSL_CertManagerCheckOCSPResponse(void) + { + EXPECT_DECLS; +diff --git a/tests/api/test_certman.h b/tests/api/test_certman.h +index 3b6afd0fc..0962b0228 100644 +--- a/tests/api/test_certman.h ++++ b/tests/api/test_certman.h +@@ -41,6 +41,7 @@ int test_wolfSSL_CRL_static_revoked_list(void); + int test_wolfSSL_CRL_duplicate_extensions(void); + int test_wolfSSL_CRL_critical_idp(void); + int test_wolfSSL_CRL_unknown_critical_ext(void); ++int test_wolfSSL_CRL_unknown_critical_entry_ext(void); + int test_wolfSSL_CertManagerCheckOCSPResponse(void); + int test_various_pathlen_chains(void); + int test_wolfSSL_CertManagerRejectMD5Cert(void); +@@ -63,6 +64,7 @@ int test_wolfSSL_CertManagerRejectMD5Cert(void); + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_duplicate_extensions), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_critical_idp), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_unknown_critical_ext), \ ++ TEST_DECL_GROUP("certman", test_wolfSSL_CRL_unknown_critical_entry_ext), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerCheckOCSPResponse), \ + TEST_DECL_GROUP("certman", test_various_pathlen_chains), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerRejectMD5Cert) +diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c +index f8db5c457..1dc27cfd0 100644 +--- a/wolfcrypt/src/asn.c ++++ b/wolfcrypt/src/asn.c +@@ -34039,16 +34039,22 @@ enum { + /* CRL Reason Code OID: 2.5.29.21 */ + static const byte crlReasonOid[] = { 0x55, 0x1d, 0x15 }; + +-/* Parse CRL entry extensions to extract the reason code. +- * Sets *reasonCode if found, otherwise leaves it unchanged. */ +-static void ParseCRL_ReasonCode(const byte* buff, word32 idx, word32 maxIdx, +- int* reasonCode) ++/* Parse CRL entry extensions. ++ * Extracts the reason code into *reasonCode if the CRL Reason extension ++ * is present. Per RFC 5280 Section 5.3, returns ASN_CRIT_EXT_E if any ++ * unknown extension is marked critical. Returns 0 on success. */ ++static int ParseCRL_EntryExtensions(const byte* buff, word32 idx, word32 maxIdx, ++ int* reasonCode) + { + while (idx < maxIdx) { + int len; ++ int oidLen; + word32 end; + word32 localIdx; ++ word32 oidContent; + byte tag; ++ int critical = 0; ++ int isReasonOid = 0; + + /* Each extension is a SEQUENCE */ + if (GetSequence(buff, &idx, &len, maxIdx) < 0) { +@@ -34056,23 +34062,39 @@ static void ParseCRL_ReasonCode(const byte* buff, word32 idx, word32 maxIdx, + } + end = idx + (word32)len; + +- /* Check for CRL Reason OID: 2.5.29.21 */ +- if (end - idx >= (word32)(2 + sizeof(crlReasonOid)) && +- buff[idx] == ASN_OBJECT_ID && +- buff[idx + 1] == sizeof(crlReasonOid) && +- XMEMCMP(buff + idx + 2, crlReasonOid, ++ /* Parse OID: tag, length (short or long form), content */ ++ if (GetASNTag(buff, &idx, &tag, end) < 0 || ++ tag != ASN_OBJECT_ID) { ++ break; ++ } ++ if (GetLength(buff, &idx, &oidLen, end) < 0) { ++ break; ++ } ++ oidContent = idx; ++ if (idx + (word32)oidLen > end) { ++ break; ++ } ++ ++ /* Check if it's the CRL Reason OID: 2.5.29.21 */ ++ if ((word32)oidLen == sizeof(crlReasonOid) && ++ XMEMCMP(buff + oidContent, crlReasonOid, + sizeof(crlReasonOid)) == 0) { +- /* Skip past the OID */ +- idx += 2 + (word32)sizeof(crlReasonOid); +- /* Skip optional critical BOOLEAN */ +- localIdx = idx; +- if (GetASNTag(buff, &localIdx, &tag, end) == 0 && +- tag == ASN_BOOLEAN) { +- /* Consume full BOOLEAN TLV (tag + length + value). */ +- if (GetBoolean(buff, &idx, end) < 0) { +- break; +- } ++ isReasonOid = 1; ++ } ++ idx = oidContent + (word32)oidLen; ++ ++ /* Parse optional critical BOOLEAN */ ++ localIdx = idx; ++ if (GetASNTag(buff, &localIdx, &tag, end) == 0 && ++ tag == ASN_BOOLEAN) { ++ int ret = GetBoolean(buff, &idx, end); ++ if (ret < 0) { ++ break; + } ++ critical = ret; ++ } ++ ++ if (isReasonOid) { + /* Get OCTET STRING wrapping the ENUMERATED */ + if (GetOctetString(buff, &idx, &len, end) >= 0) { + /* Parse ENUMERATED reason value */ +@@ -34088,8 +34110,15 @@ static void ParseCRL_ReasonCode(const byte* buff, word32 idx, word32 maxIdx, + } + } + } ++ else if (critical) { ++ /* RFC 5280 Section 5.3: reject CRL with unknown critical ++ * entry extension. */ ++ WOLFSSL_MSG("Unknown critical CRL entry extension"); ++ return ASN_CRIT_EXT_E; ++ } + idx = end; + } ++ return 0; + } + + #ifdef HAVE_CRL +@@ -34102,8 +34131,7 @@ WOLFSSL_TEST_VIS int wc_ParseCRLReasonFromExtensions(const byte* ext, + return BAD_FUNC_ARG; + } + +- ParseCRL_ReasonCode(ext, 0, extSz, reasonCode); +- return 0; ++ return ParseCRL_EntryExtensions(ext, 0, extSz, reasonCode); + } + #endif + +@@ -34166,49 +34194,58 @@ static int GetRevoked(RevokedCert* rcert, const byte* buff, word32* idx, + /* Parse CRL entry extensions (v2 only) */ + if (dataASN[REVOKEDASN_IDX_TIME_EXT].length > 0) { + word32 extOff = dataASN[REVOKEDASN_IDX_TIME_EXT].offset; +- word32 extLen = dataASN[REVOKEDASN_IDX_TIME_EXT].length; +- word32 extEnd = extOff + extLen; +- word32 extIdx2 = extOff; ++ word32 extTagEnd = extOff + ++ dataASN[REVOKEDASN_IDX_TIME_EXT].length + 6; ++ int extLen; ++ ++ /* .offset points at the outer SEQUENCE tag. Re-parse the ++ * SEQUENCE header to locate the content start (list of ++ * Extension SEQUENCEs), which handles long-form length. ++ * extTagEnd adds 6 to cover the worst-case tag+long-form-length ++ * header for the outer SEQUENCE. */ ++ if (GetSequence(buff, &extOff, &extLen, extTagEnd) < 0) { ++ ret = ASN_PARSE_E; ++ } ++ else { ++ word32 extEnd = extOff + (word32)extLen; + + #if defined(OPENSSL_EXTRA) +- /* Store raw DER of extensions for OpenSSL compat API. +- * Include the outer SEQUENCE tag+length. */ +- { +- /* Back up to include the SEQUENCE header. We know the +- * content starts at extOff, so the header is just before. +- * Use the raw buffer start from before GetASN_Items. */ +- word32 seqHdrSz = 0; +- /* The outer SEQUENCE header is at most 4 bytes before +- * content. Rather than guess, store just the content. */ +- rc->extensions = (byte*)XMALLOC(extLen, dcrl->heap, ++ /* Store raw DER of extension contents for OpenSSL compat. */ ++ rc->extensions = (byte*)XMALLOC((size_t)extLen, dcrl->heap, + DYNAMIC_TYPE_REVOKED); + if (rc->extensions != NULL) { +- XMEMCPY(rc->extensions, buff + extOff, extLen); +- rc->extensionsSz = extLen; ++ XMEMCPY(rc->extensions, buff + extOff, (size_t)extLen); ++ rc->extensionsSz = (word32)extLen; + } +- (void)seqHdrSz; +- } + #endif + +- ParseCRL_ReasonCode(buff, extIdx2, extEnd, &rc->reasonCode); ++ ret = ParseCRL_EntryExtensions(buff, extOff, extEnd, ++ &rc->reasonCode); ++ } + } + +- /* Add revoked certificate to chain. */ ++ if (ret == 0) { ++ /* Add revoked certificate to chain. */ + #ifndef CRL_STATIC_REVOKED_LIST +- rc->next = dcrl->certs; +- dcrl->certs = rc; ++ rc->next = dcrl->certs; ++ dcrl->certs = rc; + #endif +- dcrl->totalCerts++; ++ dcrl->totalCerts++; ++ } + } + + FREE_ASNGETDATA(dataASN, dcrl->heap); +-#ifndef CRL_STATIC_REVOKED_LIST + if ((ret != 0) && (rc != NULL)) { + #if defined(OPENSSL_EXTRA) + XFREE(rc->extensions, dcrl->heap, DYNAMIC_TYPE_REVOKED); ++ rc->extensions = NULL; ++ rc->extensionsSz = 0; + #endif ++#ifndef CRL_STATIC_REVOKED_LIST + XFREE(rc, dcrl->heap, DYNAMIC_TYPE_CRL); ++#endif + } ++#ifndef CRL_STATIC_REVOKED_LIST + (void)rcert; + #endif + return ret; +@@ -34232,7 +34269,13 @@ static int ParseCRL_RevokedCerts(RevokedCert* rcert, DecodedCRL* dcrl, + /* Parse each revoked certificate. */ + while ((ret == 0) && (idx < maxIdx)) { + /* Parse a revoked certificate. */ +- if (GetRevoked(rcert, buff, &idx, dcrl, maxIdx) < 0) { ++ int r = GetRevoked(rcert, buff, &idx, dcrl, maxIdx); ++ if (r == WC_NO_ERR_TRACE(ASN_CRIT_EXT_E)) { ++ /* Preserve the specific error so callers can distinguish a ++ * rejected critical extension from a generic parse failure. */ ++ ret = r; ++ } ++ else if (r < 0) { + ret = ASN_PARSE_E; + } + } +diff --git a/wolfcrypt/src/asn_orig.c b/wolfcrypt/src/asn_orig.c +index d6568aa5d..bb58eb6d4 100644 +--- a/wolfcrypt/src/asn_orig.c ++++ b/wolfcrypt/src/asn_orig.c +@@ -9061,18 +9061,17 @@ static int GetRevoked(RevokedCert* rcert, const byte* buff, word32* idx, + XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED); + return ret; + } +- /* add to list */ +- rc->next = dcrl->certs; +- dcrl->certs = rc; + + (void)rcert; + #endif /* CRL_STATIC_REVOKED_LIST */ +- dcrl->totalCerts++; + /* get date */ + #ifndef NO_ASN_TIME + ret = GetBasicDate(buff, idx, rc->revDate, &rc->revDateFormat, maxIdx); + if (ret < 0) { + WOLFSSL_MSG("Expecting Date"); ++#ifndef CRL_STATIC_REVOKED_LIST ++ XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED); ++#endif + return ret; + } + #endif +@@ -9106,11 +9105,30 @@ static int GetRevoked(RevokedCert* rcert, const byte* buff, word32* idx, + } + #endif + +- ParseCRL_ReasonCode(buff, seqIdx, extEnd, &rc->reasonCode); ++ ret = ParseCRL_EntryExtensions(buff, seqIdx, extEnd, ++ &rc->reasonCode); ++ if (ret != 0) { ++#if defined(OPENSSL_EXTRA) ++ XFREE(rc->extensions, dcrl->heap, DYNAMIC_TYPE_REVOKED); ++ rc->extensions = NULL; ++ rc->extensionsSz = 0; ++#endif ++#ifndef CRL_STATIC_REVOKED_LIST ++ XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED); ++#endif ++ return ret; ++ } + } + } + } + ++#ifndef CRL_STATIC_REVOKED_LIST ++ /* add to list only after all parsing succeeded */ ++ rc->next = dcrl->certs; ++ dcrl->certs = rc; ++#endif ++ dcrl->totalCerts++; ++ + *idx = end; + + return 0; diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 4ca330b029..26b86c1b2b 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -32,6 +32,8 @@ SRC_URI = " \ file://CVE-2026-6325.patch \ file://CVE-2026-6412-1.patch \ file://CVE-2026-6412-2.patch \ + file://CVE-2026-6450-1.patch \ + file://CVE-2026-6450-2.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:16 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97499 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 2062BC79FA7 for ; Mon, 7 Sep 2026 10:25:00 +0000 (UTC) Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.31938.1788776699779099777 for ; Mon, 07 Sep 2026 03:24:59 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=bk1H++wW; spf=pass (domain: gmail.com, ip: 209.85.214.179, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-2d5335cf904so32744275ad.2 for ; Mon, 07 Sep 2026 03:24:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776699; x=1789381499; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=E8oUiDUqX1XiMgv3N4W8AISM0vVaqVQQhClNJN+j2S4=; b=bk1H++wWfuh6lGxbbxtlrwS0RTW66HX9yu2GQxDcMIeXSKBEPUMVn6BMh8Ev0OtD8d HNe2jPrZNi48lzmLMmGiLNGw0NFnmze/EZ4grg///J+H9CdIxOIREjB9tz2mD0yckNj4 gSCwVQ5zKYQ++TUnXY6rtcwC06WfVQfqiKCj1e17UDOS4MgZxMu2utP43+P3XAe/TnEW TFtG4Eooy8+dvDWIu6zDkCoacrmM/2cAxRDrW9uyu0hvdKatociYNBF9VYCGnfm7HBLY HpqUyzQi53q+XDtsgSYOA77OSVK3ehNfbr1ODMUtBu4uugsH07hmywn3PDMgA1FINQiZ wM7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776699; x=1789381499; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=E8oUiDUqX1XiMgv3N4W8AISM0vVaqVQQhClNJN+j2S4=; b=OARrgzCz51PE8eFC0IuAYVtXb/owblpsIHYZpSI6F354p+dfwDXv5ZHNYe+B7Lq6D4 SeIFROBvy9L/538p9+z1lENj3bxOjiSpYpy6ZST9Ybc7Js5pjBwFC4a0B+GSCYoq6piZ acDAKkBg6DNMP22QlrNdkXS4Yq3TlJItJHzsfM82DLC8yQURuNU1Y5Kr5/L02TlD342S y0oPt0I27YKSKAT48C4qAS6BDPUzH4pTB24yAP6jlh+X6uMLjIQHyECjM5uAusJI16ZQ LXPOekoMuus2DZY16GgT5VThiOGm5BTh3GoV+IfXrl7zIKQ32P2vT81upeQB1bdlCdY5 IzoA== X-Gm-Message-State: AFuF++kNoKLyiWy83bSJCQ17j9f+mwqEh9YHm6XyuCIkM/pOW2brA28t RRcmzaXDmCzrer9dA/PEj6+sQTPl17AlUfKwmKZK2E7gbe8/MLpaNN7Igw6oXg== X-Gm-Gg: AYBFou2z25dIFZj7GkOMGncdcR6jd1bOuZETcC0hO+TYsqBu12JmxYTmFd2cgSnKK54 TbGTjl6Y4mVuoi7rIwAf/BHg2eQJiEHOAiX+lBJKzrjDrsZ7QfX1TG+DR5z7H+LWQPEZUMrM937 ooyJ/kwLaw43Yvzdd8f4CH6h0FWzyh/xOfIK9arIB2x/KZh2UWUak2waM/4P7t//uIM7E7pCMJ1 SwkRKUYjdF+IcDdDjToUQoiZkNjqRm6XB4hzhkAVUGF9lZIDRBHa5oXj7V5ZOn6gDZ0C2lnOFMF txBih4BK664g33KUBI5ky7wV4MEPDAOcM0YeXyMVAb8dOx4L89KdrAJVp548l5aKBZb5/L+43Gm ONwqliIXjZB1iEInKvoFNVAdqNskYw3gcMH3H1lF+9gpVjoRTa4u7DeqNOqNW8AQ0ivfmsafH7n BmhHrSD/gNHIKG0m8XfmN2WrG8SYL+mG3EvIHT5o7+CL7ZJNqTeMnZnSPjygghXxRBEJhG7XHH X-Received: by 2002:a17:90b:4a48:b0:381:6c5:3f63 with SMTP id 98e67ed59e1d1-39b260d2d58mr32030094a91.6.1788776699047; Mon, 07 Sep 2026 03:24:59 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:24:58 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 32/33] wolfssl: patch CVE-2026-6731 Date: Mon, 7 Sep 2026 22:23:16 +1200 Message-ID: <20260907102318.2459883-32-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:25:00 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129844 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-6731 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-6731-1.patch | 39 ++++ .../wolfssl/files/CVE-2026-6731-2.patch | 171 ++++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 2 + 3 files changed, 212 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6731-1.patch create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6731-2.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6731-1.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6731-1.patch new file mode 100644 index 0000000000..c6a1762b27 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6731-1.patch @@ -0,0 +1,39 @@ +From df2df57a027066708b498f41ce0b591704b579cc Mon Sep 17 00:00:00 2001 +From: Ruby Martin +Date: Tue, 14 Apr 2026 12:39:34 -0600 +Subject: [PATCH] Apply DNS constraints to subject CN when SAN is not + available. + +(cherry picked from commit e7b7fddacb4cc794e5dfc7693586d87a539f5aad) + +CVE: CVE-2026-6731 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/e7b7fddacb4cc794e5dfc7693586d87a539f5aad] + +Signed-off-by: Ankur Tyagi +--- + wolfcrypt/src/asn.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c +index f8db5c457..d12a78850 100644 +--- a/wolfcrypt/src/asn.c ++++ b/wolfcrypt/src/asn.c +@@ -17665,9 +17665,16 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) + XMEMSET(&subjectDnsName, 0, sizeof(DNS_entry)); + switch (nameType) { + case ASN_DNS_TYPE: +- /* Should it also consider CN in subject? It could use +- * subjectDnsName too */ + name = cert->altNames; ++ ++ /* When no SAN is present, apply DNS name constraints to the ++ * Subject CN. */ ++ if (cert->subjectCN != NULL && cert->altNames == NULL) { ++ subjectDnsName.next = NULL; ++ subjectDnsName.type = ASN_DNS_TYPE; ++ subjectDnsName.len = cert->subjectCNLen; ++ subjectDnsName.name = cert->subjectCN; ++ } + break; + case ASN_IP_TYPE: + /* IP addresses are stored in altNames with type ASN_IP_TYPE */ diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6731-2.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6731-2.patch new file mode 100644 index 0000000000..be5132048e --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-6731-2.patch @@ -0,0 +1,171 @@ +From 9d1ee979f67c8e31a04b73fadac61f4697bcb7c6 Mon Sep 17 00:00:00 2001 +From: Ruby Martin +Date: Tue, 14 Apr 2026 12:44:21 -0600 +Subject: [PATCH] test DNS name constraints on CA are applied against Subject + CN name when SAN name is unavailable + +test correct CN with no SAN available is accepted + +(cherry picked from commit 797ba3f03b1a8dc05c7b91a86c2e6698d76bfc8a) + +CVE: CVE-2026-6731 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/797ba3f03b1a8dc05c7b91a86c2e6698d76bfc8a] + +Signed-off-by: Ankur Tyagi +--- + tests/api/test_certman.c | 121 +++++++++++++++++++++++++++++++++++++++ + tests/api/test_certman.h | 2 + + 2 files changed, 123 insertions(+) + +diff --git a/tests/api/test_certman.c b/tests/api/test_certman.c +index 7405f4bff..c76902af2 100644 +--- a/tests/api/test_certman.c ++++ b/tests/api/test_certman.c +@@ -1584,6 +1584,127 @@ int test_wolfSSL_CertManagerNameConstraint5(void) + return EXPECT_RESULT(); + } + ++int test_wolfSSL_CertManagerNameConstraint_DNS_CN(void) ++{ ++ EXPECT_DECLS; ++#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ ++ !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) && \ ++ defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN) && \ ++ defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_ALT_NAMES) && \ ++ !defined(NO_SHA256) ++ /* Test that DNS name constraints are enforced against the Subject CN ++ * when no SAN extension is present. The CA cert (cert-ext-ncdns.der) ++ * permits only DNS:wolfssl.com and DNS:example.com. A leaf cert with ++ * CN=evil.attacker.com and no SAN should be REJECTED. */ ++ WOLFSSL_CERT_MANAGER* cm = NULL; ++ WOLFSSL_EVP_PKEY *priv = NULL; ++ WOLFSSL_X509_NAME* name = NULL; ++ const char* ca_cert = "./certs/test/cert-ext-ncdns.der"; ++ const char* server_cert = "./certs/test/server-goodcn.pem"; ++ ++ byte *der = NULL; ++ int derSz; ++ byte *pt; ++ WOLFSSL_X509 *x509 = NULL; ++ WOLFSSL_X509 *ca = NULL; ++ ++ pt = (byte*)server_key_der_2048; ++ ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, ++ (const unsigned char**)&pt, sizeof_server_key_der_2048)); ++ ++ ExpectNotNull(cm = wolfSSL_CertManagerNew()); ++ ExpectNotNull(ca = wolfSSL_X509_load_certificate_file(ca_cert, ++ WOLFSSL_FILETYPE_ASN1)); ++ ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(ca, &derSz))); ++ ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer(cm, der, derSz, ++ WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); ++ ++ /* Sanity check: cert with SAN=evil.attacker.com is correctly rejected */ ++ ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert, ++ WOLFSSL_FILETYPE_PEM)); ++ ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca)); ++ ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS); ++ name = NULL; ++ ++ ExpectNotNull(name = X509_NAME_new()); ++ ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8, ++ (byte*)"US", 2, -1, 0), SSL_SUCCESS); ++ ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8, ++ (byte*)"evil.attacker.com", 17, -1, 0), ++ SSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS); ++ X509_NAME_free(name); ++ name = NULL; ++ ++ ExpectIntEQ(wolfSSL_X509_add_altname(x509, "evil.attacker.com", ++ ASN_DNS_TYPE), WOLFSSL_SUCCESS); ++ ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0); ++ ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz))); ++ ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz, ++ WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E)); ++ wolfSSL_X509_free(x509); ++ x509 = NULL; ++ ++ /* NOW the actual vulnerability test: cert with CN=evil.attacker.com ++ * but NO SAN. The DNS name constraint should still reject this, since ++ * wolfSSL's hostname verification falls back to CN when no SAN exists. */ ++ ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert, ++ WOLFSSL_FILETYPE_PEM)); ++ ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca)); ++ ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS); ++ name = NULL; ++ ++ ExpectNotNull(name = X509_NAME_new()); ++ ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8, ++ (byte*)"US", 2, -1, 0), SSL_SUCCESS); ++ ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8, ++ (byte*)"evil.attacker.com", 17, -1, 0), ++ SSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS); ++ X509_NAME_free(name); ++ name = NULL; ++ ++ /* Do NOT add any SAN this is the bypass vector */ ++ ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0); ++ ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz))); ++ /* Should be ASN_NAME_INVALID_E because CN violates the constraint */ ++ ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz, ++ WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_NAME_INVALID_E)); ++ wolfSSL_X509_free(x509); ++ x509 = NULL; ++ ++ /* Positive test: CN matches a permitted name (wolfssl.com) and no SAN is ++ * present. The CN fallback should accept this cert. */ ++ ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(server_cert, ++ WOLFSSL_FILETYPE_PEM)); ++ ExpectNotNull(name = wolfSSL_X509_get_subject_name(ca)); ++ ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS); ++ name = NULL; ++ ++ ExpectNotNull(name = X509_NAME_new()); ++ ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "countryName", MBSTRING_UTF8, ++ (byte*)"US", 2, -1, 0), SSL_SUCCESS); ++ ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8, ++ (byte*)"wolfssl.com", 11, -1, 0), ++ SSL_SUCCESS); ++ ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS); ++ X509_NAME_free(name); ++ name = NULL; ++ ++ /* No SAN added; CN=wolfssl.com matches the permitted DNS constraint. */ ++ ExpectIntGT(wolfSSL_X509_sign(x509, priv, EVP_sha256()), 0); ++ ExpectNotNull((der = (byte*)wolfSSL_X509_get_der(x509, &derSz))); ++ ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, der, derSz, ++ WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); ++ ++ wolfSSL_CertManagerFree(cm); ++ wolfSSL_X509_free(x509); ++ wolfSSL_X509_free(ca); ++ wolfSSL_EVP_PKEY_free(priv); ++#endif ++ return EXPECT_RESULT(); ++} ++ + int test_wolfSSL_CertManagerCRL(void) + { + EXPECT_DECLS; +diff --git a/tests/api/test_certman.h b/tests/api/test_certman.h +index 3b6afd0fc..60047cfa3 100644 +--- a/tests/api/test_certman.h ++++ b/tests/api/test_certman.h +@@ -35,6 +35,7 @@ int test_wolfSSL_CertManagerNameConstraint2(void); + int test_wolfSSL_CertManagerNameConstraint3(void); + int test_wolfSSL_CertManagerNameConstraint4(void); + int test_wolfSSL_CertManagerNameConstraint5(void); ++int test_wolfSSL_CertManagerNameConstraint_DNS_CN(void); + int test_wolfSSL_CertManagerCRL(void); + int test_wolfSSL_CRL_reason_extensions_cleanup(void); + int test_wolfSSL_CRL_static_revoked_list(void); +@@ -57,6 +58,7 @@ int test_wolfSSL_CertManagerRejectMD5Cert(void); + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerNameConstraint3), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerNameConstraint4), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerNameConstraint5), \ ++ TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerNameConstraint_DNS_CN), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CertManagerCRL), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_reason_extensions_cleanup), \ + TEST_DECL_GROUP("certman", test_wolfSSL_CRL_static_revoked_list), \ diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index 26b86c1b2b..ef03d0c9ff 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -34,6 +34,8 @@ SRC_URI = " \ file://CVE-2026-6412-2.patch \ file://CVE-2026-6450-1.patch \ file://CVE-2026-6450-2.patch \ + file://CVE-2026-6731-1.patch \ + file://CVE-2026-6731-2.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24" From patchwork Mon Sep 7 10:23:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 97500 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 0AC11C79F89 for ; Mon, 7 Sep 2026 10:25:10 +0000 (UTC) Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.31717.1788776702547521077 for ; Mon, 07 Sep 2026 03:25:02 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=UBs273F7; spf=pass (domain: gmail.com, ip: 209.85.216.42, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-398a4dcf289so4084566a91.2 for ; Mon, 07 Sep 2026 03:25:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788776702; x=1789381502; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=PQjpUvwoLo31rSfTHVzR82OMLwW3S00z/DMi9Hi7osw=; b=UBs273F7wZzCpGn4lkKXiLwkpkLINdXaRjtIoFGGqfN5NirL4PtnPkIDbaRdsEzUUa A91iASddR+NU6qBiV2ekh/EGySzp3p1CDsv8pLTmLXwoXhSUfsJbCxLmOyNsrp4Y9OHe vL5sEJvCBPZzoamWk64Tf3kDLlJButEqIg3+3s8WLIKgYC3I/HfJsy+gCMGYSLLRn0ix WRwXV/xroCzsdXpJJsR7MmdxxeZhxGJiTW3weqt3HWa41NEU9xu963V5ckd5aQEYgWe2 R9xehMwYbk4u6HKDaxCETcw5vgETjxkFdIt8IU+kfyoQ44prje+XuZ9FEW7KjfkhoBK2 ua7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788776702; x=1789381502; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=PQjpUvwoLo31rSfTHVzR82OMLwW3S00z/DMi9Hi7osw=; b=Wlzjh6DrFTJ5WQqUe/s06owwQy5bGHpkPRvUhzb8dw/92Sa31qMrelujfRzJ342c9U bieJ+Gc1jCRt436Kb2o6+U2QhdG2/Ah9TxBXqF6sGolNS1VaefNaCnix+xWbeOV1C7h7 TBVFzZaHwb9aN1Xt43UkFFj1dvMOUM/2AyCbyR+uDvJHLaDZYbN+g0d6CHUhlWoz7zNL OpC/MM9ppH8Zsa8TWH/yRXAbySNFSJt3WU95Wvr64tcuE1s+n7PIbNe4EiUapZGyPzBJ 7tMoU6a5OiSL4lUpFVH4zbXjNYPjAQpEJMeQ/CQEHmUQbSzFpmt3FFOeTx5I4EqVlUDs Y8sQ== X-Gm-Message-State: AFuF++mHZSilo/B14Azjyl0c7JG7MQ78tNAIj/frb6rAKARE23w5i+rS b8F1MwutneunrWxamGxhyx/NH6qJVRiW9fmXUGKJNBrikUqvv0i4T1RLtvuoJz0g X-Gm-Gg: AYBFou0MzjI9Em8sfp0l5FHrEu+Qr5eqnq2XcHXNecY4qxl7nBzhPTr7svVmvCDmSNX 5/7t6C+B4oXZRgu0/taSZ+hWN0d8pDd8ibyJlYfzGPkm/xPMQK5G9v0dJF7PnfhFnK0xirI3/gj Ux9ehFrW1lI6Iuiw1CYY0Spbzdh0dvG5a0flRqH6YmCO+wznJ7wXuuHibpwz997qhWYVF0ccAYD wXp7wZRaiOtjY7fJyAUK8+biq/JSO4HFhgK8hqW+il8ZFjQ7K/62rsszF+gz88fBMA3TrswFYP2 0hs2mWTuRLIIn+u4FqsrLglvv9XpcMsxdPLkbztROeTtZn4pTfLadG7S8OH/eeEX036PPH/MF0C lg7rcumXEoOcAHIDawBIH1aESFrhzGi7ApUXI5RclZF2Rt4c/3qSECiMGwYewX4pZhOgIZkTROj q75FZFjH4AsOBB51ieTVasTLGSBJIbW7P6g8DJP795S9vYOANiICbSuHSM5bWdhQa1mj4fhJMt X-Received: by 2002:a17:90b:2687:b0:395:4290:46e0 with SMTP id 98e67ed59e1d1-39b2609f768mr37509491a91.5.1788776701877; Mon, 07 Sep 2026 03:25:01 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1432441f5f2sm30215104c88.15.2026.09.07.03.24.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Sep 2026 03:25:01 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 33/33] wolfssl: patch CVE-2026-7531 Date: Mon, 7 Sep 2026 22:23:17 +1200 Message-ID: <20260907102318.2459883-33-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> References: <20260907102318.2459883-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 10:25:10 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129845 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-7531 Signed-off-by: Ankur Tyagi --- .../wolfssl/files/CVE-2026-7531.patch | 180 ++++++++++++++++++ .../wolfssl/wolfssl_5.9.1.bb | 1 + 2 files changed, 181 insertions(+) create mode 100644 meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-7531.patch diff --git a/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-7531.patch b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-7531.patch new file mode 100644 index 0000000000..1d4e7605b3 --- /dev/null +++ b/meta-networking/recipes-connectivity/wolfssl/files/CVE-2026-7531.patch @@ -0,0 +1,180 @@ +From 5ab994ddce690cc904554ff03af263ef0624d29d Mon Sep 17 00:00:00 2001 +From: David Garske +Date: Tue, 5 May 2026 11:41:43 -0700 +Subject: [PATCH] Merge pull request #10327 from embhorn/zd21704 + +Hardening in TLSX_KeyShare_ProcessPqcHybridClient + +CVE: CVE-2026-7531 +Upstream-Status: Backport [https://github.com/wolfSSL/wolfssl/commit/3b7ac9fd256b26c33b66f9315c319465ba3bcfeb] + +Signed-off-by: Ankur Tyagi +--- + src/tls.c | 19 +++++--- + tests/api/test_tls13.c | 98 ++++++++++++++++++++++++++++++++++++++++++ + tests/api/test_tls13.h | 2 + + 3 files changed, 114 insertions(+), 5 deletions(-) + +diff --git a/src/tls.c b/src/tls.c +index 18aad71d3..e5b989482 100644 +--- a/src/tls.c ++++ b/src/tls.c +@@ -10187,15 +10187,24 @@ static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl, + ecc_kse->key = NULL; + pqc_kse->privKey = NULL; + } ++ else + #endif ++ { ++ /* Re-sync keyShareEntry->key with ecc_kse->key. ecc_kse->key was ++ * aliased to keyShareEntry->key above. The inner Process*_ex ++ * either ran its end-of-function cleanup and set ecc_kse->key ++ * to NULL (so the outer pointer must also become NULL to avoid ++ * UAF/double-free in TLSX_KeyShare_FreeAll), or returned early ++ * before cleanup with ecc_kse->key still pointing at the live ++ * key (so the outer pointer must keep that pointer for later ++ * freeing). Mirroring whatever the inner left in ecc_kse->key ++ * handles both cases correctly. */ ++ keyShareEntry->key = ecc_kse->key; ++ } + } + + if (ret == 0) { +- keyShareEntry->key = ecc_kse->key; +- ecc_kse->key = NULL; +- +- if ((ret == 0) && +- ((ssl->arrays->preMasterSz + ssSzPqc) > ENCRYPT_LEN)) { ++ if ((ssl->arrays->preMasterSz + ssSzPqc) > ENCRYPT_LEN) { + WOLFSSL_MSG("shared secret is too long."); + ret = LENGTH_ERROR; + } +diff --git a/tests/api/test_tls13.c b/tests/api/test_tls13.c +index 63ddffb7a..af050a234 100644 +--- a/tests/api/test_tls13.c ++++ b/tests/api/test_tls13.c +@@ -3581,6 +3581,104 @@ int test_tls13_pqc_hybrid_truncated_keyshare(void) + return EXPECT_RESULT(); + } + ++/* Test that a malformed ECDH portion in a correctly-sized PQC hybrid ++ * KeyShare does not leave a dangling pointer in keyShareEntry->key. ++ * ++ * The earlier truncated-keyshare test is rejected by the keLen <= ctSz ++ * check before TLSX_KeyShare_ProcessPqcHybridClient sets up the ++ * ecc_kse->key = keyShareEntry->key alias, so it does not exercise the ++ * dangling-pointer path. This test sends a SECP256R1MLKEM768 key_share ++ * whose total length is correct (65-byte ECDH point + 1088-byte ML-KEM ++ * ciphertext = 1153 bytes) but whose ECDH leading byte (0x05) is not a ++ * valid X9.63 marker. ProcessEcc_ex then fails at wc_ecc_import_x963 ++ * AFTER its unconditional cleanup at the end of the function frees the ++ * aliased key. Without the fix, the outer keyShareEntry->key still ++ * holds the freed pointer; wolfSSL_free -> TLSX_KeyShare_FreeAll calls ++ * wc_ecc_free + XFREE on it, producing a use-after-free and a double ++ * free that ASAN flags. */ ++int test_tls13_pqc_hybrid_malformed_ecdh(void) ++{ ++ EXPECT_DECLS; ++#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT) && \ ++ defined(WOLFSSL_HAVE_MLKEM) && defined(WOLFSSL_PQC_HYBRIDS) && \ ++ !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_ECC) && \ ++ !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \ ++ !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \ ++ (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \ ++ !defined(NO_ECC_SECP) ++ WOLFSSL_CTX *ctx = NULL; ++ WOLFSSL *ssl = NULL; ++ /* 5 (record) + 4 (HS) + 1207 (ServerHello body) = 1216 bytes. */ ++ static byte serverHello[1216]; ++ word32 i = 0; ++ WOLFSSL_BUFFER_INFO msg; ++ ++ XMEMSET(serverHello, 0, sizeof(serverHello)); ++ ++ /* Record: handshake, TLS 1.2 compat, length 1211 (0x04bb). */ ++ serverHello[i++] = 0x16; serverHello[i++] = 0x03; serverHello[i++] = 0x03; ++ serverHello[i++] = 0x04; serverHello[i++] = 0xbb; ++ /* Handshake: ServerHello (0x02), length 1207 (0x0004b7). */ ++ serverHello[i++] = 0x02; ++ serverHello[i++] = 0x00; serverHello[i++] = 0x04; serverHello[i++] = 0xb7; ++ /* legacy_version */ ++ serverHello[i++] = 0x03; serverHello[i++] = 0x03; ++ /* random (32 bytes) */ ++ XMEMSET(&serverHello[i], 0x42, 32); i += 32; ++ /* legacy_session_id_echo length: 0 */ ++ serverHello[i++] = 0x00; ++ /* cipher_suite: TLS_AES_128_GCM_SHA256 */ ++ serverHello[i++] = 0x13; serverHello[i++] = 0x01; ++ /* legacy_compression_method: null */ ++ serverHello[i++] = 0x00; ++ /* extensions length: 1167 (0x048f) */ ++ serverHello[i++] = 0x04; serverHello[i++] = 0x8f; ++ /* extension: supported_versions -> TLS 1.3 */ ++ serverHello[i++] = 0x00; serverHello[i++] = 0x2b; ++ serverHello[i++] = 0x00; serverHello[i++] = 0x02; ++ serverHello[i++] = 0x03; serverHello[i++] = 0x04; ++ /* extension: key_share, extension_data length 1157 (0x0485) */ ++ serverHello[i++] = 0x00; serverHello[i++] = 0x33; ++ serverHello[i++] = 0x04; serverHello[i++] = 0x85; ++ /* server_share.group: SECP256R1MLKEM768 (0x11eb) */ ++ serverHello[i++] = 0x11; serverHello[i++] = 0xeb; ++ /* key_exchange length: 1153 (0x0481) */ ++ serverHello[i++] = 0x04; serverHello[i++] = 0x81; ++ /* ECDH portion (65 bytes): leading 0x05 is not a valid X9.63 marker ++ * (valid markers: 0x04, 0x06, 0x07). The remaining 64 bytes stay zero ++ * from the initial XMEMSET. */ ++ serverHello[i++] = 0x05; ++ i += 64; ++ /* PQC portion (1088 bytes): all zero from the initial XMEMSET. */ ++ i += 1088; ++ AssertIntEQ((int)i, (int)sizeof(serverHello)); ++ ++ ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method())); ++ wolfSSL_SetIORecv(ctx, PqcHybridUafRecv); ++ wolfSSL_SetIOSend(ctx, PqcHybridUafSend); ++ ++ ExpectNotNull(ssl = wolfSSL_new(ctx)); ++ ++ /* Match the server's offered group so this key_share is processed. */ ++ ExpectIntEQ(wolfSSL_UseKeyShare(ssl, WOLFSSL_SECP256R1MLKEM768), ++ WOLFSSL_SUCCESS); ++ ++ msg.buffer = serverHello; ++ msg.length = (unsigned int)sizeof(serverHello); ++ wolfSSL_SetIOReadCtx(ssl, &msg); ++ ++ /* Connect should fail gracefully on the malformed ECDH point. */ ++ ExpectIntEQ(wolfSSL_connect_TLSv13(ssl), ++ WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)); ++ ++ /* Without the fix, this triggers UAF + double-free in ++ * TLSX_KeyShare_FreeAll. */ ++ wolfSSL_free(ssl); ++ wolfSSL_CTX_free(ctx); ++#endif ++ return EXPECT_RESULT(); ++} ++ + /* Test that a TLS 1.3 NewSessionTicket with a ticket shorter than ID_LEN + * (32 bytes) does not cause an unsigned integer underflow / OOB read in + * SetTicket. Uses a full memio handshake, then injects a crafted +diff --git a/tests/api/test_tls13.h b/tests/api/test_tls13.h +index c8eaa3b7f..94232f18e 100644 +--- a/tests/api/test_tls13.h ++++ b/tests/api/test_tls13.h +@@ -43,6 +43,7 @@ int test_tls13_warning_alert_is_fatal(void); + int test_tls13_cert_req_sigalgs(void); + int test_tls13_derive_keys_no_key(void); + int test_tls13_pqc_hybrid_truncated_keyshare(void); ++int test_tls13_pqc_hybrid_malformed_ecdh(void); + int test_tls13_short_session_ticket(void); + + #define TEST_TLS13_DECLS \ +@@ -65,6 +66,7 @@ int test_tls13_short_session_ticket(void); + TEST_DECL_GROUP("tls13", test_tls13_cert_req_sigalgs), \ + TEST_DECL_GROUP("tls13", test_tls13_derive_keys_no_key), \ + TEST_DECL_GROUP("tls13", test_tls13_pqc_hybrid_truncated_keyshare), \ ++ TEST_DECL_GROUP("tls13", test_tls13_pqc_hybrid_malformed_ecdh), \ + TEST_DECL_GROUP("tls13", test_tls13_short_session_ticket) + + #endif /* WOLFCRYPT_TEST_TLS13_H */ diff --git a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb index ef03d0c9ff..644c5379f5 100644 --- a/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb +++ b/meta-networking/recipes-connectivity/wolfssl/wolfssl_5.9.1.bb @@ -36,6 +36,7 @@ SRC_URI = " \ file://CVE-2026-6450-2.patch \ file://CVE-2026-6731-1.patch \ file://CVE-2026-6731-2.patch \ + file://CVE-2026-7531.patch \ " SRCREV = "1d363f3adceba9d1478230ede476a37b0dcdef24"