Skip to content

Commit 70dc639

Browse files
[High] patch mysql for CVE-2026-0994 (#15768)
Co-authored-by: jslobodzian <joslobo@microsoft.com>
1 parent c59c90f commit 70dc639

2 files changed

Lines changed: 178 additions & 1 deletion

File tree

SPECS/mysql/CVE-2026-0994.patch

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
From 5ebddcb1bcbe51d1fe323baa145e85f4f23128cf Mon Sep 17 00:00:00 2001
2+
From: zhangskz <sandyzhang@google.com>
3+
Date: Thu, 29 Jan 2026 16:32:56 -0500
4+
Subject: [PATCH] Fix Any recursion depth bypass in Python
5+
json_format.ParseDict (#25239) (#25587)
6+
7+
This fixes a security vulnerability where nested google.protobuf.Any messages could bypass the max_recursion_depth limit, potentially leading to denial of service via stack overflow.
8+
9+
The root cause was that _ConvertAnyMessage() was calling itself recursively via methodcaller() for nested well-known types, bypassing the recursion depth tracking in ConvertMessage().
10+
11+
The fix routes well-known type parsing through ConvertMessage() to ensure proper recursion depth accounting for all message types including nested Any.
12+
13+
Fixes #25070
14+
15+
Closes #25239
16+
17+
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/25239 from aviralgarg05:fix-any-recursion-depth-bypass 3cbbcbea142593d3afd2ceba2db14b05660f62f4
18+
PiperOrigin-RevId: 862740421
19+
20+
Co-authored-by: Aviral Garg <gargaviral99@gmail.com>
21+
22+
Upstream Patch Reference: https://github.com/protocolbuffers/protobuf/commit/5ebddcb1bcbe51d1fe323baa145e85f4f23128cf.patch
23+
---
24+
.../protobuf/internal/json_format_test.py | 102 ++++++++++++++++++
25+
.../python/google/protobuf/json_format.py | 12 ++-
26+
2 files changed, 111 insertions(+), 3 deletions(-)
27+
28+
diff --git a/extra/protobuf/protobuf-24.4/python/google/protobuf/internal/json_format_test.py b/extra/protobuf/protobuf-24.4/python/google/protobuf/internal/json_format_test.py
29+
index b4f516d8..d2967801 100644
30+
--- a/extra/protobuf/protobuf-24.4/python/google/protobuf/internal/json_format_test.py
31+
+++ b/extra/protobuf/protobuf-24.4/python/google/protobuf/internal/json_format_test.py
32+
@@ -1297,6 +1297,108 @@ class JsonFormatTest(JsonFormatBase):
33+
# The following one can pass
34+
json_format.Parse('{"payload": {}, "child": {"child":{}}}',
35+
message, max_recursion_depth=3)
36+
+
37+
+ def testAnyRecursionDepthEnforcement(self):
38+
+ """Test that nested Any messages respect max_recursion_depth limit."""
39+
+ # Test that deeply nested Any messages raise ParseError instead of
40+
+ # bypassing the recursion limit. This prevents DoS via nested Any.
41+
+ message = any_pb2.Any()
42+
+
43+
+ # Create nested Any structure that should exceed depth limit
44+
+ # With max_recursion_depth=5, we can nest 4 Any messages
45+
+ # (depth 1 = outer Any, depth 2-4 = nested Anys, depth 5 = final value)
46+
+ nested_any = {
47+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
48+
+ 'value': {
49+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
50+
+ 'value': {
51+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
52+
+ 'value': {
53+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
54+
+ 'value': {
55+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
56+
+ 'value': {},
57+
+ },
58+
+ },
59+
+ },
60+
+ },
61+
+ }
62+
+
63+
+ # Should raise ParseError due to exceeding max depth, not RecursionError
64+
+ self.assertRaisesRegex(
65+
+ json_format.ParseError,
66+
+ 'Message too deep. Max recursion depth is 5',
67+
+ json_format.ParseDict,
68+
+ nested_any,
69+
+ message,
70+
+ max_recursion_depth=5,
71+
+ )
72+
+
73+
+ # Verify that Any messages within the limit can be parsed successfully
74+
+ # With max_recursion_depth=5, we can nest up to 4 Any messages
75+
+ shallow_any = {
76+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
77+
+ 'value': {
78+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
79+
+ 'value': {
80+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
81+
+ 'value': {
82+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
83+
+ 'value': {},
84+
+ },
85+
+ },
86+
+ },
87+
+ }
88+
+ json_format.ParseDict(shallow_any, message, max_recursion_depth=5)
89+
+
90+
+ def testAnyRecursionDepthBoundary(self):
91+
+ """Test recursion depth boundary behavior (exclusive upper limit)."""
92+
+ message = any_pb2.Any()
93+
+
94+
+ # Create nested Any at depth exactly 4 (should succeed with max_recursion_depth=5)
95+
+ depth_4_any = {
96+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
97+
+ 'value': {
98+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
99+
+ 'value': {
100+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
101+
+ 'value': {
102+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
103+
+ 'value': {},
104+
+ },
105+
+ },
106+
+ },
107+
+ }
108+
+ # This should succeed: depth 4 < max_recursion_depth 5
109+
+ json_format.ParseDict(depth_4_any, message, max_recursion_depth=5)
110+
+
111+
+ # Create nested Any at depth exactly 5 (should fail with max_recursion_depth=5)
112+
+ depth_5_any = {
113+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
114+
+ 'value': {
115+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
116+
+ 'value': {
117+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
118+
+ 'value': {
119+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
120+
+ 'value': {
121+
+ '@type': 'type.googleapis.com/google.protobuf.Any',
122+
+ 'value': {},
123+
+ },
124+
+ },
125+
+ },
126+
+ },
127+
+ }
128+
+ # This should fail: depth 5 == max_recursion_depth 5 (exclusive limit)
129+
+ self.assertRaisesRegex(
130+
+ json_format.ParseError,
131+
+ 'Message too deep. Max recursion depth is 5',
132+
+ json_format.ParseDict,
133+
+ depth_5_any,
134+
+ message,
135+
+ max_recursion_depth=5,
136+
+ )
137+
+
138+
139+
if __name__ == '__main__':
140+
unittest.main()
141+
diff --git a/extra/protobuf/protobuf-24.4/python/google/protobuf/json_format.py b/extra/protobuf/protobuf-24.4/python/google/protobuf/json_format.py
142+
index a04e8aef..2fe8da64 100644
143+
--- a/extra/protobuf/protobuf-24.4/python/google/protobuf/json_format.py
144+
+++ b/extra/protobuf/protobuf-24.4/python/google/protobuf/json_format.py
145+
@@ -496,6 +496,10 @@ class _Parser(object):
146+
Raises:
147+
ParseError: In case of convert problems.
148+
"""
149+
+ # Increment recursion depth at message entry. The max_recursion_depth limit
150+
+ # is exclusive: a depth value equal to max_recursion_depth will trigger an
151+
+ # error. For example, with max_recursion_depth=5, nesting up to depth 4 is
152+
+ # allowed, but attempting depth 5 raises ParseError.
153+
self.recursion_depth += 1
154+
if self.recursion_depth > self.max_recursion_depth:
155+
raise ParseError('Message too deep. Max recursion depth is {0}'.format(
156+
@@ -669,9 +673,11 @@ class _Parser(object):
157+
self._ConvertWrapperMessage(value['value'], sub_message,
158+
'{0}.value'.format(path))
159+
elif full_name in _WKTJSONMETHODS:
160+
- methodcaller(_WKTJSONMETHODS[full_name][1], value['value'], sub_message,
161+
- '{0}.value'.format(path))(
162+
- self)
163+
+ # For well-known types (including nested Any), use ConvertMessage
164+
+ # to ensure recursion depth is properly tracked
165+
+ self.ConvertMessage(
166+
+ value['value'], sub_message, '{0}.value'.format(path)
167+
+ )
168+
else:
169+
del value['@type']
170+
self._ConvertFieldValuePair(value, sub_message, path)
171+
--
172+
2.45.4
173+

SPECS/mysql/mysql.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Summary: MySQL.
22
Name: mysql
33
Version: 8.0.45
4-
Release: 1%{?dist}
4+
Release: 2%{?dist}
55
License: GPLv2 with exceptions AND LGPLv2 AND BSD
66
Vendor: Microsoft Corporation
77
Distribution: Mariner
@@ -15,6 +15,7 @@ Patch1: CVE-2024-2410.patch
1515
# ciphers unavailable.
1616
Patch2: fix-tests-for-unsupported-chacha-ciphers.patch
1717
Patch3: CVE-2025-62813.patch
18+
Patch4: CVE-2026-0994.patch
1819
BuildRequires: cmake
1920
BuildRequires: libtirpc-devel
2021
BuildRequires: openssl-devel
@@ -115,6 +116,9 @@ fi
115116
%{_libdir}/pkgconfig/mysqlclient.pc
116117

117118
%changelog
119+
* Mon Feb 09 2026 Jyoti Kanase <v-jykanase@microsoft.com> - 8.0.45-2
120+
- Patch for CVE-2026-0994
121+
118122
* Wed Jan 21 2026 Kanishk Bansal <kanbansal@microsoft.com> - 8.0.45-1
119123
- Upgrade to 8.0.45 for CVE-2026-21948, CVE-2026-21968,
120124
CVE-2026-21941, CVE-2026-21964, CVE-2026-21936, CVE-2026-21937

0 commit comments

Comments
 (0)