diff --git a/.gitignore b/.gitignore index 6e522bf..c6a1ef0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/ruby-4.0.1.tar.xz +SOURCES/ruby-4.0.3.tar.xz diff --git a/.ruby.metadata b/.ruby.metadata index 08dbc27..3dc1e0a 100644 --- a/.ruby.metadata +++ b/.ruby.metadata @@ -1 +1 @@ -266e6fa80ed2b4f4bb7de2e98973dc084a1f380e SOURCES/ruby-4.0.1.tar.xz +faf1f3df171d2160116d190ca32b6b00e0338bfa SOURCES/ruby-4.0.3.tar.xz diff --git a/SOURCES/ruby-4.0.3-Fix-a-format-string-injection-vulnerability.patch b/SOURCES/ruby-4.0.3-Fix-a-format-string-injection-vulnerability.patch new file mode 100644 index 0000000..35b0a87 --- /dev/null +++ b/SOURCES/ruby-4.0.3-Fix-a-format-string-injection-vulnerability.patch @@ -0,0 +1,86 @@ +From 83dbd3f615bd8e7a31571124059eb3264f73c559 Mon Sep 17 00:00:00 2001 +From: Jean Boussier +Date: Wed, 18 Mar 2026 08:56:17 +0100 +Subject: [PATCH] Fix a format string injection vulnerability + +In `JSON.parse(doc, allow_duplicate_key: false)`. +--- + ext/json/parser/parser.c | 26 +++++++++++++++++++------- + test/json/json_parser_test.rb | 7 +++++++ + 2 files changed, 26 insertions(+), 7 deletions(-) + +diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c +index 8f9729ef28..a05c5e9657 100644 +--- a/ext/json/parser/parser.c ++++ b/ext/json/parser/parser.c +@@ -400,14 +400,9 @@ static void emit_parse_warning(const char *message, JSON_ParserState *state) + + #define PARSE_ERROR_FRAGMENT_LEN 32 + +-#ifdef RBIMPL_ATTR_NORETURN +-RBIMPL_ATTR_NORETURN() +-#endif +-static void raise_parse_error(const char *format, JSON_ParserState *state) ++static VALUE build_parse_error_message(const char *format, JSON_ParserState *state, long line, long column) + { + unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 3]; +- long line, column; +- cursor_position(state, &line, &column); + + const char *ptr = "EOF"; + if (state->cursor && state->cursor < state->end) { +@@ -442,11 +437,23 @@ static void raise_parse_error(const char *format, JSON_ParserState *state) + VALUE msg = rb_sprintf(format, ptr); + VALUE message = rb_enc_sprintf(enc_utf8, "%s at line %ld column %ld", RSTRING_PTR(msg), line, column); + RB_GC_GUARD(msg); ++ return message; ++} + ++static VALUE parse_error_new(VALUE message, long line, long column) ++{ + VALUE exc = rb_exc_new_str(rb_path2class("JSON::ParserError"), message); + rb_ivar_set(exc, rb_intern("@line"), LONG2NUM(line)); + rb_ivar_set(exc, rb_intern("@column"), LONG2NUM(column)); +- rb_exc_raise(exc); ++ return exc; ++} ++ ++NORETURN(static) void raise_parse_error(const char *format, JSON_ParserState *state) ++{ ++ long line, column; ++ cursor_position(state, &line, &column); ++ VALUE message = build_parse_error_message(format, state, line, column); ++ rb_exc_raise(parse_error_new(message, line, column)); + } + + #ifdef RBIMPL_ATTR_NORETURN +@@ -896,6 +903,11 @@ static void raise_duplicate_key_error(JSON_ParserState *state, VALUE duplicate_k + rb_inspect(duplicate_key) + ); + ++ long line, column; ++ cursor_position(state, &line, &column); ++ rb_str_concat(message, build_parse_error_message("", state, line, column)) ; ++ rb_exc_raise(parse_error_new(message, line, column)); ++ + raise_parse_error(RSTRING_PTR(message), state); + RB_GC_GUARD(message); + } +diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb +index ec9391909d..61ea35d1f9 100644 +--- a/test/json/json_parser_test.rb ++++ b/test/json/json_parser_test.rb +@@ -411,6 +411,13 @@ def test_parse_duplicate_key + end + end + ++ def test_parse_duplicate_key_escape ++ error = assert_raise(ParserError) do ++ JSON.parse('{"%s%s%s%s":1,"%s%s%s%s":2}', allow_duplicate_key: false) ++ end ++ assert_match "%s%s%s%s", error.message ++ end ++ + def test_some_wrong_inputs + assert_raise(ParserError) { parse('[] bla') } + assert_raise(ParserError) { parse('[] 1') } diff --git a/SPECS/ruby.spec b/SPECS/ruby.spec index 38d2c46..ed8718b 100644 --- a/SPECS/ruby.spec +++ b/SPECS/ruby.spec @@ -1,6 +1,6 @@ %global major_version 4 %global minor_version 0 -%global teeny_version 1 +%global teeny_version 3 %global major_minor_version %{major_version}.%{minor_version} %global ruby_version %{major_minor_version}.%{teeny_version} @@ -36,19 +36,19 @@ ## BUNDLED_GEMS_VERSIONS # Bundled libraries versions -%global rubygems_version 4.0.3 +%global rubygems_version 4.0.6 %global rubygems_molinillo_version 0.8.0 %global rubygems_net_http_version 0.7.0 %global rubygems_net_protocol_version 0.2.2 %global rubygems_optparse_version 0.8.0 -%global rubygems_resolv_version 0.6.2 +%global rubygems_resolv_version 0.7.0 %global rubygems_securerandom_version 0.4.1 %global rubygems_timeout_version 0.4.4 %global rubygems_tsort_version 0.2.0 %global rubygems_uri_version 1.1.1 # Default gems. -%global bundler_version 4.0.3 +%global bundler_version 4.0.6 %global bundler_connection_pool_version 2.5.4 %global bundler_fileutils_version 1.8.0 %global bundler_net_http_persistent_version 4.0.6 @@ -63,7 +63,7 @@ %global did_you_mean_version 2.0.0 %global digest_version 3.2.1 %global english_version 0.8.1 -%global erb_version 6.0.1 +%global erb_version 6.0.1.1 %global error_highlight_version 0.7.1 %global etc_version 1.4.6 %global fcntl_version 1.3.0 @@ -83,7 +83,7 @@ %global optparse_version 0.8.1 %global pp_version 0.6.3 %global prettyprint_version 0.2.0 -%global prism_version 1.8.0 +%global prism_version 1.8.1 %global psych_version 5.3.1 %global resolv_version 0.7.0 %global ruby2_keywords_version 0.0.5 @@ -92,7 +92,7 @@ %global singleton_version 0.3.0 %global stringio_version 3.2.0 %global strscan_version 3.1.6 -%global syntax_suggest_version 2.0.2 +%global syntax_suggest_version 2.0.3 %global tempfile_version 0.3.1 %global time_version 0.4.2 %global timeout_version 0.6.0 @@ -103,7 +103,7 @@ %global weakref_version 0.1.4 %global win32_registry_version 0.1.2 %global yaml_version 0.4.0 -%global zlib_version 3.2.2 +%global zlib_version 3.2.3 # Bundled gems. %global abbrev_version 0.1.2 @@ -129,7 +129,7 @@ %global ostruct_version 0.6.3 %global power_assert_version 3.0.1 %global prime_version 0.1.4 -%global pstore_version 0.2.0 +%global pstore_version 0.2.1 %global racc_version 1.8.1 %global rake_version 13.3.1 %global rbs_version 3.10.0 @@ -186,7 +186,7 @@ Summary: An interpreter of object-oriented scripting language Name: ruby Version: %{ruby_version}%{?development_release} -Release: 31%{?dist} +Release: 32%{?dist} # Licenses, which are likely not included in binary RPMs: # Apache-2.0: # benchmark/gc/redblack.rb @@ -293,6 +293,12 @@ Patch8: ruby-4.0.1-Support-customizable-rustc_flags-for-rustc-builds.patch # https://github.com/ruby/rdoc/pull/1531 # Fix error with `gem install --document=rdoc,ri` Patch9: rdoc-pr1531-fix-mutilple-document-installation.patch +# CVE-2026-33210 +# Fix for Denial of Service or Information Disclosure +# via format string injection +# in Ruby JSON +# https://github.com/ruby/json/commit/393b41c3e5f87491e1e34fa59fa78ff6fa179a74 +Patch10: ruby-4.0.3-Fix-a-format-string-injection-vulnerability.patch Requires: %{name}-libs%{?_isa} = %{version}-%{release} %{?with_rubypick:Suggests: rubypick} @@ -809,6 +815,7 @@ popd %patch -P 6 -p1 %patch -P 7 -p1 %patch -P 8 -p1 +%patch -P 10 -p1 # Provide an example of usage of the tapset: cp -a %{SOURCE3} . @@ -1537,7 +1544,6 @@ make -C %{_vpath_builddir} runruby TESTRUN_SCRIPT=" \ %files doc -f .ruby-doc.en -f .ruby-doc.ja %doc README.md -%doc ChangeLog %{?with_systemtap:%doc ruby-exercise.stp} %{_datadir}/ri @@ -1969,6 +1975,16 @@ make -C %{_vpath_builddir} runruby TESTRUN_SCRIPT=" \ %changelog +* Wed Apr 29 2026 Tomas Juhasz - 4.0.3-32 +- Upgrade to Ruby 4.0.3. + Resolves: RHEL-171933 +- Fix ERB: Arbitrary code execution via deserialization bypass + (CVE-2026-41316) + Resolves: RHEL-171258 +- Fix JSON: Denial of Service or Information Disclosure via format string injection + (CVE-2026-33210) + Resolves: RHEL-173458 + * Thu Jan 15 2026 Jarek Prokop - 4.0.1-31 - Upgrade to Ruby 4.0.1. Resolves: RHEL-142278