[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