* [OE-core][scarthgap][patch 1/3] python3-cryptography: Fix CVE-2026-34073
@ 2026-09-01 9:27 Vijay Anusuri
2026-09-01 9:27 ` [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248 Vijay Anusuri
2026-09-01 9:27 ` [OE-core][scarthgap][patch 3/3] python3-cryptography: Fix CVE-2026-69249 Vijay Anusuri
0 siblings, 2 replies; 11+ messages in thread
From: Vijay Anusuri @ 2026-09-01 9:27 UTC (permalink / raw)
To: openembedded-core; +Cc: Vijay Anusuri
Pick patch according to [2]
[1] https://nvd.nist.gov/vuln/detail/cve-2026-34073
[2] https://bugzilla.suse.com/show_bug.cgi?id=CVE-2026-34073
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
.../python3-cryptography/CVE-2026-34073.patch | 167 ++++++++++++++++++
.../python/python3-cryptography_42.0.5.bb | 1 +
2 files changed, 168 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-cryptography/CVE-2026-34073.patch
diff --git a/meta/recipes-devtools/python/python3-cryptography/CVE-2026-34073.patch b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-34073.patch
new file mode 100644
index 0000000000..93dd31f1aa
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-34073.patch
@@ -0,0 +1,167 @@
+From 6d97887956a05b3aaed262793710f07568026b72 Mon Sep 17 00:00:00 2001
+From: William Woodruff <william@yossarian.net>
+Date: Wed, 25 Mar 2026 18:52:17 -0400
+Subject: [PATCH] Further restrict DNS wildcards in name constraint matching
+ (#14542)
+
+* Further restruct DNS wildcards in name constraint matching
+
+Signed-off-by: William Woodruff <william@yossarian.net>
+
+* Bump limbo
+
+Signed-off-by: William Woodruff <william@yossarian.net>
+
+Upstream-Status: Backport [import from suse python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
+Upstream commit https://github.com/pyca/cryptography/commit/6d97887956a05b3aaed262793710f07568026b72]
+CVE: CVE-2026-34073
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ .../cryptography-x509-verification/src/lib.rs | 5 +-
+ .../src/types.rs | 89 ++++++++++++-------
+ 2 files changed, 62 insertions(+), 32 deletions(-)
+
+diff --git a/src/rust/cryptography-x509-verification/src/lib.rs b/src/rust/cryptography-x509-verification/src/lib.rs
+index 5ded892..f49f618 100644
+--- a/src/rust/cryptography-x509-verification/src/lib.rs
++++ b/src/rust/cryptography-x509-verification/src/lib.rs
+@@ -20,11 +20,12 @@ use cryptography_x509::{
+ oid::{NAME_CONSTRAINTS_OID, SUBJECT_ALTERNATIVE_NAME_OID},
+ };
+
++use types::{DNSPattern};
++
+ use crate::certificate::cert_is_self_issued;
+ use crate::ops::{CryptoOps, VerificationCertificate};
+ use crate::policy::Policy;
+ use crate::trust_store::Store;
+-use crate::types::DNSName;
+ use crate::types::{DNSConstraint, IPAddress, IPConstraint};
+ use crate::ApplyNameConstraintStatus::{Applied, Skipped};
+
+@@ -108,7 +109,7 @@ impl<'a, 'chain> NameChain<'a, 'chain> {
+
+ match (constraint, san) {
+ (GeneralName::DNSName(pattern), GeneralName::DNSName(name)) => {
+- match (DNSConstraint::new(pattern.0), DNSName::new(name.0)) {
++ match (DNSConstraint::new(pattern.0), DNSPattern::new(name.0)) {
+ (Some(pattern), Some(name)) => Ok(Applied(pattern.matches(&name))),
+ (_, None) => Err(ValidationError::Other(format!(
+ "unsatisfiable DNS name constraint: malformed SAN {}",
+diff --git a/src/rust/cryptography-x509-verification/src/types.rs b/src/rust/cryptography-x509-verification/src/types.rs
+index f564715..d82936e 100644
+--- a/src/rust/cryptography-x509-verification/src/types.rs
++++ b/src/rust/cryptography-x509-verification/src/types.rs
+@@ -129,35 +129,45 @@ impl<'a> DNSConstraint<'a> {
+ DNSName::new(pattern).map(Self)
+ }
+
+- /// Returns true if this `DNSConstraint` matches the given name.
++ /// Returns true if this `DNSConstraint` matches the given `DNSPattern`.
+ ///
+ /// Constraint matching is defined by RFC 5280: any DNS name that can
+ /// be constructed by simply adding zero or more labels to the left-hand
+ /// side of the name satisfies the name constraint.
+ ///
+- /// ```rust
+- /// # use cryptography_x509_verification::types::{DNSConstraint, DNSName};
+- /// let example_com = DNSName::new("example.com").unwrap();
+- /// let badexample_com = DNSName::new("badexample.com").unwrap();
+- /// let foo_example_com = DNSName::new("foo.example.com").unwrap();
+- /// assert!(DNSConstraint::new(example_com.as_str()).unwrap().matches(&example_com));
+- /// assert!(DNSConstraint::new(example_com.as_str()).unwrap().matches(&foo_example_com));
+- /// assert!(!DNSConstraint::new(example_com.as_str()).unwrap().matches(&badexample_com));
+- /// ```
+- pub fn matches(&self, name: &DNSName<'_>) -> bool {
+- // NOTE: This may seem like an obtuse way to perform label matching,
+- // but it saves us a few allocations: doing a substring check instead
+- // would require us to clone each string and do case normalization.
+- // Note also that we check the length in advance: Rust's zip
+- // implementation terminates with the shorter iterator, so we need
+- // to first check that the candidate name is at least as long as
+- // the constraint it's matching against.
+- name.as_str().len() >= self.0.as_str().len()
+- && self
+- .0
+- .rlabels()
+- .zip(name.rlabels())
+- .all(|(a, o)| a.eq_ignore_ascii_case(o))
++ /// On top of what RFC 5280 specifies, we define behavior for wildcard
++ /// patterns (which are not covered by RFC 5280): a wildcard pattern
++ /// matches a constraint if the pattern matches the constraint's inner name,
++ /// _or_ if the pattern's inner name matches the constraint.
++ /// This allows us to reject DNS names like `*.example.com` when
++ /// the constraint is `example.com` or `bar.example.com`.
++ pub fn matches(&self, name: &DNSPattern<'_>) -> bool {
++ match name {
++ DNSPattern::Exact(name) => {
++ // NOTE: This may seem like an obtuse way to perform label matching,
++ // but it saves us a few allocations: doing a substring check instead
++ // would require us to clone each string and do case normalization.
++ // Note also that we check the length in advance: Rust's zip
++ // implementation terminates with the shorter iterator, so we need
++ // to first check that the candidate name is at least as long as
++ // the constraint it's matching against.
++ name.as_str().len() >= self.0.as_str().len()
++ && self
++ .0
++ .rlabels()
++ .zip(name.rlabels())
++ .all(|(a, o)| a.eq_ignore_ascii_case(o))
++ }
++ DNSPattern::Wildcard(inner) => {
++ // NOTE: This check is not as simple as a single pattern match,
++ // since we need two subtly distinct cases here:
++ // 1. Constraint `bar.example.com` on `*.example.com`
++ // 2. Constraint `example.com` on `*.example.com`
++ // The first cases is handled by `DNSPattern::matches`, and the second is handled
++ // by `DNSConstraint::matches`.
++ name.matches(&self.0) || self.matches(&DNSPattern::Exact(inner.clone()))
++ }
++ }
+ }
+ }
+
+@@ -456,14 +466,33 @@ mod tests {
+ let example_com = DNSConstraint::new("example.com").unwrap();
+
+ // Exact domain and arbitrary subdomains match.
+- assert!(example_com.matches(&DNSName::new("example.com").unwrap()));
+- assert!(example_com.matches(&DNSName::new("foo.example.com").unwrap()));
+- assert!(example_com.matches(&DNSName::new("foo.bar.baz.quux.example.com").unwrap()));
++ assert!(example_com.matches(&DNSPattern::new("example.com").unwrap()));
++ assert!(example_com.matches(&DNSPattern::new("foo.example.com").unwrap()));
++ assert!(example_com.matches(&DNSPattern::new("foo.bar.baz.quux.example.com").unwrap()));
+
+ // Parent domains, distinct domains, and substring domains do not match.
+- assert!(!example_com.matches(&DNSName::new("com").unwrap()));
+- assert!(!example_com.matches(&DNSName::new("badexample.com").unwrap()));
+- assert!(!example_com.matches(&DNSName::new("wrong.com").unwrap()));
++ assert!(!example_com.matches(&DNSPattern::new("com").unwrap()));
++ assert!(!example_com.matches(&DNSPattern::new("badexample.com").unwrap()));
++ assert!(!example_com.matches(&DNSPattern::new("wrong.com").unwrap()));
++ }
++
++ #[test]
++ fn test_dnsconstraint_matches_wildcard() {
++ let com = DNSConstraint::new("com").unwrap();
++ let example_com = DNSConstraint::new("example.com").unwrap();
++ let bar_example_com = DNSConstraint::new("bar.example.com").unwrap();
++ let baz_bar_example_com = DNSConstraint::new("baz.bar.example.com").unwrap();
++ let any_example_com = DNSPattern::new("*.example.com").unwrap();
++
++ assert!(com.matches(&any_example_com));
++ assert!(example_com.matches(&any_example_com));
++ assert!(bar_example_com.matches(&any_example_com));
++
++ // A constraint on `baz.bar.example.com` doesn't match `*.example.com`,
++ // since `baz.bar.example.com` matches zero or more sublabels of
++ // `baz.bar.example.com` while `*.example.com` matches exactly one
++ // sublabel of `example.com`.
++ assert!(!baz_bar_example_com.matches(&any_example_com));
+ }
+
+ #[test]
+--
+2.43.0
+
diff --git a/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb b/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
index 10ce753eac..01382219fa 100644
--- a/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
+++ b/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
@@ -12,6 +12,7 @@ SRC_URI[sha256sum] = "6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da6
SRC_URI += "file://0001-pyproject.toml-remove-benchmark-disable-option.patch \
file://CVE-2026-26007.patch \
+ file://CVE-2026-34073.patch \
file://check-memfree.py \
file://run-ptest \
"
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248
2026-09-01 9:27 [OE-core][scarthgap][patch 1/3] python3-cryptography: Fix CVE-2026-34073 Vijay Anusuri
@ 2026-09-01 9:27 ` Vijay Anusuri
2026-09-10 14:20 ` Yoann Congal
2026-09-21 15:44 ` Yoann Congal
2026-09-01 9:27 ` [OE-core][scarthgap][patch 3/3] python3-cryptography: Fix CVE-2026-69249 Vijay Anusuri
1 sibling, 2 replies; 11+ messages in thread
From: Vijay Anusuri @ 2026-09-01 9:27 UTC (permalink / raw)
To: openembedded-core; +Cc: Vijay Anusuri
Pick patch according to [2]
[1] https://nvd.nist.gov/vuln/detail/cve-2026-69248
[2] https://security-tracker.debian.org/tracker/CVE-2026-69248
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
.../python3-cryptography/CVE-2026-69248.patch | 297 ++++++++++++++++++
.../python/python3-cryptography_42.0.5.bb | 1 +
2 files changed, 298 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
diff --git a/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
new file mode 100644
index 0000000000..5ccccd8034
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
@@ -0,0 +1,297 @@
+From 4d035a4225965edeffd312079a510ef25fcfdcb2 Mon Sep 17 00:00:00 2001
+From: William Woodruff <william@yossarian.net>
+Date: Thu, 21 May 2026 20:44:05 -0400
+Subject: [PATCH] x509: distinguish NC kinds when evaluating wildcard DNS SANs
+ (#14888)
+
+* x509: distinguish NC kinds when evaluating wildcard DNS SANs
+
+* Bump x509-limbo
+
+Upstream-Status: Backport [import from suse python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
+Upstream commit https://github.com/pyca/cryptography/commit/4d035a4225965edeffd312079a510ef25fcfdcb2]
+CVE: CVE-2026-69248
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ .../cryptography-x509-verification/src/lib.rs | 37 +++-
+ .../src/types.rs | 165 ++++++++++++------
+ 2 files changed, 145 insertions(+), 57 deletions(-)
+
+diff --git a/src/rust/cryptography-x509-verification/src/lib.rs b/src/rust/cryptography-x509-verification/src/lib.rs
+index f49f618..a505349 100644
+--- a/src/rust/cryptography-x509-verification/src/lib.rs
++++ b/src/rust/cryptography-x509-verification/src/lib.rs
+@@ -101,6 +101,7 @@ impl<'a, 'chain> NameChain<'a, 'chain> {
+
+ fn evaluate_single_constraint(
+ &self,
++ kind: SubtreeKind,
+ constraint: &GeneralName<'chain>,
+ san: &GeneralName<'chain>,
+ budget: &mut Budget,
+@@ -109,8 +110,18 @@ impl<'a, 'chain> NameChain<'a, 'chain> {
+
+ match (constraint, san) {
+ (GeneralName::DNSName(pattern), GeneralName::DNSName(name)) => {
++ // NOTE: A DNS SAN can be a wildcard pattern (e.g. `*.foo.com`)
++ // rather than an ordinary DNS name. A wildcard represents a
++ // *set* of names, so the check depends on which subtree we're
++ // evaluating: a `permittedSubtrees` constraint must contain
++ // *every* name the wildcard can expand to, whereas an
++ // `excludedSubtrees` constraint matches if it overlaps the
++ // wildcard at all. We dispatch on `kind` accordingly.
+ match (DNSConstraint::new(pattern.0), DNSPattern::new(name.0)) {
+- (Some(pattern), Some(name)) => Ok(Applied(pattern.matches(&name))),
++ (Some(pattern), Some(name)) => Ok(Applied(match kind {
++ SubtreeKind::Permitted => pattern.permits(&name),
++ SubtreeKind::Excluded => pattern.excludes(&name),
++ })),
+ (_, None) => Err(ValidationError::Other(format!(
+ "unsatisfiable DNS name constraint: malformed SAN {}",
+ name.0
+@@ -155,7 +166,12 @@ impl<'a, 'chain> NameChain<'a, 'chain> {
+ let mut permit = true;
+ if let Some(permitted_subtrees) = &constraints.permitted_subtrees {
+ for p in permitted_subtrees.unwrap_read().clone() {
+- let status = self.evaluate_single_constraint(&p.base, &san, budget)?;
++ let status = self.evaluate_single_constraint(
++ SubtreeKind::Permitted,
++ &p.base,
++ &san,
++ budget,
++ )?;
+ if status.is_applied() {
+ permit = status.is_match();
+ if permit {
+@@ -173,7 +189,12 @@ impl<'a, 'chain> NameChain<'a, 'chain> {
+
+ if let Some(excluded_subtrees) = &constraints.excluded_subtrees {
+ for e in excluded_subtrees.unwrap_read().clone() {
+- let status = self.evaluate_single_constraint(&e.base, &san, budget)?;
++ let status = self.evaluate_single_constraint(
++ SubtreeKind::Excluded,
++ &e.base,
++ &san,
++ budget,
++ )?;
+ if status.is_match() {
+ return Err(ValidationError::Other(
+ "excluded name constraint matched SAN".into(),
+@@ -207,6 +228,16 @@ struct ChainBuilder<'a, 'chain, B: CryptoOps> {
+ store: &'a Store<'chain, B>,
+ }
+
++/// Identifies which kind of name constraint subtree a SAN is being evaluated
++/// against. The two subtree kinds use different matching semantics for
++/// wildcard DNS SANs (containment vs. overlap); see [`DNSConstraint::permits`]
++/// and [`DNSConstraint::excludes`].
++#[derive(Clone, Copy)]
++enum SubtreeKind {
++ Permitted,
++ Excluded,
++}
++
+ // When applying a name constraint, we need to distinguish between a few different scenarios:
+ // * `Applied(true)`: The name constraint is the same type as the SAN and matches.
+ // * `Applied(false)`: The name constraint is the same type as the SAN and does not match.
+diff --git a/src/rust/cryptography-x509-verification/src/types.rs b/src/rust/cryptography-x509-verification/src/types.rs
+index d82936e..c0b72e3 100644
+--- a/src/rust/cryptography-x509-verification/src/types.rs
++++ b/src/rust/cryptography-x509-verification/src/types.rs
+@@ -129,44 +129,69 @@ impl<'a> DNSConstraint<'a> {
+ DNSName::new(pattern).map(Self)
+ }
+
+- /// Returns true if this `DNSConstraint` matches the given `DNSPattern`.
++ /// Returns true if the given exact `DNSName` falls within this
++ /// constraint's subtree.
+ ///
+- /// Constraint matching is defined by RFC 5280: any DNS name that can
+- /// be constructed by simply adding zero or more labels to the left-hand
+- /// side of the name satisfies the name constraint.
++ /// Per RFC 5280, a name satisfies the constraint if it can be constructed
++ /// by adding zero or more labels to the left-hand side of the constraint's
++ /// name (i.e. it is the constraint's name, or a subdomain of it).
++ fn contains(&self, name: &DNSName<'_>) -> bool {
++ // NOTE: This may seem like an obtuse way to perform label matching,
++ // but it saves us a few allocations: doing a substring check instead
++ // would require us to clone each string and do case normalization.
++ // Note also that we check the length in advance: Rust's zip
++ // implementation terminates with the shorter iterator, so we need
++ // to first check that the candidate name is at least as long as
++ // the constraint it's matching against.
++ name.as_str().len() >= self.0.as_str().len()
++ && self
++ .0
++ .rlabels()
++ .zip(name.rlabels())
++ .all(|(a, o)| a.eq_ignore_ascii_case(o))
++ }
++
++ /// Returns true if the given `DNSPattern` is permitted by this constraint,
++ /// for use with a `permittedSubtrees` name constraint.
+ ///
+- /// On top of what RFC 5280 specifies, we define behavior for wildcard
+- /// patterns (which are not covered by RFC 5280): a wildcard pattern
+- /// matches a constraint if the pattern matches the constraint's inner name,
+- /// _or_ if the pattern's inner name matches the constraint.
+- /// This allows us to reject DNS names like `*.example.com` when
+- /// the constraint is `example.com` or `bar.example.com`.
+- pub fn matches(&self, name: &DNSPattern<'_>) -> bool {
+- match name {
+- DNSPattern::Exact(name) => {
+- // NOTE: This may seem like an obtuse way to perform label matching,
+- // but it saves us a few allocations: doing a substring check instead
+- // would require us to clone each string and do case normalization.
+- // Note also that we check the length in advance: Rust's zip
+- // implementation terminates with the shorter iterator, so we need
+- // to first check that the candidate name is at least as long as
+- // the constraint it's matching against.
+- name.as_str().len() >= self.0.as_str().len()
+- && self
+- .0
+- .rlabels()
+- .zip(name.rlabels())
+- .all(|(a, o)| a.eq_ignore_ascii_case(o))
+- }
+- DNSPattern::Wildcard(inner) => {
+- // NOTE: This check is not as simple as a single pattern match,
+- // since we need two subtly distinct cases here:
+- // 1. Constraint `bar.example.com` on `*.example.com`
+- // 2. Constraint `example.com` on `*.example.com`
+- // The first cases is handled by `DNSPattern::matches`, and the second is handled
+- // by `DNSConstraint::matches`.
+- name.matches(&self.0) || self.matches(&DNSPattern::Exact(inner.clone()))
+- }
++ /// A pattern is permitted only if *every* name it can represent falls
++ /// within the constraint's subtree. An exact name is permitted by ordinary
++ /// subtree containment (per RFC 5280).
++ ///
++ /// Wildcard patterns are not covered by RFC 5280; we define their behavior
++ /// here. A wildcard pattern `*.X` is permitted only if its base name `X`
++ /// itself falls within the constraint's subtree. This is stricter than
++ /// mere overlap: `*.example.com` is *not* permitted by `foo.example.com`,
++ /// since it can also expand to a sibling such as `bar.example.com` that
++ /// lies outside the permitted subtree.
++ pub fn permits(&self, pattern: &DNSPattern<'_>) -> bool {
++ match pattern {
++ DNSPattern::Exact(name) => self.contains(name),
++ DNSPattern::Wildcard(base) => self.contains(base),
++ }
++ }
++
++ /// Returns true if the given `DNSPattern` is excluded by this constraint,
++ /// for use with an `excludedSubtrees` name constraint.
++ ///
++ /// A pattern is excluded if *any* name it can represent falls within the
++ /// constraint's subtree. An exact name is excluded by ordinary subtree
++ /// containment (per RFC 5280).
++ ///
++ /// Wildcard patterns are not covered by RFC 5280; we define their behavior
++ /// here. A wildcard pattern `*.X` is excluded if it overlaps the subtree
++ /// at all, which happens in two subtly distinct cases:
++ ///
++ /// 1. The constraint is more specific than the wildcard, e.g. constraint
++ /// `bar.example.com` and pattern `*.example.com` (which can expand to
++ /// `bar.example.com`). This is handled by `DNSPattern::matches`.
++ /// 2. The wildcard's base name falls within the subtree, e.g. constraint
++ /// `example.com` and pattern `*.example.com`. This is handled by
++ /// `DNSConstraint::contains`.
++ pub fn excludes(&self, pattern: &DNSPattern<'_>) -> bool {
++ match pattern {
++ DNSPattern::Exact(name) => self.contains(name),
++ DNSPattern::Wildcard(base) => pattern.matches(&self.0) || self.contains(base),
+ }
+ }
+ }
+@@ -462,37 +487,69 @@ mod tests {
+ }
+
+ #[test]
+- fn test_dnsconstraint_matches() {
++ fn test_dnsconstraint_exact() {
+ let example_com = DNSConstraint::new("example.com").unwrap();
+
+- // Exact domain and arbitrary subdomains match.
+- assert!(example_com.matches(&DNSPattern::new("example.com").unwrap()));
+- assert!(example_com.matches(&DNSPattern::new("foo.example.com").unwrap()));
+- assert!(example_com.matches(&DNSPattern::new("foo.bar.baz.quux.example.com").unwrap()));
++ // For exact patterns, `permits` and `excludes` behave identically:
++ // the pattern must fall within the constraint's subtree.
++ for permitted in [
++ "example.com",
++ "foo.example.com",
++ "foo.bar.baz.quux.example.com",
++ ] {
++ let pattern = DNSPattern::new(permitted).unwrap();
++ assert!(example_com.permits(&pattern));
++ assert!(example_com.excludes(&pattern));
++ }
+
+ // Parent domains, distinct domains, and substring domains do not match.
+- assert!(!example_com.matches(&DNSPattern::new("com").unwrap()));
+- assert!(!example_com.matches(&DNSPattern::new("badexample.com").unwrap()));
+- assert!(!example_com.matches(&DNSPattern::new("wrong.com").unwrap()));
++ for rejected in ["com", "badexample.com", "wrong.com"] {
++ let pattern = DNSPattern::new(rejected).unwrap();
++ assert!(!example_com.permits(&pattern));
++ assert!(!example_com.excludes(&pattern));
++ }
++ }
++
++ #[test]
++ fn test_dnsconstraint_permits_wildcard() {
++ let com = DNSConstraint::new("com").unwrap();
++ let example_com = DNSConstraint::new("example.com").unwrap();
++ let foo_example_com = DNSConstraint::new("foo.example.com").unwrap();
++ let any_example_com = DNSPattern::new("*.example.com").unwrap();
++
++ // A wildcard `*.example.com` is permitted only by constraints whose
++ // subtree contains *every* name the wildcard can expand to, i.e. those
++ // that contain `example.com` itself.
++ assert!(com.permits(&any_example_com));
++ assert!(example_com.permits(&any_example_com));
++
++ // A constraint more specific than the wildcard's base does *not*
++ // permit it: the wildcard can expand to siblings outside the subtree
++ // (e.g. `*.example.com` can be `bar.example.com`, which lies outside
++ // `foo.example.com`).
++ assert!(!foo_example_com.permits(&any_example_com));
+ }
+
+ #[test]
+- fn test_dnsconstraint_matches_wildcard() {
++ fn test_dnsconstraint_excludes_wildcard() {
+ let com = DNSConstraint::new("com").unwrap();
+ let example_com = DNSConstraint::new("example.com").unwrap();
+ let bar_example_com = DNSConstraint::new("bar.example.com").unwrap();
+ let baz_bar_example_com = DNSConstraint::new("baz.bar.example.com").unwrap();
+ let any_example_com = DNSPattern::new("*.example.com").unwrap();
+
+- assert!(com.matches(&any_example_com));
+- assert!(example_com.matches(&any_example_com));
+- assert!(bar_example_com.matches(&any_example_com));
+-
+- // A constraint on `baz.bar.example.com` doesn't match `*.example.com`,
+- // since `baz.bar.example.com` matches zero or more sublabels of
+- // `baz.bar.example.com` while `*.example.com` matches exactly one
+- // sublabel of `example.com`.
+- assert!(!baz_bar_example_com.matches(&any_example_com));
++ // A wildcard `*.example.com` is excluded by any constraint whose
++ // subtree it overlaps, including constraints more specific than the
++ // wildcard's base.
++ assert!(com.excludes(&any_example_com));
++ assert!(example_com.excludes(&any_example_com));
++ assert!(bar_example_com.excludes(&any_example_com));
++
++ // A constraint on `baz.bar.example.com` doesn't overlap
++ // `*.example.com`, since `baz.bar.example.com` matches zero or more
++ // sublabels of `baz.bar.example.com` while `*.example.com` matches
++ // exactly one sublabel of `example.com`.
++ assert!(!baz_bar_example_com.excludes(&any_example_com));
+ }
+
+ #[test]
+--
+2.43.0
+
diff --git a/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb b/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
index 01382219fa..8148ec0ba5 100644
--- a/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
+++ b/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
@@ -13,6 +13,7 @@ SRC_URI[sha256sum] = "6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da6
SRC_URI += "file://0001-pyproject.toml-remove-benchmark-disable-option.patch \
file://CVE-2026-26007.patch \
file://CVE-2026-34073.patch \
+ file://CVE-2026-69248.patch \
file://check-memfree.py \
file://run-ptest \
"
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [OE-core][scarthgap][patch 3/3] python3-cryptography: Fix CVE-2026-69249
2026-09-01 9:27 [OE-core][scarthgap][patch 1/3] python3-cryptography: Fix CVE-2026-34073 Vijay Anusuri
2026-09-01 9:27 ` [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248 Vijay Anusuri
@ 2026-09-01 9:27 ` Vijay Anusuri
2026-09-21 17:16 ` Yoann Congal
1 sibling, 1 reply; 11+ messages in thread
From: Vijay Anusuri @ 2026-09-01 9:27 UTC (permalink / raw)
To: openembedded-core; +Cc: Vijay Anusuri
Pick patch according to [2]
[1] https://nvd.nist.gov/vuln/detail/cve-2026-69249
[2] https://security-tracker.debian.org/tracker/CVE-2026-69249
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
.../python3-cryptography/CVE-2026-69249.patch | 349 ++++++++++++++++++
.../python/python3-cryptography_42.0.5.bb | 1 +
2 files changed, 350 insertions(+)
create mode 100644 meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
diff --git a/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
new file mode 100644
index 0000000000..a920b4a7cc
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
@@ -0,0 +1,349 @@
+From 4a12cf49675a184e47f912b00b04f3a629283582 Mon Sep 17 00:00:00 2001
+From: William Woodruff <william@yossarian.net>
+Date: Sat, 6 Jun 2026 23:30:03 -0400
+Subject: [PATCH] Add a signature validation budget during path construction
+ (#14960)
+
+* Add a signature validation budget during path construction
+
+This extends our existing NC budget check to include a budget
+for signature validations. If a path construction exceeds the
+budget by performing more than the allowed number of signature
+validation steps, the entire construction fails.
+
+For now, our budget is 128 signature validations. This is
+consistent with (higher than) Go and rustls-webpki, which
+both set a limit of 100. Like Go, we attempt to make the "best"
+use of our signature budget by ordering by likelihood, using
+AKI/SKI match as the strongest signal of fitness.
+
+* Bump limbo
+
+* Temporary commit
+
+* Revert "Temporary commit"
+
+This reverts commit bcdb6808562a8b8f484f85d21cb201cfdb2bbbd7.
+
+* Fudge a coverage test into place
+
+* Coverage for the coverage god
+
+Upstream-Status: Backport [import from suse python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
+Upstream commit https://github.com/pyca/cryptography/commit/4a12cf49675a184e47f912b00b04f3a629283582]
+CVE: CVE-2026-69249
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ .../cryptography-x509-verification/src/lib.rs | 209 +++++++++++++++++-
+ .../src/policy/mod.rs | 8 +-
+ 2 files changed, 208 insertions(+), 9 deletions(-)
+
+diff --git a/src/rust/cryptography-x509-verification/src/lib.rs b/src/rust/cryptography-x509-verification/src/lib.rs
+index a505349..334eed4 100644
+--- a/src/rust/cryptography-x509-verification/src/lib.rs
++++ b/src/rust/cryptography-x509-verification/src/lib.rs
+@@ -15,9 +15,12 @@ use std::vec;
+
+ use cryptography_x509::extensions::{DuplicateExtensionsError, Extensions};
+ use cryptography_x509::{
+- extensions::{NameConstraints, SubjectAlternativeName},
++ extensions::{AuthorityKeyIdentifier, NameConstraints, SubjectAlternativeName},
+ name::GeneralName,
+- oid::{NAME_CONSTRAINTS_OID, SUBJECT_ALTERNATIVE_NAME_OID},
++};
++use cryptography_x509::oid::{
++ AUTHORITY_KEY_IDENTIFIER_OID, NAME_CONSTRAINTS_OID, SUBJECT_ALTERNATIVE_NAME_OID,
++ SUBJECT_KEY_IDENTIFIER_OID,
+ };
+
+ use types::{DNSPattern};
+@@ -40,15 +43,23 @@ pub enum ValidationError {
+
+ struct Budget {
+ name_constraint_checks: usize,
++ signature_checks: usize,
+ }
+
+ impl Budget {
+- // Same limit as other validators
++ // The maximum number of name constraint checks performed when attempting
++ // path construction. This is the same limit as other validators.
+ const DEFAULT_NAME_CONSTRAINT_CHECK_LIMIT: usize = 1 << 20;
+
++ // The maximum number of signature verifications performed when attempting
++ // path construction. The is similar to other validators:
++ // both Go and rustls-webpki pick 100.
++ const DEFAULT_SIGNATURE_CHECK_LIMIT: usize = 1 << 7;
++
+ fn new() -> Budget {
+ Budget {
+ name_constraint_checks: Self::DEFAULT_NAME_CONSTRAINT_CHECK_LIMIT,
++ signature_checks: Self::DEFAULT_SIGNATURE_CHECK_LIMIT,
+ }
+ }
+
+@@ -61,6 +72,15 @@ impl Budget {
+ ))?;
+ Ok(())
+ }
++
++ fn signature_check(&mut self) -> Result<(), ValidationError> {
++ self.signature_checks = self.signature_checks.checked_sub(1).ok_or_else(|| {
++ ValidationError::FatalError(
++ "Exceeded maximum signature check limit",
++ )
++ })?;
++ Ok(())
++ }
+ }
+
+ impl From<asn1::ParseError> for ValidationError {
+@@ -270,18 +290,57 @@ impl<'a, 'chain, B: CryptoOps> ChainBuilder<'a, 'chain, B> {
+ }
+ }
+
++ /// Identify and return potential issuers for `cert`, considering
++ /// candidates from both the trusted store and untrusted intermediate set.
++ /// Trusted candidates are returned before untrusted intermediate
++ /// candidates, and both groups are opportunisitically ordered by
++ /// "likeliness" in terms of AKI/SKI match.
+ fn potential_issuers(
+ &'a self,
+ cert: &'a VerificationCertificate<'chain, B>,
+- ) -> impl Iterator<Item = &'a VerificationCertificate<'chain, B>> + '_ {
+- // TODO: Optimizations:
+- // * Search by AKI and other identifiers?
+- self.store
++ cert_extensions: &Extensions<'chain>,
++ ) -> Vec<&'a VerificationCertificate<'chain, B>> {
++ let mut candidates: Vec<&'a VerificationCertificate<'chain, B>> = self
++ .store
+ .get_by_subject(&cert.certificate().tbs_cert.issuer)
+ .iter()
+ .chain(self.intermediates.iter().filter(|&candidate| {
+ candidate.certificate().subject() == cert.certificate().issuer()
+ }))
++ .collect();
++
++ let want_kid: Option<&[u8]> = cert_extensions
++ .get_extension(&AUTHORITY_KEY_IDENTIFIER_OID)
++ .and_then(|ext| ext.value::<AuthorityKeyIdentifier<'_>>().ok())
++ .and_then(|aki| aki.key_identifier);
++
++ // This mirrors Go's `findPotentialParents`: we have a global
++ // signature budget, so we want to bucket candidates by likeliness
++ // to avoid wasting budget on (potentially adversarial) name collisions.
++ //
++ // Observe that we use a stable sort to preserve trusted candidates
++ // before untrusted candidates in each likeliness bucket. In other
++ // words, we always try a likely trusted candidate over an equally
++ // likely untrusted one.
++ //
++ // See: <https://github.com/golang/go/blob/d00c67f297e/src/crypto/x509/cert_pool.go#L136>
++ candidates.sort_by_key(|candidate| {
++ let have_kid: Option<&[u8]> =
++ candidate.certificate().extensions().ok().and_then(|exts| {
++ exts.get_extension(&SUBJECT_KEY_IDENTIFIER_OID)
++ .and_then(|ext| ext.value::<&[u8]>().ok())
++ });
++
++ match (want_kid, have_kid) {
++ // cert AKID matches candidate SKID, highest likelihood.
++ (Some(want), Some(have)) if want == have => 0,
++ // cert AKID and candidate SKID don't match, lowest likelihood.
++ (Some(_), Some(_)) => 2,
++ // cert AKID and/or candidate SKID is not present, medium likelihood.
++ _ => 1u8,
++ }
++ });
++ candidates
+ }
+
+ fn build_chain_inner(
+@@ -314,7 +373,8 @@ impl<'a, 'chain, B: CryptoOps> ChainBuilder<'a, 'chain, B> {
+ // Otherwise, we collect a list of potential issuers for this cert,
+ // and continue with the first that verifies.
+ let mut last_err: Option<ValidationError> = None;
+- for issuing_cert_candidate in self.potential_issuers(working_cert) {
++ for issuing_cert_candidate in self.potential_issuers(working_cert, working_cert_extensions)
++ {
+ // A candidate issuer is said to verify if it both
+ // signs for the working certificate and conforms to the
+ // policy.
+@@ -324,6 +384,7 @@ impl<'a, 'chain, B: CryptoOps> ChainBuilder<'a, 'chain, B> {
+ working_cert.certificate(),
+ current_depth,
+ &issuer_extensions,
++ budget,
+ ) {
+ Ok(_) => {
+ match self.build_chain_inner(
+@@ -417,3 +478,135 @@ impl<'a, 'chain, B: CryptoOps> ChainBuilder<'a, 'chain, B> {
+ Ok(chain)
+ }
+ }
++
++#[cfg(test)]
++mod tests {
++ use asn1::ParseError;
++ use cryptography_x509::certificate::Certificate;
++ use cryptography_x509::oid::SUBJECT_ALTERNATIVE_NAME_OID;
++
++ use crate::certificate::tests::PublicKeyErrorOps;
++ use crate::ops::{CryptoOps, VerificationCertificate};
++ use crate::policy::{Policy, PolicyDefinition, Subject};
++ use crate::trust_store::Store;
++ use crate::types::DNSName;
++ use crate::{Budget, ChainBuilder, NameChain, ValidationError};
++
++ #[test]
++ fn test_validationerror_display() {
++ let err = ValidationError::Malformed(
++ ParseError::new(asn1::ParseErrorKind::InvalidLength),
++ );
++ assert_eq!(err.to_string(), "ASN.1 parsing error: invalid length");
++
++ let err = ValidationError::ExtensionError{
++ oid: SUBJECT_ALTERNATIVE_NAME_OID,
++ reason: "duplicate extension",
++ };
++ assert_eq!(
++ err.to_string(),
++ "invalid extension: 2.5.29.17: duplicate extension"
++ );
++
++ let err = ValidationError::FatalError("oops");
++ assert_eq!(err.to_string(), "fatal error: oops");
++ }
++
++ /// A `CryptoOps` whose public key extraction and signature verification
++ /// always succeed, so that `valid_issuer` can be driven to completion
++ /// without real cryptographic material.
++ struct NullOps;
++
++ impl CryptoOps for NullOps {
++ type Key = ();
++ type Err = ();
++ type CertificateExtra = ();
++ type PolicyExtra = ();
++
++ fn public_key(&self, _cert: &Certificate<'_>) -> Result<Self::Key, Self::Err> {
++ Ok(())
++ }
++
++ fn verify_signed_by(
++ &self,
++ _cert: &Certificate<'_>,
++ _key: &Self::Key,
++ ) -> Result<(), Self::Err> {
++ Ok(())
++ }
++
++ fn clone_public_key(_key: &Self::Key) -> Self::Key {}
++
++ fn clone_extra(_extra: &Self::CertificateExtra) -> Self::CertificateExtra {}
++ }
++
++ #[test]
++ fn test_clone() {
++ assert_eq!(NullOps::clone_public_key(&()), ());
++ assert_eq!(NullOps::clone_extra(&()), ());
++ }
++
++ // A self-issued ("looping") CA certificate that is its own issuer.
++ fn looping_ca_pem() -> pem::Pem {
++ pem::parse(
++ "-----BEGIN CERTIFICATE-----
++MIIBcjCCARmgAwIBAgIBATAKBggqhkjOPQQDAjAhMR8wHQYDVQQDDBZsb29waW5n
++IHNlbGYtc2lnbmVkIENBMB4XDTIzMTIzMTAwMDAwMFoXDTI0MDEzMTAwMDAwMFow
++ITEfMB0GA1UEAwwWbG9vcGluZyBzZWxmLXNpZ25lZCBDQTBZMBMGByqGSM49AgEG
++CCqGSM49AwEHA0IABKAoXUGnHdfXJbSXjRjeW+PCVHmlo4KEki69N5pJUA0QyQMR
++v9ySOMnWf3Ea7TR4g3zdguwTP7LdpSku3uR1QkmjQjBAMA8GA1UdEwEB/wQFMAMB
++Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBR23MGdG1Ma9iR+3CxKTafD/OE0
++dTAKBggqhkjOPQQDAgNHADBEAiA4RCr07KfZdM16VfGNZAQFjvC60SWIU3RRVY/L
++qolIOwIgCaIgj9ipK0Q0p+45UJiq+L/ncrxsweJkFq/UYubzhX0=
++-----END CERTIFICATE-----",
++ )
++ .unwrap()
++ }
++
++ /// Exercises our pathlen overflow error scenario.
++ ///
++ /// This condition is logically unreachable from Python, since
++ /// we unconditionally limit signature checks to a number smaller
++ /// than `u8::MAX`, meaning that we always exhaust the signature budget
++ /// before potentially exhausting the pathlen budget.
++ ///
++ /// To test that directly, we manually lift the signature budget
++ /// and start our pathlen state right at `u8::MAX`, guaranteeing
++ /// an overflow on the immediate chain building step.
++ #[test]
++ fn test_build_chain_inner_depth_overflow() {
++ let pem = looping_ca_pem();
++ let ca = asn1::parse_single::<Certificate<'_>>(pem.contents()).unwrap();
++ let ca_exts = ca.extensions().ok().unwrap();
++
++ // The same self-issued CA is both the working certificate and its own
++ // (only) candidate issuer, so the search recurses on itself.
++ let working = VerificationCertificate::<NullOps>::new(&ca, ());
++ let intermediates = [VerificationCertificate::<NullOps>::new(&ca, ())];
++ let store: Store<'_, NullOps> = Store::new([]);
++
++ let subject = Subject::DNS(DNSName::new("example.com").unwrap());
++ let time = asn1::DateTime::new(2024, 1, 1, 0, 0, 0).unwrap();
++ let policy_def =
++ PolicyDefinition::server(NullOps, subject, time, Some(u8::MAX), None, None).unwrap();
++ let policy = Policy::new(&policy_def, ());
++
++ let builder = ChainBuilder::new(&intermediates, &policy, &store);
++ let mut budget = Budget {
++ name_constraint_checks: usize::MAX,
++ signature_checks: usize::MAX,
++ };
++
++ let name_chain = NameChain::new::<NullOps>(None, &ca_exts, false)
++ .ok()
++ .unwrap();
++ let err = builder
++ .build_chain_inner(&working, u8::MAX, &ca_exts, name_chain, &mut budget)
++ .unwrap_err();
++
++ assert!(matches!(
++ err.kind,
++ ValidationError::Other(msg) if msg.contains("current depth calculation overflowed")
++ ));
++ }
++}
+diff --git a/src/rust/cryptography-x509-verification/src/policy/mod.rs b/src/rust/cryptography-x509-verification/src/policy/mod.rs
+index d5a199d..5bdc8d5 100644
+--- a/src/rust/cryptography-x509-verification/src/policy/mod.rs
++++ b/src/rust/cryptography-x509-verification/src/policy/mod.rs
+@@ -25,7 +25,7 @@ use once_cell::sync::Lazy;
+ use crate::ops::CryptoOps;
+ use crate::policy::extension::{ca, common, ee, Criticality, ExtensionPolicy, ExtensionValidator};
+ use crate::types::{DNSName, DNSPattern, IPAddress};
+-use crate::{ValidationError, VerificationCertificate};
++use crate::{Budget, ValidationError, VerificationCertificate};
+
+ // SubjectPublicKeyInfo AlgorithmIdentifier constants, as defined in CA/B 7.1.3.1.
+
+@@ -463,10 +463,16 @@ impl<'a, B: CryptoOps> Policy<'a, B> {
+ child: &Certificate<'_>,
+ current_depth: u8,
+ issuer_extensions: &Extensions<'_>,
++ budget: &mut Budget,
+ ) -> Result<(), ValidationError> {
+ // The issuer needs to be a valid CA at the current depth.
+ self.permits_ca(issuer.certificate(), current_depth, issuer_extensions)?;
+
++ // Charge the (potentially expensive) signature verification against the
++ // budget before performing it, bounding the total work an attacker can
++ // force during chain building.
++ budget.signature_check()?;
++
+ // CA/B 7.1.3.1 SubjectPublicKeyInfo
+ // NOTE: We check the issuer's SPKI here, since the issuer is
+ // definitionally a CA and thus subject to CABF key requirements.
+--
+2.43.0
+
diff --git a/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb b/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
index 8148ec0ba5..899332123f 100644
--- a/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
+++ b/meta/recipes-devtools/python/python3-cryptography_42.0.5.bb
@@ -14,6 +14,7 @@ SRC_URI += "file://0001-pyproject.toml-remove-benchmark-disable-option.patch \
file://CVE-2026-26007.patch \
file://CVE-2026-34073.patch \
file://CVE-2026-69248.patch \
+ file://CVE-2026-69249.patch \
file://check-memfree.py \
file://run-ptest \
"
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248
2026-09-01 9:27 ` [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248 Vijay Anusuri
@ 2026-09-10 14:20 ` Yoann Congal
2026-09-18 5:50 ` Vijay Anusuri
2026-09-21 15:44 ` Yoann Congal
1 sibling, 1 reply; 11+ messages in thread
From: Yoann Congal @ 2026-09-10 14:20 UTC (permalink / raw)
To: vanusuri, openembedded-core
On Tue Sep 1, 2026 at 11:27 AM CEST, Vijay Anusuri via lists.openembedded.org wrote:
> Pick patch according to [2]
>
> [1] https://nvd.nist.gov/vuln/detail/cve-2026-69248
> [2] https://security-tracker.debian.org/tracker/CVE-2026-69248
>
> Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
> ---
> .../python3-cryptography/CVE-2026-69248.patch | 297 ++++++++++++++++++
> .../python/python3-cryptography_42.0.5.bb | 1 +
> 2 files changed, 298 insertions(+)
> create mode 100644 meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
Hello,
As far as I can tell, this CVE also need fixing on wrynose. Can you
send the need wrynose backports from this series so I can merge this on
scarthgap?
Thanks!
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248
2026-09-10 14:20 ` Yoann Congal
@ 2026-09-18 5:50 ` Vijay Anusuri
2026-09-18 8:20 ` Yoann Congal
0 siblings, 1 reply; 11+ messages in thread
From: Vijay Anusuri @ 2026-09-18 5:50 UTC (permalink / raw)
To: Yoann Congal; +Cc: openembedded-core
[-- Attachment #1: Type: text/plain, Size: 1101 bytes --]
Hi Yoann,
I have sent the required backport patches for wrynose.
Could you please consider these patches and merge them into scarthgap as
well?
Thanks & Regards,
Vijay
On Thu, Sep 10, 2026 at 7:50 PM Yoann Congal <yoann.congal@smile.fr> wrote:
> On Tue Sep 1, 2026 at 11:27 AM CEST, Vijay Anusuri via
> lists.openembedded.org wrote:
> > Pick patch according to [2]
> >
> > [1] https://nvd.nist.gov/vuln/detail/cve-2026-69248
> > [2] https://security-tracker.debian.org/tracker/CVE-2026-69248
> >
> > Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
> > ---
> > .../python3-cryptography/CVE-2026-69248.patch | 297 ++++++++++++++++++
> > .../python/python3-cryptography_42.0.5.bb | 1 +
> > 2 files changed, 298 insertions(+)
> > create mode 100644
> meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
>
> Hello,
>
> As far as I can tell, this CVE also need fixing on wrynose. Can you
> send the need wrynose backports from this series so I can merge this on
> scarthgap?
>
> Thanks!
> --
> Yoann Congal
> Smile ECS
>
>
[-- Attachment #2: Type: text/html, Size: 2135 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248
2026-09-18 5:50 ` Vijay Anusuri
@ 2026-09-18 8:20 ` Yoann Congal
0 siblings, 0 replies; 11+ messages in thread
From: Yoann Congal @ 2026-09-18 8:20 UTC (permalink / raw)
To: Vijay Anusuri; +Cc: openembedded-core
On Fri Sep 18, 2026 at 7:50 AM CEST, Vijay Anusuri wrote:
> Hi Yoann,
>
> I have sent the required backport patches for wrynose.
>
> Could you please consider these patches and merge them into scarthgap as
> well?
Hello,
I took both in my review branches.
Regards,
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248
2026-09-01 9:27 ` [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248 Vijay Anusuri
2026-09-10 14:20 ` Yoann Congal
@ 2026-09-21 15:44 ` Yoann Congal
2026-09-21 16:26 ` Vijay Anusuri
1 sibling, 1 reply; 11+ messages in thread
From: Yoann Congal @ 2026-09-21 15:44 UTC (permalink / raw)
To: vanusuri, openembedded-core
On Tue Sep 1, 2026 at 11:27 AM CEST, Vijay Anusuri via lists.openembedded.org wrote:
> Pick patch according to [2]
>
> [1] https://nvd.nist.gov/vuln/detail/cve-2026-69248
> [2] https://security-tracker.debian.org/tracker/CVE-2026-69248
>
> Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
> ---
> .../python3-cryptography/CVE-2026-69248.patch | 297 ++++++++++++++++++
> .../python/python3-cryptography_42.0.5.bb | 1 +
> 2 files changed, 298 insertions(+)
> create mode 100644 meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
>
> diff --git a/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
> new file mode 100644
> index 0000000000..5ccccd8034
> --- /dev/null
> +++ b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
> @@ -0,0 +1,297 @@
> +From 4d035a4225965edeffd312079a510ef25fcfdcb2 Mon Sep 17 00:00:00 2001
> +From: William Woodruff <william@yossarian.net>
> +Date: Thu, 21 May 2026 20:44:05 -0400
> +Subject: [PATCH] x509: distinguish NC kinds when evaluating wildcard DNS SANs
> + (#14888)
> +
> +* x509: distinguish NC kinds when evaluating wildcard DNS SANs
> +
> +* Bump x509-limbo
> +
> +Upstream-Status: Backport [import from suse python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
Hello,
"suse python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm": Where can I
download this? My usual Search engines/LLMs are not helpful here (and I
don't want to resort to boot a Suse container, yet)
Regards,
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248
2026-09-21 15:44 ` Yoann Congal
@ 2026-09-21 16:26 ` Vijay Anusuri
2026-09-21 17:10 ` Yoann Congal
0 siblings, 1 reply; 11+ messages in thread
From: Vijay Anusuri @ 2026-09-21 16:26 UTC (permalink / raw)
To: Yoann Congal; +Cc: openembedded-core
[-- Attachment #1: Type: text/plain, Size: 2106 bytes --]
Hi Yoann,
I downloaded the python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm from the
link below:
https://download.opensuse.org/distribution/leap-micro/6.1/product/repo/openSUSE-Leap-Micro-6.1-x86_64-Source/src/python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
Thanks & Regards,
Vijay
On Mon, Sep 21, 2026 at 9:14 PM Yoann Congal <yoann.congal@smile.fr> wrote:
> On Tue Sep 1, 2026 at 11:27 AM CEST, Vijay Anusuri via
> lists.openembedded.org wrote:
> > Pick patch according to [2]
> >
> > [1] https://nvd.nist.gov/vuln/detail/cve-2026-69248
> > [2] https://security-tracker.debian.org/tracker/CVE-2026-69248
> >
> > Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
> > ---
> > .../python3-cryptography/CVE-2026-69248.patch | 297 ++++++++++++++++++
> > .../python/python3-cryptography_42.0.5.bb | 1 +
> > 2 files changed, 298 insertions(+)
> > create mode 100644
> meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
> >
> > diff --git
> a/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
> b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
> > new file mode 100644
> > index 0000000000..5ccccd8034
> > --- /dev/null
> > +++
> b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69248.patch
> > @@ -0,0 +1,297 @@
> > +From 4d035a4225965edeffd312079a510ef25fcfdcb2 Mon Sep 17 00:00:00 2001
> > +From: William Woodruff <william@yossarian.net>
> > +Date: Thu, 21 May 2026 20:44:05 -0400
> > +Subject: [PATCH] x509: distinguish NC kinds when evaluating wildcard
> DNS SANs
> > + (#14888)
> > +
> > +* x509: distinguish NC kinds when evaluating wildcard DNS SANs
> > +
> > +* Bump x509-limbo
> > +
> > +Upstream-Status: Backport [import from suse
> python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
>
> Hello,
>
> "suse python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm": Where can I
> download this? My usual Search engines/LLMs are not helpful here (and I
> don't want to resort to boot a Suse container, yet)
>
> Regards,
> --
> Yoann Congal
> Smile ECS
>
>
[-- Attachment #2: Type: text/html, Size: 3386 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248
2026-09-21 16:26 ` Vijay Anusuri
@ 2026-09-21 17:10 ` Yoann Congal
0 siblings, 0 replies; 11+ messages in thread
From: Yoann Congal @ 2026-09-21 17:10 UTC (permalink / raw)
To: Vijay Anusuri; +Cc: openembedded-core
On Mon Sep 21, 2026 at 6:26 PM CEST, Vijay Anusuri wrote:
> Hi Yoann,
>
> I downloaded the python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm from the
> link below:
>
> https://download.opensuse.org/distribution/leap-micro/6.1/product/repo/openSUSE-Leap-Micro-6.1-x86_64-Source/src/python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
>
> Thanks & Regards,
> Vijay
Thanks!
In the future, please put that URL in the patch body.
Regards,
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [OE-core][scarthgap][patch 3/3] python3-cryptography: Fix CVE-2026-69249
2026-09-01 9:27 ` [OE-core][scarthgap][patch 3/3] python3-cryptography: Fix CVE-2026-69249 Vijay Anusuri
@ 2026-09-21 17:16 ` Yoann Congal
2026-09-22 6:25 ` Vijay Anusuri
0 siblings, 1 reply; 11+ messages in thread
From: Yoann Congal @ 2026-09-21 17:16 UTC (permalink / raw)
To: vanusuri, openembedded-core
On Tue Sep 1, 2026 at 11:27 AM CEST, Vijay Anusuri via lists.openembedded.org wrote:
> Pick patch according to [2]
>
> [1] https://nvd.nist.gov/vuln/detail/cve-2026-69249
> [2] https://security-tracker.debian.org/tracker/CVE-2026-69249
>
> Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
> ---
> .../python3-cryptography/CVE-2026-69249.patch | 349 ++++++++++++++++++
> .../python/python3-cryptography_42.0.5.bb | 1 +
> 2 files changed, 350 insertions(+)
> create mode 100644 meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
>
> diff --git a/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
> new file mode 100644
> index 0000000000..a920b4a7cc
> --- /dev/null
> +++ b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
> @@ -0,0 +1,349 @@
> +From 4a12cf49675a184e47f912b00b04f3a629283582 Mon Sep 17 00:00:00 2001
> +From: William Woodruff <william@yossarian.net>
> +Date: Sat, 6 Jun 2026 23:30:03 -0400
> +Subject: [PATCH] Add a signature validation budget during path construction
> + (#14960)
> +
> +* Add a signature validation budget during path construction
> +
> +This extends our existing NC budget check to include a budget
> +for signature validations. If a path construction exceeds the
> +budget by performing more than the allowed number of signature
> +validation steps, the entire construction fails.
> +
> +For now, our budget is 128 signature validations. This is
> +consistent with (higher than) Go and rustls-webpki, which
> +both set a limit of 100. Like Go, we attempt to make the "best"
> +use of our signature budget by ordering by likelihood, using
> +AKI/SKI match as the strongest signal of fitness.
> +
> +* Bump limbo
> +
> +* Temporary commit
> +
> +* Revert "Temporary commit"
> +
> +This reverts commit bcdb6808562a8b8f484f85d21cb201cfdb2bbbd7.
> +
> +* Fudge a coverage test into place
> +
> +* Coverage for the coverage god
> +
> +Upstream-Status: Backport [import from suse python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
> +Upstream commit https://github.com/pyca/cryptography/commit/4a12cf49675a184e47f912b00b04f3a629283582]
> +CVE: CVE-2026-69249
> +Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
> +---
> + .../cryptography-x509-verification/src/lib.rs | 209 +++++++++++++++++-
> + .../src/policy/mod.rs | 8 +-
> + 2 files changed, 208 insertions(+), 9 deletions(-)
When I compare CVE-2026-69249-signature-validation-budget.patch in
python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm and this patch, I get a
lot of diffs that don't look trivial to me (In particular, some hunks
about the budget handling disapear...)
Can you explain how/why did you change the upstream patch to match our
code?
Please send a v2 of this series with:
* URLs to download the Suze archive
* backport changes for this patch (2/3 also had changes but those were
easy to understand)
?
Thanks!
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [OE-core][scarthgap][patch 3/3] python3-cryptography: Fix CVE-2026-69249
2026-09-21 17:16 ` Yoann Congal
@ 2026-09-22 6:25 ` Vijay Anusuri
0 siblings, 0 replies; 11+ messages in thread
From: Vijay Anusuri @ 2026-09-22 6:25 UTC (permalink / raw)
To: Yoann Congal; +Cc: openembedded-core
[-- Attachment #1: Type: text/plain, Size: 3669 bytes --]
Hi Yoann,
On Mon, Sep 21, 2026 at 10:46 PM Yoann Congal <yoann.congal@smile.fr> wrote:
> On Tue Sep 1, 2026 at 11:27 AM CEST, Vijay Anusuri via
> lists.openembedded.org wrote:
> > Pick patch according to [2]
> >
> > [1] https://nvd.nist.gov/vuln/detail/cve-2026-69249
> > [2] https://security-tracker.debian.org/tracker/CVE-2026-69249
> >
> > Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
> > ---
> > .../python3-cryptography/CVE-2026-69249.patch | 349 ++++++++++++++++++
> > .../python/python3-cryptography_42.0.5.bb | 1 +
> > 2 files changed, 350 insertions(+)
> > create mode 100644
> meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
> >
> > diff --git
> a/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
> b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
> > new file mode 100644
> > index 0000000000..a920b4a7cc
> > --- /dev/null
> > +++
> b/meta/recipes-devtools/python/python3-cryptography/CVE-2026-69249.patch
> > @@ -0,0 +1,349 @@
> > +From 4a12cf49675a184e47f912b00b04f3a629283582 Mon Sep 17 00:00:00 2001
> > +From: William Woodruff <william@yossarian.net>
> > +Date: Sat, 6 Jun 2026 23:30:03 -0400
> > +Subject: [PATCH] Add a signature validation budget during path
> construction
> > + (#14960)
> > +
> > +* Add a signature validation budget during path construction
> > +
> > +This extends our existing NC budget check to include a budget
> > +for signature validations. If a path construction exceeds the
> > +budget by performing more than the allowed number of signature
> > +validation steps, the entire construction fails.
> > +
> > +For now, our budget is 128 signature validations. This is
> > +consistent with (higher than) Go and rustls-webpki, which
> > +both set a limit of 100. Like Go, we attempt to make the "best"
> > +use of our signature budget by ordering by likelihood, using
> > +AKI/SKI match as the strongest signal of fitness.
> > +
> > +* Bump limbo
> > +
> > +* Temporary commit
> > +
> > +* Revert "Temporary commit"
> > +
> > +This reverts commit bcdb6808562a8b8f484f85d21cb201cfdb2bbbd7.
> > +
> > +* Fudge a coverage test into place
> > +
> > +* Coverage for the coverage god
> > +
> > +Upstream-Status: Backport [import from suse
> python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm
> > +Upstream commit
> https://github.com/pyca/cryptography/commit/4a12cf49675a184e47f912b00b04f3a629283582
> ]
> > +CVE: CVE-2026-69249
> > +Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
> > +---
> > + .../cryptography-x509-verification/src/lib.rs | 209 +++++++++++++++++-
> > + .../src/policy/mod.rs | 8 +-
> > + 2 files changed, 208 insertions(+), 9 deletions(-)
>
> When I compare CVE-2026-69249-signature-validation-budget.patch in
> python-cryptography-42.0.4-slfo.1.1_6.1.src.rpm and this patch, I get a
> lot of diffs that don't look trivial to me (In particular, some hunks
> about the budget handling disapear...)
>
the budget-handling changes that are missing from our version of the patch
are already present in our codebase. Therefore, those hunks were not
included in the backport. so those changes were not applied again.
>
> Can you explain how/why did you change the upstream patch to match our
> code?
>
> Please send a v2 of this series with:
> * URLs to download the Suze archive
> * backport changes for this patch (2/3 also had changes but those were
> easy to understand)
> ?
>
I will send the updated v2 series shortly.
>
> Thanks!
> --
> Yoann Congal
> Smile ECS
>
>
Thanks & Regards,
Vijay
[-- Attachment #2: Type: text/html, Size: 5363 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-09-22 6:25 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 9:27 [OE-core][scarthgap][patch 1/3] python3-cryptography: Fix CVE-2026-34073 Vijay Anusuri
2026-09-01 9:27 ` [OE-core][scarthgap][patch 2/3] python3-cryptography: Fix CVE-2026-69248 Vijay Anusuri
2026-09-10 14:20 ` Yoann Congal
2026-09-18 5:50 ` Vijay Anusuri
2026-09-18 8:20 ` Yoann Congal
2026-09-21 15:44 ` Yoann Congal
2026-09-21 16:26 ` Vijay Anusuri
2026-09-21 17:10 ` Yoann Congal
2026-09-01 9:27 ` [OE-core][scarthgap][patch 3/3] python3-cryptography: Fix CVE-2026-69249 Vijay Anusuri
2026-09-21 17:16 ` Yoann Congal
2026-09-22 6:25 ` Vijay Anusuri
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox