[meta-python][scarthgap][PATCH 3/4] python3-ujson: Fix CVE-2026-44660

"Hetvi Thakar -X (hthakar - E INFOCHIPS PRIVATE LIMITED at Cisco)" <[email protected]>
Newsgroups org.openembedded.lists.openembedded-devel
Message-ID <[email protected]>
From: Hetvi Thakar <[email protected]>

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 <[email protected]>
---
 .../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?= <[email protected]>
+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 <[email protected]>
+---
+ 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"
-- 
2.35.6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.