python3-pyasn1: fix CVE-2026-59885

This patch applies the upstream fix as referenced in [2],
using the commit shown in [1].

[1] https://github.com/pyasn1/pyasn1/commit/45bdb19eb7df4b3780fe9c912c63e99bffc39dd9
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-59885

(From OE-Core rev: 827730f97b522c4ab31dd2b7b5a33a4933c94750)

Signed-off-by: Yogita Urade <yurade@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
Yogita Urade authored and Paul Barker committed 2026-10-07 16:08:05 +01:00
1 parent ee53daff75
commit 81f2331d9e
2 files changed
+184

No files matched your search

@@ -22,6 +22,7 @@ SRC_URI += " \
file://CVE-2026-59886.patch \
file://CVE-2026-59884.patch \
file://CVE-2026-30922.patch \
file://CVE-2026-59885.patch \
"
RDEPENDS:${PN}-ptest += " \
@@ -0,0 +1,183 @@
From 844a3c11d47d346469f5b9ffd49f91e9b76a2572 Mon Sep 17 00:00:00 2001
From: Simon Pichugin <simon.pichugin@gmail.com>
Date: Wed, 8 Jul 2026 17:37:40 -0700
Subject: [PATCH] Merge commit from fork
CVE: CVE-2026-59885
Upstream-Status: Backport [https://github.com/pyasn1/pyasn1/commit/45bdb19eb7df4b3780fe9c912c63e99bffc39dd9]
Backport Changes:
- Omitted RelativeOID decoder and encoder changes, together with their
decoder and encoder regression tests, because RelativeOID support was
introduced in pyasn1 0.6.0 and is absent from pyasn1 0.5.1
(cherry picked from commit 45bdb19eb7df4b3780fe9c912c63e99bffc39dd9)
Signed-off-by: Yogita Urade <yurade@cisco.com>
---
pyasn1/codec/ber/decoder.py | 18 ++++++++++--------
pyasn1/codec/ber/encoder.py | 12 ++++++------
tests/codec/ber/test_decoder.py | 22 ++++++++++++++++++++++
tests/codec/ber/test_encoder.py | 10 ++++++++++
4 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 4d34080..3c95a59 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -428,14 +428,14 @@ class ObjectIdentifierPayloadDecoder(AbstractSimplePayloadDecoder):
chunk = octs2ints(chunk)
- oid = ()
+ oid = []
index = 0
substrateLen = len(chunk)
while index < substrateLen:
subId = chunk[index]
index += 1
if subId < 128:
- oid += (subId,)
+ oid.append(subId)
elif subId > 128:
# Construct subid from a number of octets
nextSubId = subId
@@ -451,11 +451,11 @@ class ObjectIdentifierPayloadDecoder(AbstractSimplePayloadDecoder):
subId = (subId << 7) + (nextSubId & 0x7F)
if index >= substrateLen:
raise error.SubstrateUnderrunError(
- 'Short substrate for sub-OID past %s' % (oid,)
+ 'Short substrate for sub-OID past %s' % (tuple(oid),)
)
nextSubId = chunk[index]
index += 1
- oid += ((subId << 7) + nextSubId,)
+ oid.append((subId << 7) + nextSubId)
elif subId == 128:
# ASN.1 spec forbids leading zeros (0x80) in OID
# encoding, tolerating it opens a vulnerability. See
@@ -465,15 +465,17 @@ class ObjectIdentifierPayloadDecoder(AbstractSimplePayloadDecoder):
# Decode two leading arcs
if 0 <= oid[0] <= 39:
- oid = (0,) + oid
+ oid.insert(0, 0)
elif 40 <= oid[0] <= 79:
- oid = (1, oid[0] - 40) + oid[1:]
+ oid[0] -= 40
+ oid.insert(0, 1)
elif oid[0] >= 80:
- oid = (2, oid[0] - 80) + oid[1:]
+ oid[0] -= 80
+ oid.insert(0, 2)
else:
raise error.PyAsn1Error('Malformed first OID octet: %s' % chunk[0])
- yield self._createComponent(asn1Spec, tagSet, oid, **options)
+ yield self._createComponent(asn1Spec, tagSet, tuple(oid), **options)
class RealPayloadDecoder(AbstractSimplePayloadDecoder):
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index c59b43e..7c3c5cf 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -327,30 +327,30 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
else:
raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
- octets = ()
+ octets = []
# Cycle through subIds
for subOid in oid:
if 0 <= subOid <= 127:
# Optimize for the common case
- octets += (subOid,)
+ octets.append(subOid)
elif subOid > 127:
# Pack large Sub-Object IDs
- res = (subOid & 0x7f,)
+ res = [subOid & 0x7f]
subOid >>= 7
while subOid:
- res = (0x80 | (subOid & 0x7f),) + res
+ res.append(0x80 | (subOid & 0x7f))
subOid >>= 7
# Add packed Sub-Object ID to resulted Object ID
- octets += res
+ octets.extend(reversed(res))
else:
raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value))
- return octets, False, False
+ return tuple(octets), False, False
class RealEncoder(AbstractItemEncoder):
diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py
index 672c9af..43b9617 100644
--- a/tests/codec/ber/test_decoder.py
+++ b/tests/codec/ber/test_decoder.py
@@ -27,6 +27,14 @@ from pyasn1.compat.octets import ints2octs, str2octs, null
from pyasn1 import error
+def encode_length(length):
+ if length < 128:
+ return bytes([length])
+
+ lengthBytes = length.to_bytes((length.bit_length() + 7) // 8, 'big')
+ return bytes([0x80 | len(lengthBytes)]) + lengthBytes
+
+
class LargeTagDecoderTestCase(BaseTestCase):
def testLargeTag(self):
assert decoder.decode(ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))) == (1, null)
@@ -476,6 +484,20 @@ class ObjectIdentifierDecoderTestCase(BaseTestCase):
ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB, 0xE2, 0xB6, 0x47))
) == ((2, 999, 18446744073709551535184467440737095), null)
+ def testManySingleByteArcs(self):
+ encodedArcCount = 4096
+ substrate = (
+ bytes([0x06]) +
+ encode_length(encodedArcCount) +
+ bytes([0x01] * encodedArcCount)
+ )
+
+ value, rest = decoder.decode(substrate)
+ assert rest == b''
+ assert len(value) == encodedArcCount + 1
+ assert tuple(value[:3]) == (0, 1, 1)
+ assert tuple(value[-3:]) == (1, 1, 1)
+
def testExcessiveContinuationOctets(self):
"""Test that OID arcs with excessive continuation octets are rejected."""
# Create a payload with 25 continuation octets (exceeds 20 limit)
diff --git a/tests/codec/ber/test_encoder.py b/tests/codec/ber/test_encoder.py
index 3d7567a..ef38eef 100644
--- a/tests/codec/ber/test_encoder.py
+++ b/tests/codec/ber/test_encoder.py
@@ -349,6 +349,16 @@ class ObjectIdentifierEncoderTestCase(BaseTestCase):
) == ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6,
0xB8, 0xCB, 0xE2, 0xB6, 0x47))
+ def testManySingleByteArcs(self):
+ arcCount = 4096
+ substrate = encoder.encode(
+ univ.ObjectIdentifier((1, 3) + (1,) * arcCount)
+ )
+
+ assert substrate == (
+ bytes([0x06, 0x82, 0x10, 0x01, 0x2B]) + bytes([0x01] * arcCount)
+ )
+
class ObjectIdentifierWithSchemaEncoderTestCase(BaseTestCase):
def testOne(self):
--
2.44.4