diff --git a/backport-CVE-2026-41316.patch b/backport-CVE-2026-41316.patch new file mode 100644 index 0000000000000000000000000000000000000000..58fdffb5aa00bd24828c71f1c86b6fc22ceeb6cf --- /dev/null +++ b/backport-CVE-2026-41316.patch @@ -0,0 +1,71 @@ +From ef61b591b270f8ba58d47f12472a1c53a77b4d61 Mon Sep 17 00:00:00 2001 +From: Takashi Kokubun +Date: Tue, 21 Apr 2026 16:27:44 +0900 +Subject: [PATCH] Prohibit def_method on marshal-loaded ERB instances + +Extends the @_init guard to def_method so that an ERB object created +via Marshal.load (which bypasses initialize) raises ArgumentError +instead of evaluating arbitrary source. def_module and def_class both +delegate to def_method and are covered by the same check. + +Co-authored-by: Tristan Madani +--- + lib/erb.rb | 3 +++ + test/erb/test_erb.rb | 27 +++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/lib/erb.rb b/lib/erb.rb +index bc1615d..a7317c0 100644 +--- a/lib/erb.rb ++++ b/lib/erb.rb +@@ -463,6 +463,9 @@ class ERB + # erb.def_method(MyClass, 'render(arg1, arg2)', filename) + # print MyClass.new.render('foo', 123) + def def_method(mod, methodname, fname='(ERB)') ++ unless @_init.equal?(self.class.singleton_class) ++ raise ArgumentError, "not initialized" ++ end + src = self.src.sub(/^(?!#|$)/) {"def #{methodname}\n"} << "\nend\n" + mod.module_eval do + eval(src, binding, fname, -1) +diff --git a/test/erb/test_erb.rb b/test/erb/test_erb.rb +index 555345a..1266b64 100644 +--- a/test/erb/test_erb.rb ++++ b/test/erb/test_erb.rb +@@ -714,6 +714,33 @@ EOS + assert_raise(ArgumentError) {erb.result} + end + ++ def test_prohibited_marshal_load_def_method ++ erb = ERB.allocate ++ erb.instance_variable_set(:@src, "") ++ erb.instance_variable_set(:@lineno, 1) ++ erb.instance_variable_set(:@_init, true) ++ erb = Marshal.load(Marshal.dump(erb)) ++ assert_raise(ArgumentError) {erb.def_method(Class.new, 'render')} ++ end ++ ++ def test_prohibited_marshal_load_def_module ++ erb = ERB.allocate ++ erb.instance_variable_set(:@src, "") ++ erb.instance_variable_set(:@lineno, 1) ++ erb.instance_variable_set(:@_init, true) ++ erb = Marshal.load(Marshal.dump(erb)) ++ assert_raise(ArgumentError) {erb.def_module} ++ end ++ ++ def test_prohibited_marshal_load_def_class ++ erb = ERB.allocate ++ erb.instance_variable_set(:@src, "") ++ erb.instance_variable_set(:@lineno, 1) ++ erb.instance_variable_set(:@_init, true) ++ erb = Marshal.load(Marshal.dump(erb)) ++ assert_raise(ArgumentError) {erb.def_class} ++ end ++ + def test_multi_line_comment_lineno + erb = ERB.new(<<~EOS) + <%= __LINE__ %> +-- +2.43.7 + diff --git a/ruby.spec b/ruby.spec index addaa201af900e7dab3c8e0b62d0426e26c12668..bb376c9ee819e07a8814e5ef6558b65ae5b649bf 100644 --- a/ruby.spec +++ b/ruby.spec @@ -60,7 +60,7 @@ Summary: An interpreter of object-oriented scripting language Name: ruby Version: %{ruby_version} -Release: 15%{?dist} +Release: 16%{?dist} License: (Ruby OR BSD-2-Clause) AND BSD-3-Clause AND ISC AND Public Domain AND MIT and CC0 AND zlib AND Unicode-DFS-2015 URL: https://www.ruby-lang.org/ Source0: https://cache.ruby-lang.org/pub/%{name}/%{major_version}.%{minor_version}/%{name}-%{ruby_version}.tar.gz @@ -100,6 +100,7 @@ Patch3007: ruby-2.7.1-Timeout-the-test_bug_reporter_add-witout-raising-err.patch Patch3008: ruby-3.2.0-Revert-Fix-test-syntax-suggest-order.patch Patch3009: ruby-3.2.0-Revert-Test-syntax_suggest-by-make-check.patch Patch3010: backport-CVE-2024-35221.patch +Patch3011: backport-CVE-2026-41316.patch BuildRequires: autoconf, gcc, make, cmake, rust, system-rpm-config, git, hostname, readline-devel BuildRequires: gmp-devel, systemtap-sdt-devel, libffi-devel, openssl-devel, libyaml-devel, procps, zlib-devel @@ -1287,6 +1288,10 @@ DISABLE_TESTS="$DISABLE_TESTS -n !/TestGCCompact#test_moving_objects_between_siz %changelog +* Wed Apr 29 2026 anatasluo - 3.2.3-16 +- [Type] security +- [DESC] fix CVE-2026-41316 + * Sat May 24 2025 anatasluo - 3.2.3-15 - [Type] security - [DESC] fix CVE-2025-25186, CVE-2025-43857