fix CVE-2025-25186
(cherry picked from commit 9d1564fe1e9cd5db7988e1bd4a6a902a930e16b8)
This commit is contained in:
parent
903b11a397
commit
7c15f8745c
123
backport-CVE-2025-25186.patch
Normal file
123
backport-CVE-2025-25186.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 0dbb8eb72aa78b7ed0b01533388e69722d16b821 Mon Sep 17 00:00:00 2001
|
||||
From: nick evans <nick@rubinick.dev>
|
||||
Date: Wed, 8 Jan 2025 22:06:47 -0500
|
||||
Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=94=92=20Prevent=20runaway=20memory?=
|
||||
=?UTF-8?q?=20use=20when=20parsing=20uid-set?=
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reference:https://github.com/ruby/net-imap/commit/0dbb8eb72aa78b7ed0b01533388e69722d16b821
|
||||
Conflict:not change test, the test/net/imap/ directory doesn't exist.
|
||||
|
||||
Problem
|
||||
=========
|
||||
|
||||
The UID sets in UIDPlusData are stored as arrays of UIDs. In common
|
||||
scenarios, copying between one and a few hundred emails at a time, this
|
||||
is barely noticable. But the memory use expands _exponentially_.
|
||||
|
||||
This should not be an issue for _trusted_ servers, and (I assume)
|
||||
compromised servers will be more interested in evading detection and
|
||||
stealing your credentials and your email than in causing client Denial
|
||||
of Service. Nevertheless, this is a very simple DoS attack against
|
||||
clients connecting to untrusted servers (for example, a service that
|
||||
connects to user-specified servers).
|
||||
|
||||
For example, assuming a 64-bit architecture, considering only the data
|
||||
in the two arrays, assuming the arrays' internal capacity is no more
|
||||
than needed, and ignoring the fixed cost of the response structs:
|
||||
* 32 bytes expands to ~160KB (about 5000 times more):
|
||||
`"* OK [COPYUID 1 1:9999 1:9999]\r\n"`
|
||||
* 40 bytes expands to ~1.6GB (about 50 million times more):
|
||||
`"* OK [COPYUID 1 1:99999999 1:99999999]\r\n"`
|
||||
* In the worst scenario (uint32 max), 44 bytes expands to 64GiB in
|
||||
memory, using over 1.5 billion times more to store than to send:
|
||||
`"* OK [COPYUID 1 1:4294967295 1:4294967295]\r\n"`
|
||||
|
||||
Preferred fix
|
||||
===============
|
||||
|
||||
The preferred fix is to store `uid-set` as a SequenceSet, not an array.
|
||||
Unfortunately, this is not fully backwards compatible. For v0.4 and
|
||||
v0.5, use `Config#parser_use_deprecated_uidplus_data` to false to use
|
||||
AppendUIDData and CopyUIDData instead of UIDPlusData. Unless you are
|
||||
_using_ UIDPLUS, this is completely safe. v0.6 will drop UIDPlusData.
|
||||
|
||||
Workaround
|
||||
============
|
||||
|
||||
The simplest _partial_ fix (preserving full backward compatibility) is
|
||||
to raise an error when the number of UIDs goes over some threshold, and
|
||||
continue using arrays inside UIDPlusData.
|
||||
|
||||
For v0.3 (this commit) the maximum count is hard-coded to 10,000. This
|
||||
is high enough that it should almost never be triggered by normal usage,
|
||||
and low enough to be a less extreme problem. For v0.4 and v0.5, the
|
||||
maximum array size is configurable, with a much lower default: 1000 for
|
||||
v0.4 and 100 for v0.5. These are low enough that they are _unlikely_ to
|
||||
cause a problem, but v0.4 and v0.5 can also use the newer AppendUIDData
|
||||
and CopyUIDData classes.
|
||||
|
||||
However, because unhandled responses are stored on the `#responses`
|
||||
hash, this can still be a problem. A malicious server could repeatedly
|
||||
use 160Kb of client memory by sending only 32 bytes in a loop. To fully
|
||||
solve this problem, a response handler must be added to prune excessive
|
||||
APPENDUID/COPYUID responses as they are received.
|
||||
|
||||
Because unhandled responses have always been retained, managing
|
||||
unhandled responses is already documented as necessary for long-lived
|
||||
connections.
|
||||
---
|
||||
.../lib/net/imap/response_parser.rb | 26 ++++++++++++++++---
|
||||
1 file changed, 23 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/.bundle/gems/net-imap-0.3.4/lib/net/imap/response_parser.rb b/.bundle/gems/net-imap-0.3.4/lib/net/imap/response_parser.rb
|
||||
index be1a849..0341356 100644
|
||||
--- a/.bundle/gems/net-imap-0.3.4/lib/net/imap/response_parser.rb
|
||||
+++ b/.bundle/gems/net-imap-0.3.4/lib/net/imap/response_parser.rb
|
||||
@@ -7,6 +7,8 @@ module Net
|
||||
|
||||
# Parses an \IMAP server response.
|
||||
class ResponseParser
|
||||
+ MAX_UID_SET_SIZE = 10_000
|
||||
+
|
||||
# :call-seq: Net::IMAP::ResponseParser.new -> Net::IMAP::ResponseParser
|
||||
def initialize
|
||||
@str = nil
|
||||
@@ -1379,11 +1381,29 @@ module Net
|
||||
case token.symbol
|
||||
when T_NUMBER then [Integer(token.value)]
|
||||
when T_ATOM
|
||||
- token.value.split(",").flat_map {|range|
|
||||
- range = range.split(":").map {|uniqueid| Integer(uniqueid) }
|
||||
- range.size == 1 ? range : Range.new(range.min, range.max).to_a
|
||||
+ entries = uid_set__ranges(token.value)
|
||||
+ if (count = entries.sum(&:count)) > MAX_UID_SET_SIZE
|
||||
+ parse_error("uid-set is too large: %d > 10k", count)
|
||||
+ end
|
||||
+ entries.flat_map(&:to_a)
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
+ # returns an array of ranges
|
||||
+ def uid_set__ranges(uidset)
|
||||
+ entries = []
|
||||
+ uidset.split(",") do |entry|
|
||||
+ uids = entry.split(":", 2).map {|uid|
|
||||
+ unless uid =~ /\A[1-9][0-9]*\z/
|
||||
+ parse_error("invalid uid-set uid: %p", uid)
|
||||
+ end
|
||||
+ uid = Integer(uid)
|
||||
+ NumValidator.ensure_nz_number(uid)
|
||||
+ uid
|
||||
}
|
||||
+ entries << Range.new(*uids.minmax)
|
||||
end
|
||||
+ entries
|
||||
end
|
||||
|
||||
def nil_atom
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
Name: ruby
|
||||
Version: %{ruby_version}
|
||||
Release: 147
|
||||
Release: 148
|
||||
Summary: Object-oriented scripting language interpreter
|
||||
License: (Ruby or BSD) and Public Domain and MIT and CC0 and zlib and UCD
|
||||
URL: https://www.ruby-lang.org/en/
|
||||
@ -103,6 +103,7 @@ Patch6026: backport-CVE-2024-39908-CVE-2024-41123-upgrade-lib-rexml-to-3.3.3.pat
|
||||
Patch6027: backport-CVE-2024-43398-upgrade-lib-rexml-to-3.3.6.patch
|
||||
Patch6028: backport-CVE-2024-47220.patch
|
||||
Patch6029: backport-CVE-2024-49761.patch
|
||||
Patch6030: backport-CVE-2025-25186.patch
|
||||
|
||||
Provides: %{name}-libs = %{version}-%{release}
|
||||
Obsoletes: %{name}-libs < %{version}-%{release}
|
||||
@ -888,6 +889,9 @@ make runruby TESTRUN_SCRIPT=%{SOURCE13}
|
||||
%{gem_dir}/specifications/matrix-%{matrix_version}.gemspec
|
||||
|
||||
%changelog
|
||||
* Sat Feb 22 2025 shixuantong <shixuantong1@huawei.com> - 3.2.2-148
|
||||
- fix CVE-2025-25186
|
||||
|
||||
* Tue Oct 29 2024 shixuantong <shixuantong1@huawei.com> - 3.2.2-147
|
||||
- fix CVE-2024-49761
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user