diff --git a/package/ruby/0001-fix-CVE-2026-41316.patch b/package/ruby/0001-fix-CVE-2026-41316.patch new file mode 100644 index 0000000000..1c5949c221 --- /dev/null +++ b/package/ruby/0001-fix-CVE-2026-41316.patch @@ -0,0 +1,73 @@ +From c35379df5279777fb4e02d989064eecd9cbbf338 Mon Sep 17 00:00:00 2001 +From: Takashi Kokubun +Date: Tue, 21 Apr 2026 16:27:44 +0900 +Subject: [PATCH] [ruby/erb] 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 + +Upstream: https://github.com/ruby/ruby/commit/c35379df5279777fb4e02d989064eecd9cbbf338 +CVE: CVE-2026-41316 +[Titouan: Rebase on top of Ruby 3.4.9] +Signed-off-by: Titouan Christophe +--- + 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 bc1615d7da..a7317c0856 100644 +--- a/lib/erb.rb ++++ b/lib/erb.rb +@@ -463,6 +463,9 @@ def new_toplevel(vars = nil) + # 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 09496d31e25ca2..9eec43da158c0c 100644 +--- a/test/erb/test_erb.rb ++++ b/test/erb/test_erb.rb +@@ -664,6 +664,33 @@ def test_prohibited_marshal_load + 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__ %> diff --git a/package/ruby/ruby.mk b/package/ruby/ruby.mk index c56d2510be..a66bbd4cbf 100644 --- a/package/ruby/ruby.mk +++ b/package/ruby/ruby.mk @@ -19,6 +19,9 @@ RUBY_LICENSE_FILES = LEGAL COPYING BSDL RUBY_CPE_ID_VENDOR = ruby-lang +# 0001-fix-CVE-2026-41316.patch +RUBY_IGNORE_CVES += CVE-2026-41316 + RUBY_DEPENDENCIES = host-pkgconf host-ruby HOST_RUBY_DEPENDENCIES = host-libyaml host-pkgconf host-openssl RUBY_MAKE_ENV = $(TARGET_MAKE_ENV)