From patchwork Thu Aug 20 05:16:27 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" X-Patchwork-Id: 95858 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 80C5BC5DF85 for ; Thu, 20 Aug 2026 05:19:15 +0000 (UTC) Received: from alln-iport-4.cisco.com (alln-iport-4.cisco.com [173.37.142.91]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.556.1787203150286865810 for ; Wed, 19 Aug 2026 22:19:10 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: message contains an insecure body length tag" header.i=@cisco.com header.s=iport01 header.b=hTsy3dvX; spf=pass (domain: cisco.com, ip: 173.37.142.91, mailfrom: hthakar@cisco.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cisco.com; i=@cisco.com; l=9034; q=dns/txt; s=iport01; t=1787203150; x=1788412750; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=o4HNRelvX4/Jz8m5K7xR2TqJniktNP/SOjxKlC3uOUY=; b=hTsy3dvX+7xgyQXHe4juH1i+Bi8a1xKHgofPOtsx61rGpzvmyHez7qHS lFNLBmUiU5YZVS5/5gAe0EiYpGuWijMIMxHBFV8R1L74eWGHk9/euuP7w jJzr+ARMToxdIiH1aAKPrUaiDubE+VkKnXoT8/r10I7wLS5oFkCQL2dvv K5ddOuuGlpjevdCfw0R56IOqeEZarBxVxt75/Sg3d6T5MnnveUy6P6o9M I2ZdfyGzbYENZkYIcAJxbLuV25FhryKjj4JbclIUfo4QgykPrOD+DDgGf a/iSFcIP6xSN89tFJ7blDG9VfMsQfwMPREJEBKJaDGNSCq+EqppFut24l Q==; X-CSE-ConnectionGUID: eGr32raySPyjBrNZ0HOzSw== X-CSE-MsgGUID: AccbY9O8TCuWEHnXvR5jSg== X-IPAS-Result: A0BGAgADjoZq/4oQJK1aglmCV3ReQ0mWSotnkjeBfg8BAQEPRA0EAQGEP0aNbQImNAkOAQIEAwIDAQEBAQEBAQEBAQELAQEFAQEBAgEHBYEOE4ZPDYZaAQIBKgsBGAEtLAMBAk8LIyGDAgGCOgM3AxHCSIF5M4EBgygBPwJDUNhLDYJYAQsUAQWBM4U/gn+FI10YAYR8JxsbgXKBFYNpgQWBGkIBAYFCD4ZUBIIiehKBWoEtkENIgR4DWSwBVRMNCgsHBYFmAzUSKhVuMh2BIz4XgQ0bBgWBHYEohDcjGTZ8gQlegSsqYQESF4EJggoCgnCCBgIBSUUOCRcLGA1IESw3FBkEPm4HjlEggkuBCQUBK4EFfygWkyEBkB2CIaAecQoog3aMIY8+hXwaM6psC5h9jgqECZJHhGmBaDyBRwsHcBU7gmcJShkPji0LC4NggX/KOicyAgkyAQEHAgcOAwuBaJACgXwBAQ IronPort-Data: A9a23:poAJo6r02CP4FprsZ01OfqysUDBeBmJLZBIvgKrLsJaIsI4StFCzt garIBnUMv/eNjD8KN93OYy2/BhSvMOEx9dnTQM+pX1kQnhDouPIVI+TRqvS04x+DSFioGZPt Zh2hgzodZhsJpPkjk7zdOCn9j8kif3gqoPUUIbsIjp2SRJvVBAvgBdin/9RqoNziLBVOSvV0 T/Ji5OZYgLNNwJcaDpOtfrT8UI35pwehRtB1rAATaET1LPhvyF94KI3fcmZM3b+S49IKe+2L 86r5K255G7Q4yA2AdqjlLvhGmVSKlIFFVHT4pb+c/HKbilq/kTe4I5iXBYvQRs/ZwGyojxE4 I4lWapc5useFvakdOw1C3G0GszlVEFM0OevzXOX6aR/w6BaGpfh660GMa04AWEX0utYGzoU7 /UJEwgcbDqZodDu4JWpcfY506zPLOGzVG8eknhkyTecCbMtRorOBv2To9RZxzw3wMtJGJ4yZ eJANmEpN0qGOkMJYwxHYH49tL/Aan3XcyFYoVGcv4I84nPYy0p6172F3N/9KoXRG5gLxBnHz o7A103yCRsrZfvP9RGYzV+MgN/Rp375Y41HQdVU8dYv2jV/3Fc7DwUbU1a+q/S1hkOyHt5SN UEQ0i4vtrQpskuzQ9/wWhe1rHKJslgbQdU4LgEhwAiJzqyR50OSAXIJC2YYLtcnr8QxAzct0 zdlgu/UONCmi5XNIVr1y1tehWrvYHh9wbMqDcPccTY43g== IronPort-HdrOrdr: A9a23:S06Zqa29QVnrHFjQ7FbMmQqjBJ4kLtp133Aq2lEZdPWaSKOlfq eV7ZEmPHDP6Qr5NEtMpTniAtjjfZqjz/5ICOAqVN/INjUO01HHEGgN1+ffKhTbaknDH5ZmpM RdWpk7LsHsBl5nisu/ygy5H9E8hOSjysmT9IDjJ7MHd3ASV0mmhD0JbDqmLg== X-Talos-CUID: 9a23:yInd22Cfdt30Cq36EyRI7hVOAMk0SUXMzl3KBX3gKUF7c6LAHA== X-Talos-MUID: 9a23:ylaJPwW4DcmUet7q/BbnjztTZeA434+zN20tl6UYgZSGDiMlbg== X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.25,232,1779148800"; d="scan'208";a="813656277" Received: from alln-l-core-01.cisco.com ([173.36.16.138]) by alln-iport-4.cisco.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 20 Aug 2026 05:18:45 +0000 Received: from sjc-ads-5471.cisco.com (sjc-ads-5471.cisco.com [10.28.23.235]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "ciscoit-managed-infra-smtp-auth.cisco.com", Issuer "Internal Private TLS SubCA" (verified OK)) by alln-l-core-01.cisco.com (Postfix) with ESMTPS id C656318009018; Thu, 20 Aug 2026 05:16:32 +0000 (GMT) Received: by sjc-ads-5471.cisco.com (Postfix, from userid 1887505) id 66AA3CC12A6; Wed, 19 Aug 2026 22:16:32 -0700 (PDT) From: "Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" To: openembedded-devel@lists.openembedded.org Cc: xe-linux-external@cisco.com, Hetvi Thakar Subject: [meta-python][scarthgap][PATCH 1/4] python3-ujson: Fix CVE-2026-32875 Date: Wed, 19 Aug 2026 22:16:27 -0700 Message-Id: <20260820051630.63383-1-hthakar@cisco.com> X-Mailer: git-send-email 2.35.6 MIME-Version: 1.0 X-Auto-Response-Suppress: DR, OOF, AutoReply X-Outbound-Client-TLS: VERIFIED;sjc-ads-5471.cisco.com [10.28.23.235];TLSv1.3;TLS_AES_256_GCM_SHA384;256;ciscoit-managed-infra-smtp-auth.cisco.com X-Outbound-SMTP-Client: 10.28.23.235, sjc-ads-5471.cisco.com X-Outbound-Node: alln-l-core-01.cisco.com 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 ; Thu, 20 Aug 2026 05:19:15 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129373 From: Hetvi Thakar This patch applies the upstream fix referenced in [2], using the commit shown in [1]. [1] https://github.com/ultrajson/ultrajson/commit/486bd4553dc471a1de11613bc7347a6b318e37ea [2] https://nvd.nist.gov/vuln/detail/CVE-2026-32875 Signed-off-by: Hetvi Thakar --- .../python/python3-ujson/CVE-2026-32875.patch | 199 ++++++++++++++++++ .../python/python3-ujson_5.9.0.bb | 1 + 2 files changed, 200 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-ujson/CVE-2026-32875.patch diff --git a/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-32875.patch b/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-32875.patch new file mode 100644 index 0000000000..5727412835 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-32875.patch @@ -0,0 +1,199 @@ +From efe3a00499a74ff44867711f40f9bcc279d2ea92 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Br=C3=A9nainn=20Woodsend?= +Date: Wed, 4 Mar 2026 22:28:11 +0000 +Subject: [PATCH] Fix buffer overflow/infinite loop from indent handling + +If indent * nest depth is large enough to overflow an int, it causes the +required output buffer size to be underestimated leading to a buffer +overflow. + +The offending arithmetic is upgraded to a ptrdiff_t and indent is +artificially capped. An overflow is still technically possible given a +high enough recursion depth but not without first consuming petabytes of +RAM. + +If indent is negative, it causes a size_t to underflow to some number a +little bellow size_t max. If that underflow isn't accidentally rectified +by a subsequent overflow (if -indent * (nest_depth + 1) > +current_buffer_size) then the buffer up-sizer gets stuck in an infinite +loop trying to find a power of two that fits in a size_t but is greater +that size_t max / 2. + +It's hard to tell if `ujson.dumps(..., indent=-1)` was ever an +intentional feature but I don't feel comfortable breaking it in a +security fix. For now, the dubious *any negative indent -> pad colons +but add no indentation or newlines* behaviour is preserved but +internally the indent is clipped to -1 and all subsequent indentation +code paths are skipped over. + +CVE: CVE-2026-32875 +Upstream-Status: Backport [https://github.com/ultrajson/ultrajson/commit/486bd4553dc471a1de11613bc7347a6b318e37ea] + +Backport Changes: +- Adjusted source paths for ujson 5.9.0's pre-src-layout tree. + +(cherry picked from commit 486bd4553dc471a1de11613bc7347a6b318e37ea) +Signed-off-by: Hetvi Thakar +--- + lib/ultrajson.h | 3 ++- + lib/ultrajsonenc.c | 16 +++++++++------- + python/objToJSON.c | 16 +++++++++++++++- + tests/test_ujson.py | 20 ++++++++++++++++++-- + 4 files changed, 44 insertions(+), 11 deletions(-) + +diff --git a/lib/ultrajson.h b/lib/ultrajson.h +index 143cd9e..4560f4d 100644 +--- a/lib/ultrajson.h ++++ b/lib/ultrajson.h +@@ -54,6 +54,7 @@ tree doesn't have cyclic references. + #define __ULTRAJSON_H__ + + #include ++#include + + // Max decimals to encode double floating point numbers with + #ifndef JSON_DOUBLE_MAX_DECIMALS +@@ -257,7 +258,7 @@ typedef struct __JSONObjectEncoder + + /* + Configuration for spaces of indent */ +- int indent; ++ ptrdiff_t indent; + + /* + If true, NaN will be encoded as a string matching the Python standard library's JSON behavior. +diff --git a/lib/ultrajsonenc.c b/lib/ultrajsonenc.c +index 9ec2faf..0f9fde3 100644 +--- a/lib/ultrajsonenc.c ++++ b/lib/ultrajsonenc.c +@@ -575,7 +575,7 @@ static void Buffer_AppendIndentNewlineUnchecked(JSONObjectEncoder *enc) + + static void Buffer_AppendIndentUnchecked(JSONObjectEncoder *enc, JSINT32 value) + { +- int i; ++ ptrdiff_t i; + if (enc->indent > 0) + while (value-- > 0) + for (i = 0; i < enc->indent; i++) +@@ -741,10 +741,11 @@ static void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t c + + Buffer_AppendCharUnchecked (enc, '['); + ++ // The extra 1 byte covers the optional newline. ++ size_t per_item_reserve = (enc->indent > 0 ? enc->indent : 0) * (enc->level + 1) + enc->itemSeparatorLength + 1; + while (enc->iterNext(obj, &tc)) + { +- // The extra 1 byte covers the optional newline. +- Buffer_Reserve (enc, enc->indent * (enc->level + 1) + enc->itemSeparatorLength + 1); ++ Buffer_Reserve (enc, per_item_reserve); + + if (count > 0) + { +@@ -769,7 +770,7 @@ static void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t c + + enc->iterEnd(obj, &tc); + +- if (count > 0) { ++ if (count > 0 && enc->indent > 0) { + // Reserve space for the indentation plus the newline. + Buffer_Reserve (enc, enc->indent * enc->level + 1); + Buffer_AppendIndentNewlineUnchecked (enc); +@@ -786,10 +787,11 @@ static void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t c + + Buffer_AppendCharUnchecked (enc, '{'); + ++ // The extra 1 byte covers the optional newline. ++ size_t reserve_size = (enc->indent > 0 ? enc->indent : 0) * (enc->level + 1) + enc->itemSeparatorLength + 1; + while ((res = enc->iterNext(obj, &tc))) + { +- // The extra 1 byte covers the optional newline. +- Buffer_Reserve (enc, enc->indent * (enc->level + 1) + enc->itemSeparatorLength + 1); ++ Buffer_Reserve (enc, reserve_size); + + if(res < 0) + { +@@ -823,7 +825,7 @@ static void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t c + + enc->iterEnd(obj, &tc); + +- if (count > 0) { ++ if (count > 0 && enc->indent > 0) { + Buffer_Reserve (enc, enc->indent * enc->level + 1); + Buffer_AppendIndentNewlineUnchecked (enc); + Buffer_AppendIndentUnchecked (enc, enc->level); +diff --git a/python/objToJSON.c b/python/objToJSON.c +index b754819..9013205 100644 +--- a/python/objToJSON.c ++++ b/python/objToJSON.c +@@ -678,6 +678,7 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs) + PyObject *separatorsKeyBytes = NULL; + int allowNan = -1; + int orejectBytes = -1; ++ int indent = 0; + size_t retLen; + + JSONObjectEncoder encoder = +@@ -714,7 +715,7 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs) + + PRINTMARK(); + +- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOOOiiiOO", kwlist, &oinput, &oensureAscii, &oencodeHTMLChars, &oescapeForwardSlashes, &osortKeys, &encoder.indent, &allowNan, &orejectBytes, &odefaultFn, &oseparators)) ++ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOOOiiiOO", kwlist, &oinput, &oensureAscii, &oencodeHTMLChars, &oescapeForwardSlashes, &osortKeys, &indent, &allowNan, &orejectBytes, &odefaultFn, &oseparators)) + { + return NULL; + } +@@ -761,6 +762,19 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs) + encoder.rejectBytes = orejectBytes; + } + ++ if (indent < -1) ++ { ++ encoder.indent = -1; ++ } ++ else if (indent > 1000) ++ { ++ PyErr_SetString(PyExc_ValueError, "Maximum allowed indentation is 1000"); ++ return NULL; ++ } ++ else { ++ encoder.indent = indent; ++ } ++ + if (oseparators != NULL && oseparators != Py_None) + { + if (!PyTuple_Check(oseparators)) +diff --git a/tests/test_ujson.py b/tests/test_ujson.py +index 506666d..d24edb0 100644 +--- a/tests/test_ujson.py ++++ b/tests/test_ujson.py +@@ -1050,9 +1050,25 @@ def test_default_function(): + ujson.dumps(unjsonable_obj, default=default) + + +-@pytest.mark.parametrize("indent", list(range(65537, 65542))) ++@pytest.mark.parametrize("indent", [999, 1000, 1001, 1 << 30, 1 << 63, 1 << 128]) + def test_dump_huge_indent(indent): +- ujson.encode({"a": True}, indent=indent) ++ obj = {"list": [1, [2, 3], 4], "nested": {"key": "value", "a": True}} ++ if indent <= 1000: ++ assert ujson.loads(ujson.encode(obj, indent=indent)) == obj ++ else: ++ with pytest.raises((ValueError, OverflowError)): ++ ujson.encode(obj, indent=indent) ++ ++ ++def test_negative_indent(): ++ obj = {"a": [1, 2], "b": "c"} ++ assert ujson.dumps(obj) == '{"a":[1,2],"b":"c"}' ++ assert ujson.dumps(obj, 0) == '{"a":[1,2],"b":"c"}' ++ assert ujson.dumps(obj, indent=-1) == '{"a": [1,2],"b": "c"}' ++ assert ujson.dumps(obj, indent=-1000000) == '{"a": [1,2],"b": "c"}' ++ assert ( ++ ujson.dumps(obj, indent=2) == '{\n "a": [\n 1,\n 2\n ],\n "b": "c"\n}' ++ ) + + + @pytest.mark.parametrize("first_length", list(range(2, 7))) +-- +2.35.6 + diff --git a/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb b/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb index b5f6be9f27..c6b69790e8 100644 --- a/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb +++ b/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb @@ -11,6 +11,7 @@ inherit pypi ptest setuptools3 SRC_URI += " \ file://run-ptest \ file://0001-setup.py-Do-not-strip-debugging-symbols.patch \ + file://CVE-2026-32875.patch \ " DEPENDS += "python3-setuptools-scm-native" From patchwork Thu Aug 20 05:16:28 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" X-Patchwork-Id: 95861 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 A2965C5DF81 for ; Thu, 20 Aug 2026 05:21:25 +0000 (UTC) Received: from alln-iport-1.cisco.com (alln-iport-1.cisco.com [173.37.142.88]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.636.1787203284354275697 for ; Wed, 19 Aug 2026 22:21:24 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: message contains an insecure body length tag" header.i=@cisco.com header.s=iport01 header.b=LErPbGB2; spf=pass (domain: cisco.com, ip: 173.37.142.88, mailfrom: hthakar@cisco.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cisco.com; i=@cisco.com; l=3508; q=dns/txt; s=iport01; t=1787203284; x=1788412884; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0C0oNvsVhwOicgp5WHQEQBycI0iDjNQrQlx1jYKdy14=; b=LErPbGB2/S2Fn6aZHvKd6I6NuX9k3A2s1nVlZ8SivH8hq3TfDiwnocnR RKfaUg3515Juws9D8BVXUZ2Mavt8bFDW1sI6kDqQrQ9jf6190RNKyeVLO u8Q54s9/ViBtg5NBkNkr7ZUDHp1Jnp8hkoNevvzn2bUUv97IsLFNEN3nG AIhxz+/VIW5TvcWyoruB1GuOarFvi7U+GT3pw/K/lx2aOTwHS2RXGPZRa f7GKu2NnAdk9rlkgZxE7O409C5/vN7SQsgc9yQSL05EEX7iwdBftmdDAs mDW4JstvnT0tJJ4zhO2Ba9C3f5H9CGRIDo++OixL80z7bjrkPWHdp5go5 Q==; X-CSE-ConnectionGUID: 1nGpROkRQbaWjQdLbMqhpQ== X-CSE-MsgGUID: J+ke2GJnSKqnrfWDV5IbbQ== X-IPAS-Result: A0BHAgADjoZq/5EQJK1aHgEBCxIMggULgld0XkNJlk2LZJI3gX4PAQEBD0QNBAEBhD9GAo1rAiY0CQ4BAgQDAgMBAQEBAQEBAQEBAQsBAQUBAQECAQcFgQ4Thk8NhloBAgEDMgEYAS0QHAMBAi8gCyMIGYMCAYI6AzcDEcJIgiyBAYMoAT8CQ1DYSw2CWAELFAEFgTOFP4J/hSNdGAGEfCcbG4FygRWDaYEFgRpCAQGBJ4Z+BIIigQyBWpFwSIEeA1ksAVUTDQoLBwWBZgM1EioVbjIdgSM+F4ENGwYFgR2BKIQ3Ixk2fIEJXoErKmEBEheBCYIKAoJwggYCAUlFDgkXCxgNSBEsNxQZBD5uB45RIIJLgQ4BK6YBgiGgHnEKKIN2jCGPPoV8GjOqbAuYfY4KhAmSR4RpgWg8gUcLB3AVgyIJShkPji0LC4NggX+CUcdpJzICCTIBAQcCBw4DC4FokACBfgEB IronPort-Data: A9a23:KIti2q6/BLVEHI6bhzuPLwxRtGvGchMFZxGqfqrLsTDasY5as4F+v mZLWmiOPPbZMGb8ftsnPoWy9xwFupXQzIdkSFdorSA0Zn8b8sCt6fZ1gavT04J+CuWZESqLO u1HMoGowPgcFyGa/lH2dOC98RGQ7InQLpLkEunIJyttcgFtTSYlmHpLlvUw6mJSqYDR7zil5 5Wo/qUzBHf/g2QqajJNuvrZwP9SlK2aVA0w7wRWic9j5Dcyp1FNZLoDKKe4KWfPQ4U8NoaSW +bZwbilyXjS9hErB8nNuu6TnpoiG+O60aCm0xK6aoD66vRwjnVaPpUTaJLwXXxqZwChxLid/ jniWauYEm/FNoWU8AgUvoIx/ytWZcWq85efSZSzXFD6I0DuKxPRL/tS4E4eZIs34txQAlt3/ /UnKgkBShqmnuKu+efuIgVsrpxLwMjDNYcbvDRkiDreF/tjGcCFSKTR7tge1zA17ixMNa+BP IxCN3w2MlKZP0An1lQ/UPrSmM+omnn2cDRCgFmUvqEwpWPUyWSd1ZC9aYqEIIzRG589ckCwh CHF8j7WIBchF8WZ0zS63kzxp+XFpHauMG4VPPjinhJwu3WU3mEVBRgcWFe3rPX8hkOgVtZ3L 00P5jFoqrA/8kGuRNTxUxC05nmesXYht8F4Guk+7kSJj6HT+QvcXjhCRT9aY9tgv8gzLdA36 mK0cxrSLWQHmNWopbi1qOzL9Fte5QB9wbc+WBI5 IronPort-HdrOrdr: A9a23:R5LmHKPws2LhD8BcThmjsMiBIKoaSvp037Dk7S9MoHtuA6ulfq +V/cjzuSWYtN9VYgBDpTniAtjlfZqjz/5ICOAqVN/INjUO+lHYSb2KhrGN/9SPIUHDH8dmpM FdmtBFeb7NJGk/q9rm6w+lFNtl6tyG/Ke0wdr69R5WPHhXg2UK1XYDNu5deXcGPDV7OQ== X-Talos-CUID: 9a23:axBnZWu/K02sodK3xFW1F1U96It8dFLF9lDTGXayAFlrcbGxQ3qJ+Ltdxp8= X-Talos-MUID: 9a23:RbT3Ng3xaSwM7AkhMWQSTwhNxjUjweetBRois5M9mNCCLyJPFwnArT69e9py X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.25,232,1779148800"; d="scan'208";a="818928362" Received: from alln-l-core-08.cisco.com ([173.36.16.145]) by alln-iport-1.cisco.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 20 Aug 2026 05:17:55 +0000 Received: from sjc-ads-5471.cisco.com (sjc-ads-5471.cisco.com [10.28.23.235]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "ciscoit-managed-infra-smtp-auth.cisco.com", Issuer "Internal Private TLS SubCA" (verified OK)) by alln-l-core-08.cisco.com (Postfix) with ESMTPS id AFBAD1802EB8A; Thu, 20 Aug 2026 05:16:33 +0000 (GMT) Received: by sjc-ads-5471.cisco.com (Postfix, from userid 1887505) id 18ED6CC12A6; Wed, 19 Aug 2026 22:16:33 -0700 (PDT) From: "Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" To: openembedded-devel@lists.openembedded.org Cc: xe-linux-external@cisco.com, Hetvi Thakar Subject: [meta-python][scarthgap][PATCH 2/4] python3-ujson: Fix CVE-2026-32874 Date: Wed, 19 Aug 2026 22:16:28 -0700 Message-Id: <20260820051630.63383-2-hthakar@cisco.com> X-Mailer: git-send-email 2.35.6 In-Reply-To: <20260820051630.63383-1-hthakar@cisco.com> References: <20260820051630.63383-1-hthakar@cisco.com> MIME-Version: 1.0 X-Auto-Response-Suppress: DR, OOF, AutoReply X-Outbound-Client-TLS: VERIFIED;sjc-ads-5471.cisco.com [10.28.23.235];TLSv1.3;TLS_AES_256_GCM_SHA384;256;ciscoit-managed-infra-smtp-auth.cisco.com X-Outbound-SMTP-Client: 10.28.23.235, sjc-ads-5471.cisco.com X-Outbound-Node: alln-l-core-08.cisco.com 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 ; Thu, 20 Aug 2026 05:21:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129376 From: Hetvi Thakar This patch applies the upstream fix referenced in [2], using the commit shown in [1]. [1] https://github.com/ultrajson/ultrajson/commit/4baeb950df780092bd3c89fc702a868e99a3a1d2 [2] https://nvd.nist.gov/vuln/detail/CVE-2026-32874 Signed-off-by: Hetvi Thakar --- .../python/python3-ujson/CVE-2026-32874.patch | 61 +++++++++++++++++++ .../python/python3-ujson_5.9.0.bb | 1 + 2 files changed, 62 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-ujson/CVE-2026-32874.patch diff --git a/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-32874.patch b/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-32874.patch new file mode 100644 index 0000000000..09730b9623 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-32874.patch @@ -0,0 +1,61 @@ +From cf988dbccb1b71cc1cb27c59ac73e09f3a68c3c1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Br=C3=A9nainn=20Woodsend?= +Date: Wed, 10 Dec 2025 22:37:20 +0000 +Subject: [PATCH] Fix memory leak parsing large integers + +CVE: CVE-2026-32874 +Upstream-Status: Backport [https://github.com/ultrajson/ultrajson/commit/4baeb950df780092bd3c89fc702a868e99a3a1d2] + +Backport Changes: +- Adjusted source paths for ujson 5.9.0's pre-src-layout tree. + +(cherry picked from commit 4baeb950df780092bd3c89fc702a868e99a3a1d2) +Signed-off-by: Hetvi Thakar +--- + python/JSONtoObj.c | 4 +++- + tests/test_ujson.py | 14 ++++++++++++++ + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/python/JSONtoObj.c b/python/JSONtoObj.c +index 208055c..93e87f3 100644 +--- a/python/JSONtoObj.c ++++ b/python/JSONtoObj.c +@@ -136,7 +136,9 @@ static JSOBJ Object_newIntegerFromString(void *prv, char *value, size_t length) + char *buf = PyObject_Malloc(length + 1); + memcpy(buf, value, length); + buf[length] = '\0'; +- return PyLong_FromString(buf, NULL, 10); ++ PyObject *ret = PyLong_FromString(buf, NULL, 10); ++ PyObject_Free(buf); ++ return ret; + } + + static JSOBJ Object_newDouble(void *prv, double value) +diff --git a/tests/test_ujson.py b/tests/test_ujson.py +index d24edb0..9ba6f55 100644 +--- a/tests/test_ujson.py ++++ b/tests/test_ujson.py +@@ -653,6 +653,20 @@ def test_encode_decode_big_int(i, mode): + assert ujson.decode(json_string) == python_object + + ++@pytest.mark.xfail( ++ sys.implementation.name == "pypy", ++ reason="PyPy's PyNumber_ToBase ignores sys.get_int_max_str_digits()", ++) ++def test_encode_too_big_int_error(): ++ with pytest.raises(ValueError, match="integer string conversion"): ++ ujson.dumps(pow(10, 10_000)) ++ ++ ++def test_decode_too_big_int_error(): ++ with pytest.raises(ValueError, match="integer string conversion"): ++ ujson.loads("9" * 10_000) ++ ++ + @pytest.mark.parametrize( + "test_input, expected", + [ +-- +2.35.6 + diff --git a/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb b/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb index c6b69790e8..8b970ee564 100644 --- a/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb +++ b/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb @@ -12,6 +12,7 @@ SRC_URI += " \ file://run-ptest \ file://0001-setup.py-Do-not-strip-debugging-symbols.patch \ file://CVE-2026-32875.patch \ + file://CVE-2026-32874.patch \ " DEPENDS += "python3-setuptools-scm-native" From patchwork Thu Aug 20 05:16:29 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" X-Patchwork-Id: 95857 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 9FDADC5DF81 for ; Thu, 20 Aug 2026 05:19:05 +0000 (UTC) Received: from alln-iport-5.cisco.com (alln-iport-5.cisco.com [173.37.142.92]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.613.1787203143110982831 for ; Wed, 19 Aug 2026 22:19:03 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: message contains an insecure body length tag" header.i=@cisco.com header.s=iport01 header.b=fE7b1wOx; spf=pass (domain: cisco.com, ip: 173.37.142.92, mailfrom: hthakar@cisco.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cisco.com; i=@cisco.com; l=4696; q=dns/txt; s=iport01; t=1787203143; x=1788412743; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wE42LMCFZwgsLzJNJ27Kh7hXxJ2UnTuIYFbiqHNWCKU=; b=fE7b1wOxs/Au7BLUf5Jdw19Aej9Z904U8/XlwwRVr7xu34m1CgtWw9Dj bPH0w/YecHy9gRYyuJDuTqmNHoYHuECIt1/fkDSZnDYZd1QKM1nbWvwv1 xqjHqB90tBzw2+nfhnQhDQ4H73N9nFZv/yzCGS2otnLV1NYX+aGdLV8fD x54Og7z4uBC9OsoXETLaPPSiu9OrsfwGXfrIbw08yPCjPsSeWi5iO7aYU cPyZYJr6y4zWb7prQV7JLJQ9bEzTHaJrEghjv4Sj6rZPKj44RJczQtY3c CJaOObTOhKSQnb2si325wpuus5EqL+fNetT8MWI8jBz/UltmEg8GMfTfp Q==; X-CSE-ConnectionGUID: 8zT0XGBFQkCHUsGkqUIVLg== X-CSE-MsgGUID: akniEXkYTLmUPbkJdkieJw== X-IPAS-Result: A0BIAgADjoZq/5QQJK1aHgEBCxIMggULgld0XkNJlkoDi2SSN4F+DwEBAQ9EDQQBAYQ/RgKNawImNAkOAQIEAwIDAQEBAQEBAQEBAQELAQEFAQEBAgEHBYEOE4ZPDYZaAQIBAzIBGAEtEBwDAQIvIAsjCBmDAgGCOgM3AxHCSIIsgQGDKAE/AkNQ2EsNglgBCxQBBYEzhT+Cf4UjXRgBhHwnGxuBcoEVg2mBBYEaQgEBiCUEgiKBDIFakXBIgR4DWSwBVRMNCgsHBYFmAzUSKhVuMh2BIz4XgQ0bBgWBHYEohDcjGTZ8gQlegSsqYQESF4EJggoCgnCCBgIBSUUOCRcLGA1IESw3FBkEPm4HjlEggksOdgoBK4IFdZJgCpI+gTWeaXEKKIN2jCGPPoV8GjOqbAuYfY4KhAmRal2EaYFoPIFHCwdwFYMiCUoZD44tCwuDYIF/yjonMgIJMgEBBwIHDgMLgWiRfgEB IronPort-Data: A9a23:1MvatqOER8w3+P3vrR32lsFynXyQoLVcMsEvi/4bfWQNrUp0g2RVz 2sWWW2GPP+JamujL9FzYdm+90IHu5/dn9JlGnM5pCpnJ55oRWUpJjg4wmPYZX76whjrFRo/h ykmQoCeaphyFTmE+kvF3oHJ9RFUzbuPSqf3FNnKMyVwQR4MYCo6gHqPocZh6mJTqYb/WV7lV e/a+ZWFZgf1gm8saAr41orawP9RlKWq0N8nlgRWicBj5Df2i3QTBZQDEqC9R1OQapVUBOOzW 9HYx7i/+G7Dlz91Yj9yuu+mGqGiaue60Tmm0hK6aYD76vRxjnBaPpIACRYpQRw/ZwNlMDxG4 I4lWZSYEW/FN0BX8QgXe0Ew/ypWZcWq9FJbSJSymZT78qHIT5fj66V8MBkGEqc2w+VcIVxV2 v8BFREzSh/W0opawJrjIgVtrs0nKM+uOMYUvWttiGiAS/0nWpvEBa7N4Le03h9p2ZsIRqiYP pRfMGY/BPjDS0Un1lM/CI4+leShnFH0ciZTrxSeoq9fD237nFUtgee1aIGNEjCMbcxWmEe1l mH3w0D8PykQN/6TyjuI0G3504cjmgu+Aur+DoaQ8eZnhlCWzGEfBBAaEFe2v/S9okq/QM5Eb UsM9ywjqKI/+ECmQp/6RRLQnZKflhcYX9wVF6gx7xuAj/ONpQ2YHWMDCDVGbbTKqfMLeNDj7 XfR9/uBONClmOfPFyr1Gmu8xd9qBRUoEA== IronPort-HdrOrdr: A9a23:99+KUK1PVZSzEcv/vWj1pgqjBGokLtp133Aq2lEZdPWaSKOlfq eV7ZMmPHDP6Qr5NEtMpTnEAtjjfZq+z+8Q3WBuB9eftWDd0QPCRr2Kr7GSpgEIcBeRygcy78 tdmoFFebvN5CBB/KXHyTj9Nco8y9+a963tr+Lfw3BxCTxOUchbnn5E4sLxKDwMeOGAbqBJbK ah2g== X-Talos-CUID: 9a23:wRRhC2EL7qt8pVjnqmI35nJMKu8PXETe51ftOGC7EFtIdpmaHAo= X-Talos-MUID: 9a23:Niht9gT2vhjKzl+hRXTlhzdjGfdr0piKDX01m5Ykt8qFOA5vbmI= X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.25,232,1779148800"; d="scan'208";a="814970030" Received: from alln-l-core-11.cisco.com ([173.36.16.148]) by alln-iport-5.cisco.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 20 Aug 2026 05:18:13 +0000 Received: from sjc-ads-5471.cisco.com (sjc-ads-5471.cisco.com [10.28.23.235]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "ciscoit-managed-infra-smtp-auth.cisco.com", Issuer "Internal Private TLS SubCA" (verified OK)) by alln-l-core-11.cisco.com (Postfix) with ESMTPS id C124418013BF3; Thu, 20 Aug 2026 05:16:35 +0000 (GMT) Received: by sjc-ads-5471.cisco.com (Postfix, from userid 1887505) id 5F3C2CC12A6; Wed, 19 Aug 2026 22:16:35 -0700 (PDT) From: "Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" To: openembedded-devel@lists.openembedded.org Cc: xe-linux-external@cisco.com, Hetvi Thakar Subject: [meta-python][scarthgap][PATCH 3/4] python3-ujson: Fix CVE-2026-44660 Date: Wed, 19 Aug 2026 22:16:29 -0700 Message-Id: <20260820051630.63383-3-hthakar@cisco.com> X-Mailer: git-send-email 2.35.6 In-Reply-To: <20260820051630.63383-1-hthakar@cisco.com> References: <20260820051630.63383-1-hthakar@cisco.com> MIME-Version: 1.0 X-Auto-Response-Suppress: DR, OOF, AutoReply X-Outbound-Client-TLS: VERIFIED;sjc-ads-5471.cisco.com [10.28.23.235];TLSv1.3;TLS_AES_256_GCM_SHA384;256;ciscoit-managed-infra-smtp-auth.cisco.com X-Outbound-SMTP-Client: 10.28.23.235, sjc-ads-5471.cisco.com X-Outbound-Node: alln-l-core-11.cisco.com 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 ; Thu, 20 Aug 2026 05:19:05 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129372 From: Hetvi Thakar This patch applies the upstream fix referenced in [2], using the commit shown in [1]. [1] https://github.com/ultrajson/ultrajson/commit/82af1d0ac01d09aa40c887b460d44b9d9f4bccd9 [2] https://nvd.nist.gov/vuln/detail/CVE-2026-44660 Signed-off-by: Hetvi Thakar --- .../python/python3-ujson/CVE-2026-44660.patch | 112 ++++++++++++++++++ .../python/python3-ujson_5.9.0.bb | 1 + 2 files changed, 113 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-ujson/CVE-2026-44660.patch diff --git a/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-44660.patch b/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-44660.patch new file mode 100644 index 0000000000..bfbaaf53b2 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-44660.patch @@ -0,0 +1,112 @@ +From 62fa316b5bdf9b2bb66efa60d1a17b38dc80f946 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Br=C3=A9nainn=20Woodsend?= +Date: Sun, 3 May 2026 12:22:48 +0100 +Subject: [PATCH] Fix failure cleanup paths in ujson.dump() + +* Add missing dec-refs for if PyTuple_Pack() or writing the payload to + file fails + +* Add missing bailout for failed PyTuple_Pack() + +* Add tests for all but the PyTuple_Pack() failing (which requires + inducing a malloc() failure) + +CVE: CVE-2026-44660 +Upstream-Status: Backport [https://github.com/ultrajson/ultrajson/commit/82af1d0ac01d09aa40c887b460d44b9d9f4bccd9] + +Backport Changes: +- Adjusted source paths for ujson 5.9.0's pre-src-layout tree. + +(cherry picked from commit 82af1d0ac01d09aa40c887b460d44b9d9f4bccd9) +Signed-off-by: Hetvi Thakar +--- + python/objToJSON.c | 7 +++++++ + tests/test_ujson.py | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 40 insertions(+) + +diff --git a/python/objToJSON.c b/python/objToJSON.c +index 9013205..47e46c1 100644 +--- a/python/objToJSON.c ++++ b/python/objToJSON.c +@@ -909,6 +909,11 @@ PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs) + } + + argtuple = PyTuple_Pack(1, data); ++ if (argtuple == NULL) ++ { ++ Py_XDECREF(write); ++ return NULL; ++ } + + string = objToJSON (self, argtuple, kwargs); + +@@ -925,6 +930,7 @@ PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs) + if (argtuple == NULL) + { + Py_XDECREF(write); ++ Py_DECREF(string); + return NULL; + } + +@@ -932,6 +938,7 @@ PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs) + if (write_result == NULL) + { + Py_XDECREF(write); ++ Py_DECREF(string); + Py_XDECREF(argtuple); + return NULL; + } +diff --git a/tests/test_ujson.py b/tests/test_ujson.py +index 9ba6f55..ccff37f 100644 +--- a/tests/test_ujson.py ++++ b/tests/test_ujson.py +@@ -8,6 +8,7 @@ import os.path + import re + import subprocess + import sys ++import types + import uuid + from collections import OrderedDict + from pathlib import Path +@@ -365,6 +366,38 @@ def test_dump_to_file_like_object(): + def test_dump_file_args_error(): + with pytest.raises(TypeError): + ujson.dump([], "") ++ with pytest.raises(TypeError): ++ ujson.dump([], "", "") ++ ++ ++def test_dump_non_callable_write(): ++ file = types.SimpleNamespace(write="a") ++ with pytest.raises(TypeError): ++ ujson.dump([7] * 100, file) ++ ++ ++def test_failed_dump(): ++ with pytest.raises(TypeError): ++ ujson.dump([[0] * 100, object()], io.StringIO()) ++ ++ ++def test_failed_dump_bogus_file(): ++ file = types.SimpleNamespace(write=lambda: None) ++ with pytest.raises(TypeError, match="0 positional arguments"): ++ ujson.dump([0] * 100, file) ++ ++ ++def test_failed_dump_failed_write(): ++ file = types.SimpleNamespace(write=lambda x: 1 / 0) ++ with pytest.raises(ZeroDivisionError): ++ ujson.dump([0] * 100, file) ++ ++ ++def test_failed_dump_closed_file(): ++ file = io.StringIO() ++ file.close() ++ with pytest.raises(ValueError, match="closed file"): ++ ujson.dump([0] * 100, file) + + + def test_load_file(): +-- +2.35.6 + diff --git a/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb b/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb index 8b970ee564..ed08ede1d9 100644 --- a/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb +++ b/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb @@ -13,6 +13,7 @@ SRC_URI += " \ file://0001-setup.py-Do-not-strip-debugging-symbols.patch \ file://CVE-2026-32875.patch \ file://CVE-2026-32874.patch \ + file://CVE-2026-44660.patch \ " DEPENDS += "python3-setuptools-scm-native" From patchwork Thu Aug 20 05:16:30 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" X-Patchwork-Id: 95859 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 83571C5DF85 for ; Thu, 20 Aug 2026 05:19:25 +0000 (UTC) Received: from alln-iport-7.cisco.com (alln-iport-7.cisco.com [173.37.142.94]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.616.1787203158686665360 for ; Wed, 19 Aug 2026 22:19:20 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: message contains an insecure body length tag" header.i=@cisco.com header.s=iport01 header.b=X5LSLPlw; spf=pass (domain: cisco.com, ip: 173.37.142.94, mailfrom: hthakar@cisco.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cisco.com; i=@cisco.com; l=12432; q=dns/txt; s=iport01; t=1787203160; x=1788412760; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cIGslw1Ah+d/xiOE+ZgL3jsujmCahOtWIaW6P7CPvy0=; b=X5LSLPlwQELvvpeAFOzCsQPNlOx7NlKpumC+NKyZpWMbK/0zqQkqeliT wyDsTx6eYzumaLS79FTo2mjSAv8iMc5F7JURIThHTU4RDTFkQxydkyaxb cH3Y/lG9dM+5+4lcaEhQUAuxy94l52E0xzYb2RwcuEfiwChNmBn3V8EeJ VIB4J3G4wB98z91725LWNTVmk0t26SaRiuCIqkjBxsm2XiJ7Hbe/ckJw+ TDHPa3A2AVhTKlyCkI5V9xlgHkI1q2bWWEYwOpcakUC/VCp+OMpSIxhRM BRFmkvMg2l85plwNcQ7w8PFyQJYdx3URm7yqy4HDtKprRX5yeAzNtzQrf Q==; X-CSE-ConnectionGUID: zxblw8TaRtuRCgZhwzYIvw== X-CSE-MsgGUID: 4XbrECRyQUq55MZlpMcQAg== X-IPAS-Result: A0BIAgAHjYZq/4wQJK1aHgEBCxIMggULgld0XkNJlkoDi2SSN4F+DwEBAQ9EDQQBAYQ/RgKNawImNAkOAQIEAwIDAQEBAQEBAQEBAQELAQEFAQEBAgEHBYEOE4ZPDYZaAQIBAycLARgBLRAcAwECLyALIwgZgwIBgjoDNwMRwl2BeTOBAYMoAT8CQ1DYSw2CWAELFAEFgTOFP4J/hSNdGAGEfCcbG4FyglCCLoEFgRpCAQECAYgiBIIigQyBWh6RUkiBHgNZLAFVEw0KCwcFgWYDNRIqFW4yHYEjPheBDRsGBYEdgSiENyMZNnyBCV6BKyphARIXgQmCCgKCcIIGAgFJRQ4JFwsYDUgRLDcUGQQ+bgeOUSCCRAcBLCYoEwErF4Ftph6gHnEKKIN2jCGPPoV8GjOqbAuYfY4KhAmRal2EaYFoPIFHCwdwFYMiCUoZD44qAwsLg2CBf4MUxyYnMgIJMgEBBwIHDgMLgWiQAi2BTwEB IronPort-Data: A9a23:fvNqMaw4VfRq74/7dRl6t+dnxyrEfRIJ4+MujC+fZmUNrF6WrkUAn GMXDWuPM/reYDSnfdglYImx8EgEscTVzNAyS1Rkq1hgHilAwSbn6Xt1DatR0we6dJCroJdPt p1GAjX4BJlqCCea/VH1buSJQUBUjcmgXqD7BPPPJhd/TAplTDZJoR94kobVuKYw6TSCK13L4 46aT/H3Ygf/hWYkazNMscpvlTs21BjMkGJA1rABTagjUG/2zxE9EJ8ZLKetGHr0KqE8NvK6X evK0Iai9Wrf+Ro3Yvv9+losWhRXKlJ6FVHmZkt+A8BOsDAbzsAB+vpT2M4nVKtio27hc+adZ zl6ncfYpQ8BZsUgkQmGOvVSO3kW0aZuoNcrLZUj2CCe5xWuTpfi/xlhJFMmN4kHqtp+O31Tz 9cXGjASfCGimf3jldpXSsE07igiBMDvOIVavjRryivUSK59B5vCWK7No9Rf2V/chOgXQq2YP JRfMGQpNUiYC/FMEg9/5JYWnPuoj3r2aRVTqUmeouw85G27IAlZgOG3YYKEKoTXLSlTthqor Hjr1F7oOywDaYG6+z6d13mVr+CayEsXX6pXTtVU7MVCh0WewGEWAhAaWVa35PW0lEO6c9ZeM FAPvC02oK4/8UamQtXwU1u/unHsg/IHc9NUF+t/7ESGzbDZpl7CQGMFVTVGLtchsafaWAAX6 7NApPuxbRQHjVFfYSLCrt94cRva1fApEFI/ IronPort-HdrOrdr: A9a23:ju1Zc6wcbVPaaGHeoU3TKrPw9L1zdoMgy1knxilNoNJuHfBw8P re+8jzuiWUtN98YhwdcJW7Scu9qBDnhPpICPcqXYtKNTOO0ADDEGgh1/qG/9SKIUPDH4BmuZ uIWpIObuEYdWIK7vrS0U2fD8sqxsWB/eSDgOfTyGoocCRRApsQljuQzm2gYzZLrM4sP+tAKK ah X-Talos-CUID: 9a23:gDzoGWg45rNP9GdNJ7uIkNc36jJuYG3XyGiAH0aCFXtTY7KnSUCCyYJ6jJ87 X-Talos-MUID: 9a23:Ai4UUgjAHthikQdXLrVt9cMpaPdi+YmFMlE0rIxb5uy2MTRVMA60g2Hi X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.25,232,1779148800"; d="scan'208";a="812909805" Received: from alln-l-core-03.cisco.com ([173.36.16.140]) by alln-iport-7.cisco.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 20 Aug 2026 05:18:40 +0000 Received: from sjc-ads-5471.cisco.com (sjc-ads-5471.cisco.com [10.28.23.235]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "ciscoit-managed-infra-smtp-auth.cisco.com", Issuer "Internal Private TLS SubCA" (verified OK)) by alln-l-core-03.cisco.com (Postfix) with ESMTPS id 612B8180079BD; Thu, 20 Aug 2026 05:16:36 +0000 (GMT) Received: by sjc-ads-5471.cisco.com (Postfix, from userid 1887505) id 07104CC12A6; Wed, 19 Aug 2026 22:16:36 -0700 (PDT) From: "Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" To: openembedded-devel@lists.openembedded.org Cc: xe-linux-external@cisco.com, Hetvi Thakar Subject: [meta-python][scarthgap][PATCH 4/4] python3-ujson: Fix CVE-2026-54911 Date: Wed, 19 Aug 2026 22:16:30 -0700 Message-Id: <20260820051630.63383-4-hthakar@cisco.com> X-Mailer: git-send-email 2.35.6 In-Reply-To: <20260820051630.63383-1-hthakar@cisco.com> References: <20260820051630.63383-1-hthakar@cisco.com> MIME-Version: 1.0 X-Auto-Response-Suppress: DR, OOF, AutoReply X-Outbound-Client-TLS: VERIFIED;sjc-ads-5471.cisco.com [10.28.23.235];TLSv1.3;TLS_AES_256_GCM_SHA384;256;ciscoit-managed-infra-smtp-auth.cisco.com X-Outbound-SMTP-Client: 10.28.23.235, sjc-ads-5471.cisco.com X-Outbound-Node: alln-l-core-03.cisco.com 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 ; Thu, 20 Aug 2026 05:19:25 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/129374 From: Hetvi Thakar This patch applies the upstream fix referenced in [2], using the commit shown in [1]. [1] https://github.com/ultrajson/ultrajson/commit/169eaf36b1116fece5034ee79a7a0ef3f6deedcf [2] https://nvd.nist.gov/vuln/detail/CVE-2026-54911 Signed-off-by: Hetvi Thakar --- .../python/python3-ujson/CVE-2026-54911.patch | 267 ++++++++++++++++++ .../python/python3-ujson_5.9.0.bb | 1 + 2 files changed, 268 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-ujson/CVE-2026-54911.patch diff --git a/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-54911.patch b/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-54911.patch new file mode 100644 index 0000000000..c7c14066d4 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-ujson/CVE-2026-54911.patch @@ -0,0 +1,267 @@ +From 92a7b67d7b6155c2e3bc225fa0238ea35249bb36 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Br=C3=A9nainn=20Woodsend?= +Date: Fri, 24 Apr 2026 21:59:45 +0100 +Subject: [PATCH] More UTF-8 validation for ujson.dumps(b"...", + reject_bytes=False) + +* Fix off by one errors in detecting end of string mid sequence +* Add missing check for codepoints > max unicode +* Add missing check for bad continuation bytes + +CVE: CVE-2026-54911 +Upstream-Status: Backport [https://github.com/ultrajson/ultrajson/commit/169eaf36b1116fece5034ee79a7a0ef3f6deedcf] + +Backport Changes: +- Adjusted source paths for ujson 5.9.0's pre-src-layout tree. +- Relocated regression tests to the matching section of the 5.9.0 test suite. +- Added the `random` import required by the backported fuzz regression test; + newer upstream already imports it, while ujson 5.9.0 does not. + +(cherry picked from commit 169eaf36b1116fece5034ee79a7a0ef3f6deedcf) +Signed-off-by: Hetvi Thakar +--- + lib/ultrajsondec.c | 6 ++-- + lib/ultrajsonenc.c | 46 ++++++++++++++++++++++----- + tests/test_ujson.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 118 insertions(+), 10 deletions(-) + +diff --git a/lib/ultrajsondec.c b/lib/ultrajsondec.c +index bccb0aa..5583376 100644 +--- a/lib/ultrajsondec.c ++++ b/lib/ultrajsondec.c +@@ -531,7 +531,7 @@ static FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds + return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'"); + } + ucs |= (*inputOffset++) & 0x3f; +- if (ucs < 0x80) return SetError (ds, -1, "Overlong 2 byte UTF-8 sequence detected when decoding 'string'"); ++ if (ucs < 0x80) return SetError (ds, -1, "Overlong 2-byte UTF-8 sequence detected when decoding 'string'"); + *(escOffset++) = (JSUINT32) ucs; + break; + } +@@ -554,7 +554,7 @@ static FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds + ucs |= oct & 0x3f; + } + +- if (ucs < 0x800) return SetError (ds, -1, "Overlong 3 byte UTF-8 sequence detected when encoding string"); ++ if (ucs < 0x800) return SetError (ds, -1, "Overlong 3-byte UTF-8 sequence detected when encoding string"); + *(escOffset++) = (JSUINT32) ucs; + break; + } +@@ -577,7 +577,7 @@ static FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds + ucs |= oct & 0x3f; + } + +- if (ucs < 0x10000) return SetError (ds, -1, "Overlong 4 byte UTF-8 sequence detected when decoding 'string'"); ++ if (ucs < 0x10000) return SetError (ds, -1, "Overlong 4-byte UTF-8 sequence detected when decoding 'string'"); + + *(escOffset++) = (JSUINT32) ucs; + break; +diff --git a/lib/ultrajsonenc.c b/lib/ultrajsonenc.c +index 0f9fde3..5bafd52 100644 +--- a/lib/ultrajsonenc.c ++++ b/lib/ultrajsonenc.c +@@ -347,17 +347,24 @@ static int Buffer_EscapeStringValidated (JSOBJ obj, JSONObjectEncoder *enc, cons + continue; + } + ++ // https://en.wikipedia.org/wiki/UTF-8#Description + case 2: + { + JSUTF32 in; + JSUTF16 in16; + +- if (end - io < 1) ++ if (end - io < 2) + { + enc->offset += (of - enc->offset); + SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string"); + return FALSE; + } ++ if ((io[1] & 0xc0) != 0x80) ++ { ++ enc->offset += (of - enc->offset); ++ SetError (obj, enc, "Invalid continuation byte in 2-byte UTF-8 sequence detected when encoding string"); ++ return FALSE; ++ } + + memcpy(&in16, io, sizeof(JSUTF16)); + in = (JSUTF32) in16; +@@ -371,7 +378,7 @@ static int Buffer_EscapeStringValidated (JSOBJ obj, JSONObjectEncoder *enc, cons + if (ucs < 0x80) + { + enc->offset += (of - enc->offset); +- SetError (obj, enc, "Overlong 2 byte UTF-8 sequence detected when encoding string"); ++ SetError (obj, enc, "Overlong 2-byte UTF-8 sequence detected when encoding string"); + return FALSE; + } + +@@ -385,13 +392,26 @@ static int Buffer_EscapeStringValidated (JSOBJ obj, JSONObjectEncoder *enc, cons + JSUTF16 in16; + JSUINT8 in8; + +- if (end - io < 2) ++ if (end - io < 3) + { + enc->offset += (of - enc->offset); + SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string"); + return FALSE; + } +- ++ if ((io[1] & 0xc0) != 0x80 || (io[2] & 0xc0) != 0x80) ++ { ++ enc->offset += (of - enc->offset); ++ SetError (obj, enc, "Invalid continuation byte in 3-byte UTF-8 sequence detected when encoding string"); ++ return FALSE; ++ } ++ // Under normal UTF-8 decoding rules, UTF-16 surrogates should also be disallowed ++ // but in JSON, they're special cased and rewritten later as \udc7f. ++ // if ((JSUINT8) io[0] == 0xed && (JSUINT8) io[1] >= 0xa0) ++ // { ++ // enc->offset += (of - enc->offset); ++ // SetError (obj, enc, "Illegal UTF-16 surrogate in 3-byte UTF-8 sequence detected when encoding string"); ++ // return FALSE; ++ // } + memcpy(&in16, io, sizeof(JSUTF16)); + memcpy(&in8, io + 2, sizeof(JSUINT8)); + #ifdef __LITTLE_ENDIAN__ +@@ -407,7 +427,7 @@ static int Buffer_EscapeStringValidated (JSOBJ obj, JSONObjectEncoder *enc, cons + if (ucs < 0x800) + { + enc->offset += (of - enc->offset); +- SetError (obj, enc, "Overlong 3 byte UTF-8 sequence detected when encoding string"); ++ SetError (obj, enc, "Overlong 3-byte UTF-8 sequence detected when encoding string"); + return FALSE; + } + +@@ -418,12 +438,24 @@ static int Buffer_EscapeStringValidated (JSOBJ obj, JSONObjectEncoder *enc, cons + { + JSUTF32 in; + +- if (end - io < 3) ++ if (end - io < 4) + { + enc->offset += (of - enc->offset); + SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string"); + return FALSE; + } ++ if ((io[1] & 0xc0) != 0x80 || (io[2] & 0xc0) != 0x80 || (io[3] & 0xc0) != 0x80) ++ { ++ enc->offset += (of - enc->offset); ++ SetError (obj, enc, "Invalid continuation byte in 4-byte UTF-8 sequence detected when encoding string"); ++ return FALSE; ++ } ++ if (((JSUINT8) io[0] >= 0xf4 && (JSUINT8) io[1] >= 0x90) || (JSUINT8) io[0] >= 0xf5) ++ { ++ enc->offset += (of - enc->offset); ++ SetError (obj, enc, ">U+10FFFF in 4-byte UTF-8 sequence detected when encoding string"); ++ return FALSE; ++ } + + memcpy(&in, io, sizeof(JSUTF32)); + #ifdef __LITTLE_ENDIAN__ +@@ -434,7 +466,7 @@ static int Buffer_EscapeStringValidated (JSOBJ obj, JSONObjectEncoder *enc, cons + if (ucs < 0x10000) + { + enc->offset += (of - enc->offset); +- SetError (obj, enc, "Overlong 4 byte UTF-8 sequence detected when encoding string"); ++ SetError (obj, enc, "Overlong 4-byte UTF-8 sequence detected when encoding string"); + return FALSE; + } + +diff --git a/tests/test_ujson.py b/tests/test_ujson.py +index ccff37f..9024dac 100644 +--- a/tests/test_ujson.py ++++ b/tests/test_ujson.py +@@ -5,6 +5,7 @@ import io + import json + import math + import os.path ++import random + import re + import subprocess + import sys +@@ -1053,6 +1053,81 @@ def test_reject_bytes_false(): + assert ujson.dumps(data, reject_bytes=False) == '{"a":"b"}' + + ++@pytest.mark.parametrize( ++ "codepoint", ++ [0x0, 0x7F, 0x80, 0x7FF, 0x800, 0xFFFF, 0x10000, 0x10FFFF], ++) ++def test_reject_bytes_false_codepoint_boundaries(codepoint): ++ char = chr(codepoint) ++ assert ujson.loads(ujson.dumps(char.encode(), reject_bytes=False)) == char ++ ++ ++@pytest.mark.parametrize( ++ "value, error", ++ [ ++ # Bad start bytes ++ (b"\xfd", "Unsupported UTF-8 sequence length when encoding string"), ++ (b"\xfc:", "Unsupported UTF-8 sequence length when encoding string"), ++ (b"U>\xfb", "Unsupported UTF-8 sequence length when encoding string"), ++ (b"\\\xf8\x98\t", "Unsupported UTF-8 sequence length when encoding string"), ++ (b"\x9b", "'utf-8' codec can't decode byte 0x9b in position 1:"), ++ (b"B\x8a", "'utf-8' codec can't decode byte 0x8a in position 2:"), ++ # Bad continuation bytes (any non-start byte not matching 0b10xx_xxxx) ++ (b"\xcf\x13", "Invalid continuation byte in 2-byte UTF-8 sequence"), ++ (b"\xcfa", "Invalid continuation byte in 2-byte UTF-8 sequence"), ++ (b"\xd8\xcf\xd3", "Invalid continuation byte in 2-byte UTF-8 sequence"), ++ (b"\xd2\t\x8b\x84", "Invalid continuation byte in 2-byte UTF-8 sequence"), ++ (b"\xe2\x17\xce", "Invalid continuation byte in 3-byte UTF-8 sequence"), ++ (b"\xe2a\x17\xce", "Invalid continuation byte in 3-byte UTF-8 sequence"), ++ (b"\xe2\x17a", "Invalid continuation byte in 3-byte UTF-8 sequence"), ++ (b"\xe0\x9c\xc6\xde", "Invalid continuation byte in 3-byte UTF-8 sequence"), ++ (b"\xf0H\xce\x9b", "Invalid continuation byte in 4-byte UTF-8 sequence"), ++ (b"\xf0\xce4\x9b", "Invalid continuation byte in 4-byte UTF-8 sequence"), ++ # Truncated UTF-8 sequences ++ (b"\xc3", "Unterminated UTF-8 sequence when encoding string"), ++ (b"\x8c$\xe3", "Unterminated UTF-8 sequence when encoding string"), ++ (b"\x8c\xe3$", "Unterminated UTF-8 sequence when encoding string"), ++ (b"=\x8c\xe36", "Unterminated UTF-8 sequence when encoding string"), ++ (b"\x08\x11\xe3", "Unterminated UTF-8 sequence when encoding string"), ++ (b"\xf0\x90\x94", "Unterminated UTF-8 sequence when encoding string"), ++ # Small codepoints using longer byte sequences than they need ++ (b"\xc0\xa2", "Overlong 2-byte UTF-8 sequence"), ++ (b"A\xc1\x9c", "Overlong 2-byte UTF-8 sequence"), ++ (b"\xc1\xbf", "Overlong 2-byte UTF-8 sequence"), ++ (b"N\xc0\xb4\xb4", "Overlong 2-byte UTF-8 sequence"), ++ (b"\xe0\x9d\xb3", "Overlong 3-byte UTF-8 sequence"), ++ (b"E\xe0\x9e\x8b", "Overlong 3-byte UTF-8 sequence"), ++ (b"\xe0\x9f\xbf", "Overlong 3-byte UTF-8 sequence"), ++ (b"\xf0\x80\x80\x80", "Overlong 4-byte UTF-8 sequence"), ++ (b"\xf0\x8f\xbf\xbf", "Overlong 4-byte UTF-8 sequence"), ++ (b"\xf0\x85\xa7\xbd", "Overlong 4-byte UTF-8 sequence"), ++ # Codepoints above unicode max ++ (b"\xf4\x90\x80\x80", r">U\+10FFFF in 4-byte UTF-8 sequence"), ++ (b"\xf7\x8f\x99\x90", r">U\+10FFFF in 4-byte UTF-8 sequence"), ++ (b"\xf7\xbf\xbf\xbf", r">U\+10FFFF in 4-byte UTF-8 sequence"), ++ ], ++) ++def test_dump_bytes_invalid_utf8(value, error): ++ with pytest.raises((OverflowError, UnicodeDecodeError), match=error): ++ ujson.dumps(bytes(value), reject_bytes=False) ++ ++ ++def test_dump_bytes_fuzz(): ++ # ujson.dumps(..., reject_bytes=False) should accept or reject the same byte ++ # sequences as b"...".decode() when unpaired surrogates are allowed ++ for seed in range(10000): ++ r = random.Random(seed) ++ a = r.randbytes(r.randrange(8)) ++ try: ++ expected = a.decode(errors="surrogatepass") ++ except UnicodeDecodeError: ++ with pytest.raises((UnicodeDecodeError, OverflowError)): ++ ujson.dumps(a, reject_bytes=False) ++ else: ++ actual = ujson.loads(ujson.dumps(a, reject_bytes=False)) ++ assert actual == expected, (a, [bin(i) for i in a], actual, expected) ++ ++ + def test_encode_special_keys(): + data = {None: 0, True: 1, False: 2} + assert ujson.dumps(data) == '{"null":0,"true":1,"false":2}' +-- +2.35.6 + diff --git a/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb b/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb index ed08ede1d9..bd1f06acf9 100644 --- a/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb +++ b/meta-python/recipes-devtools/python/python3-ujson_5.9.0.bb @@ -14,6 +14,7 @@ SRC_URI += " \ file://CVE-2026-32875.patch \ file://CVE-2026-32874.patch \ file://CVE-2026-44660.patch \ + file://CVE-2026-54911.patch \ " DEPENDS += "python3-setuptools-scm-native"