Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions SPECS/python-msgpack/CVE-2026-57585.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
From 2c56ddb5d0025ed481d962c0f5d62d19dec7476d Mon Sep 17 00:00:00 2001
From: Inada Naoki <songofacandy@gmail.com>
Date: Fri, 19 Jun 2026 00:13:13 +0900
Subject: [PATCH] Merge commit from fork

* fix Unpacker crash after unpack failure.

* fixup

Upstream Patch reference: https://github.com/msgpack/msgpack-python/commit/2c56ddb5d0025ed481d962c0f5d62d19dec7476d.patch
---
msgpack/_unpacker.pyx | 8 ++++++--
msgpack/unpack_template.h | 28 ++++++++++++++++++++++++----
requirements.txt | 9 ++++-----
test/test_except.py | 26 ++++++++++++++++++++++++++
4 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/msgpack/_unpacker.pyx b/msgpack/_unpacker.pyx
index 8b06661..3db94a3 100644
--- a/msgpack/_unpacker.pyx
+++ b/msgpack/_unpacker.pyx
@@ -53,6 +53,7 @@ cdef extern from "unpack.h":
execute_fn unpack_skip
execute_fn read_array_header
execute_fn read_map_header
+
void unpack_init(unpack_context* ctx)
object unpack_data(unpack_context* ctx)
void unpack_clear(unpack_context* ctx)
@@ -200,6 +201,7 @@ def unpackb(object packed, *, object object_hook=None, object list_hook=None,
if off < buf_len:
raise ExtraData(obj, PyBytes_FromStringAndSize(buf+off, buf_len-off))
return obj
+
unpack_clear(&ctx)
if ret == 0:
raise ValueError("Unpack failed: incomplete input")
@@ -469,7 +471,7 @@ cdef class Unpacker(object):
obj = unpack_data(&self.ctx)
unpack_init(&self.ctx)
return obj
- elif ret == 0:
+ if ret == 0:
if self.file_like is not None:
self.read_from_file()
continue
@@ -477,7 +479,9 @@ cdef class Unpacker(object):
raise StopIteration("No more data to unpack.")
else:
raise OutOfData("No more data to unpack.")
- elif ret == -2:
+
+ unpack_clear(&self.ctx)
+ if ret == -2:
raise FormatError
elif ret == -3:
raise StackError
diff --git a/msgpack/unpack_template.h b/msgpack/unpack_template.h
index 8b9fcc1..9090000 100644
--- a/msgpack/unpack_template.h
+++ b/msgpack/unpack_template.h
@@ -72,7 +72,14 @@ static inline PyObject* unpack_data(unpack_context* ctx)

static inline void unpack_clear(unpack_context *ctx)
{
- Py_CLEAR(ctx->stack[0].obj);
+ for (unsigned int i = 0; i < ctx->top; i++) {
+ /* map_key holds a live reference only while waiting for the value */
+ if (ctx->stack[i].ct == CT_MAP_VALUE) {
+ Py_CLEAR(ctx->stack[i].map_key);
+ }
+ Py_CLEAR(ctx->stack[i].obj);
+ }
+ unpack_init(ctx);
}

template <bool construct>
@@ -193,7 +200,7 @@ static inline int unpack_execute(unpack_context* ctx, const char* data, Py_ssize
case 0xd5: // fixext 2
case 0xd6: // fixext 4
case 0xd7: // fixext 8
- again_fixed_trail_if_zero(ACS_EXT_VALUE,
+ again_fixed_trail_if_zero(ACS_EXT_VALUE,
(1 << (((unsigned int)*p) & 0x03))+1,
_ext_zero);
case 0xd8: // fixext 16
@@ -337,6 +344,7 @@ _push:
goto _header_again;
case CT_MAP_VALUE:
if(construct_cb(_map_item)(user, c->count, &c->obj, c->map_key, obj) < 0) { goto _failed; }
+ c->map_key = NULL;
if(++c->count == c->size) {
obj = c->obj;
if (construct_cb(_map_end)(user, &obj) < 0) { goto _failed; }
@@ -454,8 +462,20 @@ static inline int unpack_container_header(unpack_context* ctx, const char* data,
#undef SWITCH_RANGE_DEFAULT
#undef SWITCH_RANGE_END

-static const execute_fn unpack_construct = &unpack_execute<true>;
-static const execute_fn unpack_skip = &unpack_execute<false>;
+static int unpack_construct(unpack_context *ctx, const char *data, Py_ssize_t len, Py_ssize_t *off) {
+ int ret = unpack_execute(1, ctx, data, len, off);
+ if (ret == -1) {
+ unpack_clear(ctx);
+ }
+ return ret;
+}
+static int unpack_skip(unpack_context *ctx, const char *data, Py_ssize_t len, Py_ssize_t *off) {
+ int ret = unpack_execute(0, ctx, data, len, off);
+ if (ret == -1) {
+ unpack_clear(ctx);
+ }
+ return ret;
+}
static const execute_fn read_array_header = &unpack_container_header<0x90, 0xdc>;
static const execute_fn read_map_header = &unpack_container_header<0x80, 0xde>;

diff --git a/requirements.txt b/requirements.txt
index 9f3c1a0..7991e3f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,4 @@
-# Also declared in pyproject.toml, if updating here please also update there
-Cython~=0.29.30
-
-# dev only tools. no need to add pyproject
-black==22.3.0
+cython==3.2.5
+setuptools==78.1.1
+pytest
+build
diff --git a/test/test_except.py b/test/test_except.py
index 5544f2b..facdd75 100644
--- a/test/test_except.py
+++ b/test/test_except.py
@@ -31,6 +31,22 @@ def test_raise_from_object_hook():
object_pairs_hook=hook,
)

+ up = Unpacker(object_hook=hook)
+
+ def up_unpack(x):
+ up.feed(x)
+ return up.unpack()
+
+ raises(DummyException, up_unpack, packb({}))
+ raises(DummyException, up_unpack, packb({"fizz": "buzz"}))
+ raises(DummyException, up_unpack, packb({"fizz": "buzz"}))
+ raises(DummyException, up_unpack, packb({"fizz": {"buzz": "spam"}}))
+ raises(
+ DummyException,
+ up_unpack,
+ packb({"fizz": {"buzz": "spam"}}),
+ )
+

def test_invalidvalue():
incomplete = b"\xd9\x97#DL_" # raw8 - length=0x97
@@ -61,3 +77,13 @@ def test_strict_map_key():
packed = packb(invalid, use_bin_type=True)
with raises(ValueError):
unpackb(packed, raw=False, strict_map_key=True)
+
+
+def test_unpacker_should_not_crash_after_exception():
+ up = Unpacker() # default: strict_map_key=True
+ up.feed(b"\x83\x73\xc4\x00") # fixmap(3): int key (rejected) + empty bin8
+ try:
+ up.unpack() # ValueError: int is not allowed for map key ...
+ except Exception:
+ pass
+ up.skip() # SIGSEGV (resumes from a corrupt parser context)
--
2.43.0

8 changes: 6 additions & 2 deletions SPECS/python-msgpack/python-msgpack.spec
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
Summary: MessagePack (de)serializer.
Name: python-msgpack
Version: 1.0.5
Release: 2%{?dist}
Release: 3%{?dist}
License: ASL 2.0
Vendor: Microsoft Corporation
Distribution: Azure Linux
Group: Development/Languages/Python
URL: https://msgpack.org/
Source0: https://github.com/msgpack/msgpack-python/archive/v%{version}.tar.gz#/msgpack-python-%{version}.tar.gz
Patch0: CVE-2026-57585.patch
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-Cython
Expand All @@ -28,7 +29,7 @@ Requires: python3
MessagePack is a fast, compact binary serialization format, suitable for similar data to JSON. This package provides CPython bindings for reading and writing MessagePack data.

%prep
%autosetup -n msgpack-python-%{version}
%autosetup -p1 -n msgpack-python-%{version}

%build
%py3_build
Expand All @@ -45,6 +46,9 @@ MessagePack is a fast, compact binary serialization format, suitable for similar
%{python3_sitelib}/*

%changelog
* Fri Jul 03 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 1.0.5-3
- Patch for CVE-2026-57585

* Tue Apr 29 2025 Riken Maharjan <rmaharjan@microsoft.com> - 1.0.5-2
- Use pytest instead of tox to fix the ptest

Expand Down
Loading