mirror of
https://git.yoctoproject.org/poky
synced 2026-10-04 13:30:54 +00:00
python3-cryptography: Fix CVE-2026-34073
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 (From OE-Core rev: fc077ee2c3a8c306df3245da7114724a7220c30b) Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
1 parent
6661b25ca2
commit
a4238b2e81
2 files changed
+168
No files matched your search
@@ -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 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
|
||||
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
|
||||
|
||||
@@ -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 \
|
||||
"
|
||||
|
||||
Reference in new issue
Block a user