!193 fix CVE-2024-41946
From: @zhangxianting Reviewed-by: @tong_1001, @small_leek Signed-off-by: @small_leek
This commit is contained in:
commit
21c99c7ebb
407
backport-CVE-2024-41946.patch
Normal file
407
backport-CVE-2024-41946.patch
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
From 033d1909a8f259d5a7c53681bcaf14f13bcf0368 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NAITOH Jun <naitoh@gmail.com>
|
||||||
|
Date: Thu, 1 Aug 2024 09:20:31 +0900
|
||||||
|
Subject: [PATCH] Add support for XML entity expansion limitation in SAX and
|
||||||
|
pull parsers (#187)
|
||||||
|
https://github.com/ruby/rexml/commit/033d1909a8f259d5a7c53681bcaf14f13bcf0368
|
||||||
|
|
||||||
|
- Supported `REXML::Security.entity_expansion_limit=` in SAX and pull parsers
|
||||||
|
- Supported `REXML::Security.entity_expansion_text_limit=` in SAX and pull parsers
|
||||||
|
---
|
||||||
|
lib/rexml/parsers/baseparser.rb | 19 ++++++-
|
||||||
|
lib/rexml/parsers/pullparser.rb | 4 ++
|
||||||
|
lib/rexml/parsers/sax2parser.rb | 4 ++
|
||||||
|
test/rexml/test_document.rb | 25 +++++----
|
||||||
|
test/rexml/test_pullparser.rb | 96 +++++++++++++++++++++++++++++++++
|
||||||
|
test/rexml/test_sax.rb | 86 +++++++++++++++++++++++++++++
|
||||||
|
6 files changed, 222 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
|
||||||
|
index 54014e5..c4ddee3 100644
|
||||||
|
--- a/lib/rexml/parsers/baseparser.rb
|
||||||
|
+++ b/lib/rexml/parsers/baseparser.rb
|
||||||
|
@@ -154,6 +154,7 @@ module REXML
|
||||||
|
self.stream = source
|
||||||
|
@listeners = []
|
||||||
|
@prefixes = Set.new
|
||||||
|
+ @entity_expansion_count = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_listener( listener )
|
||||||
|
@@ -161,6 +162,7 @@ module REXML
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :source
|
||||||
|
+ attr_reader :entity_expansion_count
|
||||||
|
|
||||||
|
def stream=( source )
|
||||||
|
@source = SourceFactory.create_from( source )
|
||||||
|
@@ -513,7 +515,9 @@ module REXML
|
||||||
|
def entity( reference, entities )
|
||||||
|
value = nil
|
||||||
|
value = entities[ reference ] if entities
|
||||||
|
- if not value
|
||||||
|
+ if value
|
||||||
|
+ record_entity_expansion
|
||||||
|
+ else
|
||||||
|
value = DEFAULT_ENTITIES[ reference ]
|
||||||
|
value = value[2] if value
|
||||||
|
end
|
||||||
|
@@ -552,12 +556,17 @@ module REXML
|
||||||
|
}
|
||||||
|
matches.collect!{|x|x[0]}.compact!
|
||||||
|
if matches.size > 0
|
||||||
|
+ sum = 0
|
||||||
|
matches.each do |entity_reference|
|
||||||
|
unless filter and filter.include?(entity_reference)
|
||||||
|
entity_value = entity( entity_reference, entities )
|
||||||
|
if entity_value
|
||||||
|
re = Private::DEFAULT_ENTITIES_PATTERNS[entity_reference] || /&#{entity_reference};/
|
||||||
|
rv.gsub!( re, entity_value )
|
||||||
|
+ sum += rv.bytesize
|
||||||
|
+ if sum > Security.entity_expansion_text_limit
|
||||||
|
+ raise "entity expansion has grown too large"
|
||||||
|
+ end
|
||||||
|
else
|
||||||
|
er = DEFAULT_ENTITIES[entity_reference]
|
||||||
|
rv.gsub!( er[0], er[2] ) if er
|
||||||
|
@@ -570,6 +579,14 @@ module REXML
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
+
|
||||||
|
+ def record_entity_expansion
|
||||||
|
+ @entity_expansion_count += 1
|
||||||
|
+ if @entity_expansion_count > Security.entity_expansion_limit
|
||||||
|
+ raise "number of entity expansions exceeded, processing aborted."
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
def need_source_encoding_update?(xml_declaration_encoding)
|
||||||
|
return false if xml_declaration_encoding.nil?
|
||||||
|
return false if /\AUTF-16\z/i =~ xml_declaration_encoding
|
||||||
|
diff --git a/lib/rexml/parsers/pullparser.rb b/lib/rexml/parsers/pullparser.rb
|
||||||
|
index f8b232a..36b4595 100644
|
||||||
|
--- a/lib/rexml/parsers/pullparser.rb
|
||||||
|
+++ b/lib/rexml/parsers/pullparser.rb
|
||||||
|
@@ -47,6 +47,10 @@ module REXML
|
||||||
|
@listeners << listener
|
||||||
|
end
|
||||||
|
|
||||||
|
+ def entity_expansion_count
|
||||||
|
+ @parser.entity_expansion_count
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
def each
|
||||||
|
while has_next?
|
||||||
|
yield self.pull
|
||||||
|
diff --git a/lib/rexml/parsers/sax2parser.rb b/lib/rexml/parsers/sax2parser.rb
|
||||||
|
index 36f98c2..cec9d2f 100644
|
||||||
|
--- a/lib/rexml/parsers/sax2parser.rb
|
||||||
|
+++ b/lib/rexml/parsers/sax2parser.rb
|
||||||
|
@@ -22,6 +22,10 @@ module REXML
|
||||||
|
@parser.source
|
||||||
|
end
|
||||||
|
|
||||||
|
+ def entity_expansion_count
|
||||||
|
+ @parser.entity_expansion_count
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
def add_listener( listener )
|
||||||
|
@parser.add_listener( listener )
|
||||||
|
end
|
||||||
|
diff --git a/test/rexml/test_document.rb b/test/rexml/test_document.rb
|
||||||
|
index 33cf400..0764631 100644
|
||||||
|
--- a/test/rexml/test_document.rb
|
||||||
|
+++ b/test/rexml/test_document.rb
|
||||||
|
@@ -41,7 +41,7 @@ EOF
|
||||||
|
|
||||||
|
class GeneralEntityTest < self
|
||||||
|
def test_have_value
|
||||||
|
- xml = <<EOF
|
||||||
|
+ xml = <<XML
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE member [
|
||||||
|
<!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
|
||||||
|
@@ -55,23 +55,24 @@ EOF
|
||||||
|
<member>
|
||||||
|
&a;
|
||||||
|
</member>
|
||||||
|
-EOF
|
||||||
|
+XML
|
||||||
|
|
||||||
|
doc = REXML::Document.new(xml)
|
||||||
|
- assert_raise(RuntimeError) do
|
||||||
|
+ assert_raise(RuntimeError.new("entity expansion has grown too large")) do
|
||||||
|
doc.root.children.first.value
|
||||||
|
end
|
||||||
|
+
|
||||||
|
REXML::Security.entity_expansion_limit = 100
|
||||||
|
assert_equal(100, REXML::Security.entity_expansion_limit)
|
||||||
|
doc = REXML::Document.new(xml)
|
||||||
|
- assert_raise(RuntimeError) do
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
doc.root.children.first.value
|
||||||
|
end
|
||||||
|
assert_equal(101, doc.entity_expansion_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_empty_value
|
||||||
|
- xml = <<EOF
|
||||||
|
+ xml = <<XML
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE member [
|
||||||
|
<!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
|
||||||
|
@@ -85,23 +86,24 @@ EOF
|
||||||
|
<member>
|
||||||
|
&a;
|
||||||
|
</member>
|
||||||
|
-EOF
|
||||||
|
+XML
|
||||||
|
|
||||||
|
doc = REXML::Document.new(xml)
|
||||||
|
- assert_raise(RuntimeError) do
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
doc.root.children.first.value
|
||||||
|
end
|
||||||
|
+
|
||||||
|
REXML::Security.entity_expansion_limit = 100
|
||||||
|
assert_equal(100, REXML::Security.entity_expansion_limit)
|
||||||
|
doc = REXML::Document.new(xml)
|
||||||
|
- assert_raise(RuntimeError) do
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
doc.root.children.first.value
|
||||||
|
end
|
||||||
|
assert_equal(101, doc.entity_expansion_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_with_default_entity
|
||||||
|
- xml = <<EOF
|
||||||
|
+ xml = <<XML
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE member [
|
||||||
|
<!ENTITY a "a">
|
||||||
|
@@ -112,14 +114,15 @@ EOF
|
||||||
|
&a2;
|
||||||
|
<
|
||||||
|
</member>
|
||||||
|
-EOF
|
||||||
|
+XML
|
||||||
|
|
||||||
|
REXML::Security.entity_expansion_limit = 4
|
||||||
|
doc = REXML::Document.new(xml)
|
||||||
|
assert_equal("\na\na a\n<\n", doc.root.children.first.value)
|
||||||
|
+
|
||||||
|
REXML::Security.entity_expansion_limit = 3
|
||||||
|
doc = REXML::Document.new(xml)
|
||||||
|
- assert_raise(RuntimeError) do
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
doc.root.children.first.value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
diff --git a/test/rexml/test_pullparser.rb b/test/rexml/test_pullparser.rb
|
||||||
|
index 096e8b7..55205af 100644
|
||||||
|
--- a/test/rexml/test_pullparser.rb
|
||||||
|
+++ b/test/rexml/test_pullparser.rb
|
||||||
|
@@ -155,5 +155,101 @@ module REXMLTests
|
||||||
|
end
|
||||||
|
assert_equal( 0, names.length )
|
||||||
|
end
|
||||||
|
+
|
||||||
|
+ class EntityExpansionLimitTest < Test::Unit::TestCase
|
||||||
|
+ def setup
|
||||||
|
+ @default_entity_expansion_limit = REXML::Security.entity_expansion_limit
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ def teardown
|
||||||
|
+ REXML::Security.entity_expansion_limit = @default_entity_expansion_limit
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ class GeneralEntityTest < self
|
||||||
|
+ def test_have_value
|
||||||
|
+ source = <<-XML
|
||||||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
+<!DOCTYPE member [
|
||||||
|
+ <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
|
||||||
|
+ <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
|
||||||
|
+ <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
|
||||||
|
+ <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
|
||||||
|
+ <!ENTITY e "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
|
||||||
|
+]>
|
||||||
|
+<member>
|
||||||
|
+&a;
|
||||||
|
+</member>
|
||||||
|
+ XML
|
||||||
|
+
|
||||||
|
+ parser = REXML::Parsers::PullParser.new(source)
|
||||||
|
+ assert_raise(RuntimeError.new("entity expansion has grown too large")) do
|
||||||
|
+ while parser.has_next?
|
||||||
|
+ parser.pull
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ def test_empty_value
|
||||||
|
+ source = <<-XML
|
||||||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
+<!DOCTYPE member [
|
||||||
|
+ <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
|
||||||
|
+ <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
|
||||||
|
+ <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
|
||||||
|
+ <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
|
||||||
|
+ <!ENTITY e "">
|
||||||
|
+]>
|
||||||
|
+<member>
|
||||||
|
+&a;
|
||||||
|
+</member>
|
||||||
|
+ XML
|
||||||
|
+
|
||||||
|
+ parser = REXML::Parsers::PullParser.new(source)
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
+ while parser.has_next?
|
||||||
|
+ parser.pull
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ REXML::Security.entity_expansion_limit = 100
|
||||||
|
+ parser = REXML::Parsers::PullParser.new(source)
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
+ while parser.has_next?
|
||||||
|
+ parser.pull
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ assert_equal(101, parser.entity_expansion_count)
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ def test_with_default_entity
|
||||||
|
+ source = <<-XML
|
||||||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
+<!DOCTYPE member [
|
||||||
|
+ <!ENTITY a "a">
|
||||||
|
+ <!ENTITY a2 "&a; &a;">
|
||||||
|
+]>
|
||||||
|
+<member>
|
||||||
|
+&a;
|
||||||
|
+&a2;
|
||||||
|
+<
|
||||||
|
+</member>
|
||||||
|
+ XML
|
||||||
|
+
|
||||||
|
+ REXML::Security.entity_expansion_limit = 4
|
||||||
|
+ parser = REXML::Parsers::PullParser.new(source)
|
||||||
|
+ while parser.has_next?
|
||||||
|
+ parser.pull
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ REXML::Security.entity_expansion_limit = 3
|
||||||
|
+ parser = REXML::Parsers::PullParser.new(source)
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
+ while parser.has_next?
|
||||||
|
+ parser.pull
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
diff --git a/test/rexml/test_sax.rb b/test/rexml/test_sax.rb
|
||||||
|
index 5a3f5e4..5e3ad75 100644
|
||||||
|
--- a/test/rexml/test_sax.rb
|
||||||
|
+++ b/test/rexml/test_sax.rb
|
||||||
|
@@ -99,6 +99,92 @@ module REXMLTests
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
+ class EntityExpansionLimitTest < Test::Unit::TestCase
|
||||||
|
+ def setup
|
||||||
|
+ @default_entity_expansion_limit = REXML::Security.entity_expansion_limit
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ def teardown
|
||||||
|
+ REXML::Security.entity_expansion_limit = @default_entity_expansion_limit
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ class GeneralEntityTest < self
|
||||||
|
+ def test_have_value
|
||||||
|
+ source = <<-XML
|
||||||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
+<!DOCTYPE member [
|
||||||
|
+ <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
|
||||||
|
+ <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
|
||||||
|
+ <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
|
||||||
|
+ <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
|
||||||
|
+ <!ENTITY e "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
|
||||||
|
+]>
|
||||||
|
+<member>
|
||||||
|
+&a;
|
||||||
|
+</member>
|
||||||
|
+ XML
|
||||||
|
+
|
||||||
|
+ sax = REXML::Parsers::SAX2Parser.new(source)
|
||||||
|
+ assert_raise(RuntimeError.new("entity expansion has grown too large")) do
|
||||||
|
+ sax.parse
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ def test_empty_value
|
||||||
|
+ source = <<-XML
|
||||||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
+<!DOCTYPE member [
|
||||||
|
+ <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
|
||||||
|
+ <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
|
||||||
|
+ <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
|
||||||
|
+ <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
|
||||||
|
+ <!ENTITY e "">
|
||||||
|
+]>
|
||||||
|
+<member>
|
||||||
|
+&a;
|
||||||
|
+</member>
|
||||||
|
+ XML
|
||||||
|
+
|
||||||
|
+ sax = REXML::Parsers::SAX2Parser.new(source)
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
+ sax.parse
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ REXML::Security.entity_expansion_limit = 100
|
||||||
|
+ sax = REXML::Parsers::SAX2Parser.new(source)
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
+ sax.parse
|
||||||
|
+ end
|
||||||
|
+ assert_equal(101, sax.entity_expansion_count)
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ def test_with_default_entity
|
||||||
|
+ source = <<-XML
|
||||||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
+<!DOCTYPE member [
|
||||||
|
+ <!ENTITY a "a">
|
||||||
|
+ <!ENTITY a2 "&a; &a;">
|
||||||
|
+]>
|
||||||
|
+<member>
|
||||||
|
+&a;
|
||||||
|
+&a2;
|
||||||
|
+<
|
||||||
|
+</member>
|
||||||
|
+ XML
|
||||||
|
+
|
||||||
|
+ REXML::Security.entity_expansion_limit = 4
|
||||||
|
+ sax = REXML::Parsers::SAX2Parser.new(source)
|
||||||
|
+ sax.parse
|
||||||
|
+
|
||||||
|
+ REXML::Security.entity_expansion_limit = 3
|
||||||
|
+ sax = REXML::Parsers::SAX2Parser.new(source)
|
||||||
|
+ assert_raise(RuntimeError.new("number of entity expansions exceeded, processing aborted.")) do
|
||||||
|
+ sax.parse
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
# used by test_simple_doctype_listener
|
||||||
|
# submitted by Jeff Barczewski
|
||||||
|
class SimpleDoctypeListener
|
||||||
|
--
|
||||||
|
2.20.1
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
Name: ruby
|
Name: ruby
|
||||||
Version: 2.5.8
|
Version: 2.5.8
|
||||||
Release: 126
|
Release: 127
|
||||||
Summary: Object-oriented scripting language interpreter
|
Summary: Object-oriented scripting language interpreter
|
||||||
License: (Ruby or BSD) and Public Domain and MIT and CC0 and zlib and UCD
|
License: (Ruby or BSD) and Public Domain and MIT and CC0 and zlib and UCD
|
||||||
URL: https://www.ruby-lang.org/
|
URL: https://www.ruby-lang.org/
|
||||||
@ -69,6 +69,7 @@ Patch6025: backport-0004-CVE-2024-35221.patch
|
|||||||
Patch6026: backport-0005-CVE-2024-35221.patch
|
Patch6026: backport-0005-CVE-2024-35221.patch
|
||||||
Patch6027: upgrade-lib-rexml-to-3.3.1.patch
|
Patch6027: upgrade-lib-rexml-to-3.3.1.patch
|
||||||
Patch6028: upgrade-lib-rexml-test-to-3.3.1.patch
|
Patch6028: upgrade-lib-rexml-test-to-3.3.1.patch
|
||||||
|
Patch6029: backport-CVE-2024-41946.patch
|
||||||
|
|
||||||
Patch9000: add-require_relative-helper-to-uninitialized-constan.patch
|
Patch9000: add-require_relative-helper-to-uninitialized-constan.patch
|
||||||
|
|
||||||
@ -608,6 +609,9 @@ make runruby TESTRUN_SCRIPT=%{SOURCE13}
|
|||||||
%exclude %{gem_dir}/gems/xmlrpc-0.3.0/.*
|
%exclude %{gem_dir}/gems/xmlrpc-0.3.0/.*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Aug 09 2024 zhangxianting <zhangxianting@uniontech.com> - 2.5.8-127
|
||||||
|
- fix CVE-2024-41946
|
||||||
|
|
||||||
* Tue Jul 02 2024 shixuantong <shixuantong1@huawei.com> - 2.5.8-126
|
* Tue Jul 02 2024 shixuantong <shixuantong1@huawei.com> - 2.5.8-126
|
||||||
- upgrade rexml version to fix CVE-2024-35176
|
- upgrade rexml version to fix CVE-2024-35176
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user