Skip to content
This repository has been archived by the owner on Jan 15, 2025. It is now read-only.

Commit

Permalink
(PA-6507) Patch REXML for CVE-2024-35176 in ruby 2.7 and 3.2
Browse files Browse the repository at this point in the history
  • Loading branch information
amitkarsale committed Jul 2, 2024
1 parent a39b23b commit 395eb24
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 0 deletions.
22 changes: 22 additions & 0 deletions configs/components/ruby-2.7.8.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

pkg.apply_patch "#{base}/uri-redos-cve-2023-36617.patch"


if platform.is_cross_compiled?
unless platform.is_macos?
pkg.apply_patch "#{base}/uri_generic_remove_safe_nav_operator_r2.5.patch"
Expand Down Expand Up @@ -169,6 +170,26 @@
]
end

#########
# BUILD
#########

pkg.add_source("file://resources/patches/ruby_27/rexml_for_CVE-2024-35176.patch")

pkg.build do
# This patch is applied after install because rexml gem is the bundled gem unlike default gems and hence
# not able to find the path of the files to be patched prior configuring and installing
#this patch is not required in ruby >= 3.2.5
ruby = "#{ruby_bindir}/ruby -rrbconfig"
steps = [
"export RUBYHDRDIR=$(shell #{ruby} -e 'puts RbConfig::CONFIG[\"rubyhdrdir\"]')",
"export VENDORARCHDIR=$(shell #{ruby} -e 'puts RbConfig::CONFIG[\"vendorarchdir\"]')",
"export ARCHDIR=$${RUBYHDRDIR}/$(shell #{ruby} -e 'puts RbConfig::CONFIG[\"arch\"]')",
"export INCLUDESTR=\"-I#{settings[:includedir]} -I$${RUBYHDRDIR} -I$${ARCHDIR}\""
]
steps = ["#{platform.patch} --strip=1 --fuzz=3 --ignore-whitespace --no-backup-if-mismatch < ../rexml_for_CVE-2024-35176.patch"]
end

#########
# INSTALL
#########
Expand Down Expand Up @@ -268,4 +289,5 @@
]
end
end

end
22 changes: 22 additions & 0 deletions configs/components/ruby-3.2.4.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

base = 'resources/patches/ruby_32'


if platform.is_cross_compiled?
pkg.apply_patch "#{base}/rbinstall_gem_path.patch"
end
Expand Down Expand Up @@ -300,4 +301,25 @@
]
end
end

#########
# BUILD
#########

pkg.add_source("file://resources/patches/ruby_32/rexml_for_CVE-2024-35176.patch")

pkg.build do
# This patch is applied after install because rexml gem is the bundled gem unlike default gems and hence
# not able to find the path of the files to be patched prior configuring and installing
#this patch is not required in ruby >= 3.2.5
ruby = "#{ruby_bindir}/ruby -rrbconfig"
steps = [
"export RUBYHDRDIR=$(shell #{ruby} -e 'puts RbConfig::CONFIG[\"rubyhdrdir\"]')",
"export VENDORARCHDIR=$(shell #{ruby} -e 'puts RbConfig::CONFIG[\"vendorarchdir\"]')",
"export ARCHDIR=$${RUBYHDRDIR}/$(shell #{ruby} -e 'puts RbConfig::CONFIG[\"arch\"]')",
"export INCLUDESTR=\"-I#{settings[:includedir]} -I$${RUBYHDRDIR} -I$${ARCHDIR}\""
]
steps << ["#{platform.patch} --strip=1 --fuzz=3 --ignore-whitespace --no-backup-if-mismatch < ../rexml_for_CVE-2024-35176.patch"]
end

end
96 changes: 96 additions & 0 deletions resources/patches/ruby_27/rexml_for_CVE-2024-35176.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@

diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
index 8d62391c..d09237c5 100644
--- a/lib/rexml/parsers/baseparser.rb
+++ b/lib/rexml/parsers/baseparser.rb
@@ -628,17 +628,17 @@ def parse_attributes(prefixes, curr_ns)
message = "Missing attribute equal: <#{name}>"
raise REXML::ParseException.new(message, @source)
end
- unless match = @source.match(/(['"])(.*?)\1\s*/um, true)
- if match = @source.match(/(['"])/, true)
- message =
- "Missing attribute value end quote: <#{name}>: <#{match[1]}>"
- raise REXML::ParseException.new(message, @source)
- else
- message = "Missing attribute value start quote: <#{name}>"
- raise REXML::ParseException.new(message, @source)
- end
+ unless match = @source.match(/(['"])/, true)
+ message = "Missing attribute value start quote: <#{name}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+ quote = match[1]
+ value = @source.read_until(quote)
+ unless value.chomp!(quote)
+ message = "Missing attribute value end quote: <#{name}>: <#{quote}>"
+ raise REXML::ParseException.new(message, @source)
end
- value = match[2]
+ @source.match(/\s*/um, true)
if prefix == "xmlns"
if local_part == "xml"
if value != "http://www.w3.org/XML/1998/namespace"
diff --git a/lib/rexml/source.rb b/lib/rexml/source.rb
index 7f47c2be..999751b4 100644
--- a/lib/rexml/source.rb
+++ b/lib/rexml/source.rb
@@ -65,7 +65,11 @@ def encoding=(enc)
encoding_updated
end

- def read
+ def read(term = nil)
+ end
+
+ def read_until(term)
+ @scanner.scan_until(Regexp.union(term)) or @scanner.rest
end

def ensure_buffer
@@ -158,9 +162,9 @@ def initialize(arg, block_size=500, encoding=nil)
end
end

- def read
+ def read(term = nil)
begin
- @scanner << readline
+ @scanner << readline(term)
true
rescue Exception, NameError
@source = nil
@@ -168,6 +172,21 @@ def read
end
end

+ def read_until(term)
+ pattern = Regexp.union(term)
+ data = []
+ begin
+ until str = @scanner.scan_until(pattern)
+ @scanner << readline(term)
+ end
+ rescue EOFError
+ @scanner.rest
+ else
+ read if @scanner.eos? and [email protected]?
+ str
+ end
+ end
+
def ensure_buffer
read if @scanner.eos? && @source
end
@@ -218,8 +237,8 @@ def current_line
end

private
- def readline
- str = @source.readline(@line_break)
+ def readline(term = nil)
+ str = @source.readline(term || @line_break)
if @pending_buffer
if str.nil?
str = @pending_buffer

96 changes: 96 additions & 0 deletions resources/patches/ruby_32/rexml_for_CVE-2024-35176.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@

diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
index 8d62391c..d09237c5 100644
--- a/lib/rexml/parsers/baseparser.rb
+++ b/lib/rexml/parsers/baseparser.rb
@@ -628,17 +628,17 @@ def parse_attributes(prefixes, curr_ns)
message = "Missing attribute equal: <#{name}>"
raise REXML::ParseException.new(message, @source)
end
- unless match = @source.match(/(['"])(.*?)\1\s*/um, true)
- if match = @source.match(/(['"])/, true)
- message =
- "Missing attribute value end quote: <#{name}>: <#{match[1]}>"
- raise REXML::ParseException.new(message, @source)
- else
- message = "Missing attribute value start quote: <#{name}>"
- raise REXML::ParseException.new(message, @source)
- end
+ unless match = @source.match(/(['"])/, true)
+ message = "Missing attribute value start quote: <#{name}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+ quote = match[1]
+ value = @source.read_until(quote)
+ unless value.chomp!(quote)
+ message = "Missing attribute value end quote: <#{name}>: <#{quote}>"
+ raise REXML::ParseException.new(message, @source)
end
- value = match[2]
+ @source.match(/\s*/um, true)
if prefix == "xmlns"
if local_part == "xml"
if value != "http://www.w3.org/XML/1998/namespace"
diff --git a/lib/rexml/source.rb b/lib/rexml/source.rb
index 7f47c2be..999751b4 100644
--- a/lib/rexml/source.rb
+++ b/lib/rexml/source.rb
@@ -65,7 +65,11 @@ def encoding=(enc)
encoding_updated
end

- def read
+ def read(term = nil)
+ end
+
+ def read_until(term)
+ @scanner.scan_until(Regexp.union(term)) or @scanner.rest
end

def ensure_buffer
@@ -158,9 +162,9 @@ def initialize(arg, block_size=500, encoding=nil)
end
end

- def read
+ def read(term = nil)
begin
- @scanner << readline
+ @scanner << readline(term)
true
rescue Exception, NameError
@source = nil
@@ -168,6 +172,21 @@ def read
end
end

+ def read_until(term)
+ pattern = Regexp.union(term)
+ data = []
+ begin
+ until str = @scanner.scan_until(pattern)
+ @scanner << readline(term)
+ end
+ rescue EOFError
+ @scanner.rest
+ else
+ read if @scanner.eos? and [email protected]?
+ str
+ end
+ end
+
def ensure_buffer
read if @scanner.eos? && @source
end
@@ -218,8 +237,8 @@ def current_line
end

private
- def readline
- str = @source.readline(@line_break)
+ def readline(term = nil)
+ str = @source.readline(term || @line_break)
if @pending_buffer
if str.nil?
str = @pending_buffer

0 comments on commit 395eb24

Please sign in to comment.