diff --git a/.gitignore b/.gitignore
index de44b79..a915dc1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/ruby-3.0.2.tar.xz
+SOURCES/ruby-3.0.4.tar.xz
diff --git a/.ruby.metadata b/.ruby.metadata
index 26f0479..34cda36 100644
--- a/.ruby.metadata
+++ b/.ruby.metadata
@@ -1 +1 @@
-cd04711ed3adecbe244c3b4391e67430d11fa9f8 SOURCES/ruby-3.0.2.tar.xz
+14461adca874d42a06a11851029dec877d9d28de SOURCES/ruby-3.0.4.tar.xz
diff --git a/SOURCES/ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch b/SOURCES/ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch
index 118203c..437d09f 100644
--- a/SOURCES/ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch
+++ b/SOURCES/ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch
@@ -14,7 +14,7 @@ diff --git a/configure.ac b/configure.ac
 index c42436c23d..d261ea57b5 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -3881,7 +3881,8 @@ AS_CASE(["$ruby_version_dir_name"],
+@@ -3886,7 +3886,8 @@ AS_CASE(["$ruby_version_dir_name"],
  ruby_version_dir=/'${ruby_version_dir_name}'
  
  if test -z "${ruby_version_dir_name}"; then
diff --git a/SOURCES/ruby-2.1.0-always-use-i386.patch b/SOURCES/ruby-2.1.0-always-use-i386.patch
index de58295..46584d7 100644
--- a/SOURCES/ruby-2.1.0-always-use-i386.patch
+++ b/SOURCES/ruby-2.1.0-always-use-i386.patch
@@ -11,7 +11,7 @@ diff --git a/configure.ac b/configure.ac
 index 3c13076b82..93af30321d 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -3945,6 +3945,8 @@ AC_SUBST(vendorarchdir)dnl
+@@ -3950,6 +3950,8 @@ AC_SUBST(vendorarchdir)dnl
  AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl
  AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl
  
diff --git a/SOURCES/ruby-2.1.0-custom-rubygems-location.patch b/SOURCES/ruby-2.1.0-custom-rubygems-location.patch
index b7157ff..6946429 100644
--- a/SOURCES/ruby-2.1.0-custom-rubygems-location.patch
+++ b/SOURCES/ruby-2.1.0-custom-rubygems-location.patch
@@ -15,7 +15,7 @@ diff --git a/configure.ac b/configure.ac
 index 93af30321d..bc13397e0e 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -3917,6 +3917,10 @@ AC_ARG_WITH(vendorarchdir,
+@@ -3922,6 +3922,10 @@ AC_ARG_WITH(vendorarchdir,
              [vendorarchdir=$withval],
              [vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby'${ruby_version_dir}}${multiarch-'${vendorlibdir}/${sitearch}'}])
  
@@ -26,7 +26,7 @@ index 93af30321d..bc13397e0e 100644
  AS_IF([test "${LOAD_RELATIVE+set}"], [
      AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE)
      RUBY_EXEC_PREFIX=''
-@@ -3941,6 +3941,7 @@ AC_SUBST(sitearchdir)dnl
+@@ -3946,6 +3950,7 @@ AC_SUBST(sitearchdir)dnl
  AC_SUBST(vendordir)dnl
  AC_SUBST(vendorlibdir)dnl
  AC_SUBST(vendorarchdir)dnl
@@ -75,7 +75,7 @@ index e9110a17ca..76a1f0a315 100755
  mandir = CONFIG["mandir", true]
  docdir = CONFIG["docdir", true]
  enable_shared = CONFIG["ENABLE_SHARED"] == 'yes'
-@@ -581,7 +581,16 @@ def stub
+@@ -581,7 +582,16 @@ def stub
  install?(:local, :comm, :lib) do
    prepare "library scripts", rubylibdir
    noinst = %w[*.txt *.rdoc *.gemspec]
diff --git a/SOURCES/ruby-2.3.0-ruby_version.patch b/SOURCES/ruby-2.3.0-ruby_version.patch
index 4fd6530..fd545e5 100644
--- a/SOURCES/ruby-2.3.0-ruby_version.patch
+++ b/SOURCES/ruby-2.3.0-ruby_version.patch
@@ -20,7 +20,7 @@ diff --git a/configure.ac b/configure.ac
 index 80b137e380..63cd3b4f8b 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -3832,9 +3832,6 @@ AS_CASE(["$target_os"],
+@@ -3837,9 +3837,6 @@ AS_CASE(["$target_os"],
      rubyw_install_name='$(RUBYW_INSTALL_NAME)'
      ])
  
@@ -30,7 +30,7 @@ index 80b137e380..63cd3b4f8b 100644
  rubyarchprefix=${multiarch+'${archlibdir}/${RUBY_BASE_NAME}'}${multiarch-'${rubylibprefix}/${arch}'}
  AC_ARG_WITH(rubyarchprefix,
  	    AS_HELP_STRING([--with-rubyarchprefix=DIR],
-@@ -3857,56 +3857,62 @@ AC_ARG_WITH(ridir,
+@@ -3862,56 +3859,62 @@ AC_ARG_WITH(ridir,
  AC_SUBST(ridir)
  AC_SUBST(RI_BASE_NAME)
  
@@ -120,7 +120,7 @@ index 80b137e380..63cd3b4f8b 100644
  
  AS_IF([test "${LOAD_RELATIVE+set}"], [
      AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE)
-@@ -3923,6 +3923,7 @@ AC_SUBST(sitearchincludedir)dnl
+@@ -3928,6 +3931,7 @@ AC_SUBST(sitearchincludedir)dnl
  AC_SUBST(arch)dnl
  AC_SUBST(sitearch)dnl
  AC_SUBST(ruby_version)dnl
@@ -237,7 +237,7 @@ diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
 index b25068405d..e9fef4a311 100644
 --- a/test/rubygems/test_gem.rb
 +++ b/test/rubygems/test_gem.rb
-@@ -1452,7 +1452,8 @@ def test_self_use_paths
+@@ -1440,7 +1440,8 @@ def test_self_use_paths
  
    def test_self_user_dir
      parts = [@userhome, '.gem', Gem.ruby_engine]
@@ -247,7 +247,7 @@ index b25068405d..e9fef4a311 100644
  
      FileUtils.mkdir_p File.join(parts)
  
-@@ -1530,7 +1531,7 @@ def test_self_vendor_dir
+@@ -1516,7 +1517,7 @@ def test_self_vendor_dir
      vendordir(File.join(@tempdir, 'vendor')) do
        expected =
          File.join RbConfig::CONFIG['vendordir'], 'gems',
diff --git a/SOURCES/ruby-2.3.1-Rely-on-ldd-to-detect-glibc.patch b/SOURCES/ruby-2.3.1-Rely-on-ldd-to-detect-glibc.patch
deleted file mode 100644
index db6737d..0000000
--- a/SOURCES/ruby-2.3.1-Rely-on-ldd-to-detect-glibc.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 346e147ba6480839b87046e9a9efab0bf6ed3660 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
-Date: Wed, 10 Aug 2016 17:35:48 +0200
-Subject: [PATCH] Rely on ldd to detect glibc.
-
-This is just workaround, since we know we are quite sure this will be successful
-on Red Hat platforms.
-
-This workaround rhbz#1361037
----
- test/fiddle/helper.rb |    3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
-index 1da3d93..65148a1 100644
---- a/test/fiddle/helper.rb
-+++ b/test/fiddle/helper.rb
-@@ -139,6 +139,9 @@
-   libc_so = libm_so = "/usr/lib/libSystem.B.dylib"
- end
- 
-+# Just ignore the heuristic, because it is not reliable on all platforms.
-+libc_so = libm_so = nil
-+
- if !libc_so || !libm_so
-   ruby = EnvUtil.rubybin
-   # When the ruby binary is 32-bit and the host is 64-bit,
--- 
-2.9.2
-
diff --git a/SOURCES/ruby-3.1.0-Don-t-query-RubyVM-FrozenCore-for-class-path.patch b/SOURCES/ruby-3.1.0-Don-t-query-RubyVM-FrozenCore-for-class-path.patch
new file mode 100644
index 0000000..f32f306
--- /dev/null
+++ b/SOURCES/ruby-3.1.0-Don-t-query-RubyVM-FrozenCore-for-class-path.patch
@@ -0,0 +1,43 @@
+From 0ade5611df9f981005eed32b369d1e699e520221 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
+Date: Thu, 10 Feb 2022 13:26:44 +0100
+Subject: [PATCH] Don't query `RubyVM::FrozenCore` for class path.
+
+The `RubyVM::FrozenCore` class path is corrupted during GC cycle and
+returns random garbage, which might result in segfault.
+
+But since it is easy to detect the `RubyVM::FrozenCore`, just provide
+the class path explicitly as a workaround.
+
+Other possibility would be to ignore `RubyVM::FrozenCore` simlarly as
+TracePoint API does:
+
+https://github.com/ruby/ruby/blob/46f6575157d4c2f6bbd5693896e26a65037e5552/vm_trace.c#L411
+---
+ vm.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/vm.c b/vm.c
+index 8ce8b279d4..3d189fa63a 100644
+--- a/vm.c
++++ b/vm.c
+@@ -446,7 +446,15 @@ rb_dtrace_setup(rb_execution_context_t *ec, VALUE klass, ID id,
+     }
+     type = BUILTIN_TYPE(klass);
+     if (type == T_CLASS || type == T_ICLASS || type == T_MODULE) {
+-	VALUE name = rb_class_path(klass);
++	VALUE name = Qnil;
++	/*
++	 * Special treatment for rb_mRubyVMFrozenCore wchi is broken by GC.
++         * https://bugs.ruby-lang.org/issues/18257
++	 */
++	if (klass == rb_mRubyVMFrozenCore)
++	    name = rb_str_new_cstr("RubyVM::FrozenCore");
++	else
++	    name = rb_class_path(klass);
+ 	const char *classname, *filename;
+ 	const char *methodname = rb_id2name(id);
+ 	if (methodname && (filename = rb_source_location_cstr(&args->line_no)) != 0) {
+-- 
+2.34.1
+
diff --git a/SOURCES/ruby-3.1.0-Properly-exclude-test-cases.patch b/SOURCES/ruby-3.1.0-Properly-exclude-test-cases.patch
new file mode 100644
index 0000000..ca2cd9b
--- /dev/null
+++ b/SOURCES/ruby-3.1.0-Properly-exclude-test-cases.patch
@@ -0,0 +1,93 @@
+From 96684439e96aa92e10376b5be45f006772028295 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
+Date: Thu, 21 Oct 2021 13:02:38 +0200
+Subject: [PATCH] Properly exclude test cases.
+
+Lets consider the following scenario:
+
+~~~
+irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):001:0> p suite
+OpenSSL::TestEC
+=> OpenSSL::TestEC
+
+irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):002:0> p all_test_methods
+["test_ECPrivateKey", "test_ECPrivateKey_encrypted", "test_PUBKEY", "test_check_key", "test_derive_key", "test_dh_compute_key", "test_dsa_sign_asn1_FIPS186_3", "test_ec_group", "test_ec_key", "test_ec_point", "test_ec_point_add", "test_ec_point_mul", "test_generate", "test_marshal", "test_sign_verify", "test_sign_verify_raw"]
+=>
+["test_ECPrivateKey",
+ "test_ECPrivateKey_encrypted",
+ "test_PUBKEY",
+ "test_check_key",
+ "test_derive_key",
+ "test_dh_compute_key",
+ "test_dsa_sign_asn1_FIPS186_3",
+ "test_ec_group",
+ "test_ec_key",
+ "test_ec_point",
+ "test_ec_point_add",
+ "test_ec_point_mul",
+ "test_generate",
+ "test_marshal",
+ "test_sign_verify",
+ "test_sign_verify_raw"]
+
+irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):003:0> p filter
+/\A(?=.*)(?!.*(?-mix:(?-mix:memory_leak)|(?-mix:OpenSSL::TestEC.test_check_key)))/
+=> /\A(?=.*)(?!.*(?-mix:(?-mix:memory_leak)|(?-mix:OpenSSL::TestEC.test_check_key)))/
+
+irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):004:0> method = "test_check_key"
+=> "test_check_key"
+~~~
+
+The intention here is to exclude the `test_check_key` test case.
+Unfortunately this does not work as expected, because the negative filter
+is never checked:
+
+~~~
+
+irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):005:0> filter === method
+=> true
+
+irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):006:0> filter === "#{suite}##{method}"
+=> false
+
+irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):007:0> filter === method || filter === "#{suite}##{method}"
+=> true
+~~~
+
+Therefore always filter against the fully qualified method name
+`#{suite}##{method}`, which should provide the expected result.
+
+However, if plain string filter is used, keep checking also only the
+method name.
+
+This resolves [Bug #16936].
+---
+ tool/lib/minitest/unit.rb | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/tool/lib/minitest/unit.rb b/tool/lib/minitest/unit.rb
+index c58a609bfa..d5af6cb906 100644
+--- a/tool/lib/minitest/unit.rb
++++ b/tool/lib/minitest/unit.rb
+@@ -956,9 +956,15 @@ def _run_suite suite, type
+ 
+       all_test_methods = suite.send "#{type}_methods"
+ 
+-      filtered_test_methods = all_test_methods.find_all { |m|
+-        filter === m || filter === "#{suite}##{m}"
+-      }
++      filtered_test_methods = if Regexp === filter
++        all_test_methods.find_all { |m|
++          filter === "#{suite}##{m}"
++        }
++      else
++        all_test_methods.find_all {|m|
++          filter === m || filter === "#{suite}##{m}"
++        }
++      end
+ 
+       leakchecker = LeakChecker.new
+ 
+-- 
+2.32.0
+
diff --git a/SOURCES/ruby-3.1.0-Support-GCCs-DWARF-5.patch b/SOURCES/ruby-3.1.0-Support-GCCs-DWARF-5.patch
new file mode 100644
index 0000000..d9b434a
--- /dev/null
+++ b/SOURCES/ruby-3.1.0-Support-GCCs-DWARF-5.patch
@@ -0,0 +1,229 @@
+From 3b91792d3d644d6d6b0059cb315c9fe5d3626bab Mon Sep 17 00:00:00 2001
+From: Yusuke Endoh <mame@ruby-lang.org>
+Date: Sat, 6 Mar 2021 00:03:57 +0900
+Subject: [PATCH] Support GCC's DWARF 5 [Bug #17585]
+
+Co-Authored-By: xtkoba (Tee KOBAYASHI) <xtkoba+ruby@gmail.com>
+---
+ addr2line.c | 119 ++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 97 insertions(+), 22 deletions(-)
+
+diff --git a/addr2line.c b/addr2line.c
+index 0029cffbca..855efb40d4 100644
+--- a/addr2line.c
++++ b/addr2line.c
+@@ -159,11 +159,12 @@ typedef struct obj_info {
+     struct dwarf_section debug_info;
+     struct dwarf_section debug_line;
+     struct dwarf_section debug_ranges;
++    struct dwarf_section debug_rnglists;
+     struct dwarf_section debug_str;
+     struct obj_info *next;
+ } obj_info_t;
+ 
+-#define DWARF_SECTION_COUNT 5
++#define DWARF_SECTION_COUNT 6
+ 
+ static struct dwarf_section *
+ obj_dwarf_section_at(obj_info_t *obj, int n)
+@@ -173,6 +174,7 @@ obj_dwarf_section_at(obj_info_t *obj, int n)
+         &obj->debug_info,
+         &obj->debug_line,
+         &obj->debug_ranges,
++        &obj->debug_rnglists,
+         &obj->debug_str
+     };
+     if (n < 0 || DWARF_SECTION_COUNT <= n) {
+@@ -411,7 +413,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
+ 	    FILL_LINE();
+ 	    break;
+ 	case DW_LNS_advance_pc:
+-	    a = uleb128((char **)&p);
++	    a = uleb128((char **)&p) * header.minimum_instruction_length;
+ 	    addr += a;
+ 	    break;
+ 	case DW_LNS_advance_line: {
+@@ -451,7 +453,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
+ 	    /* isa = (unsigned int)*/(void)uleb128((char **)&p);
+ 	    break;
+ 	case 0:
+-	    a = *(unsigned char *)p++;
++	    a = uleb128((char **)&p);
+ 	    op = *p++;
+ 	    switch (op) {
+ 	    case DW_LNE_end_sequence:
+@@ -808,6 +810,18 @@ enum
+     DW_FORM_addrx4 = 0x2c
+ };
+ 
++/* Range list entry encodings */
++enum {
++    DW_RLE_end_of_list = 0x00,
++    DW_RLE_base_addressx = 0x01,
++    DW_RLE_startx_endx = 0x02,
++    DW_RLE_startx_length = 0x03,
++    DW_RLE_offset_pair = 0x04,
++    DW_RLE_base_address = 0x05,
++    DW_RLE_start_end = 0x06,
++    DW_RLE_start_length = 0x07
++};
++
+ enum {
+     VAL_none = 0,
+     VAL_cstr = 1,
+@@ -961,6 +975,23 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
+     reader->current_low_pc = 0;
+ }
+ 
++static void
++di_skip_die_attributes(char **p)
++{
++    for (;;) {
++        uint64_t at = uleb128(p);
++        uint64_t form = uleb128(p);
++        if (!at && !form) break;
++        switch (form) {
++          default:
++            break;
++          case DW_FORM_implicit_const:
++            sleb128(p);
++            break;
++        }
++    }
++}
++
+ static void
+ di_read_debug_abbrev_cu(DebugInfoReader *reader)
+ {
+@@ -975,12 +1006,7 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader)
+         prev = abbrev_number;
+         uleb128(&p); /* tag */
+         p++; /* has_children */
+-        /* skip content */
+-        for (;;) {
+-            uint64_t at = uleb128(&p);
+-            uint64_t form = uleb128(&p);
+-            if (!at && !form) break;
+-        }
++        di_skip_die_attributes(&p);
+     }
+ }
+ 
+@@ -1244,12 +1270,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
+     /* skip 255th record */
+     uleb128(&p); /* tag */
+     p++; /* has_children */
+-    /* skip content */
+-    for (;;) {
+-        uint64_t at = uleb128(&p);
+-        uint64_t form = uleb128(&p);
+-        if (!at && !form) break;
+-    }
++    di_skip_die_attributes(&p);
+     for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) {
+         if (n == 0) {
+             fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
+@@ -1257,12 +1278,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
+         }
+         uleb128(&p); /* tag */
+         p++; /* has_children */
+-        /* skip content */
+-        for (;;) {
+-            uint64_t at = uleb128(&p);
+-            uint64_t form = uleb128(&p);
+-            if (!at && !form) break;
+-        }
++        di_skip_die_attributes(&p);
+     }
+     return p;
+ }
+@@ -1390,6 +1406,21 @@ ranges_set(ranges_t *ptr, DebugInfoValue *v)
+     }
+ }
+ 
++static uint64_t
++read_dw_form_addr(DebugInfoReader *reader, char **ptr)
++{
++    char *p = *ptr;
++    *ptr = p + reader->format;
++    if (reader->format == 4) {
++        return read_uint32(&p);
++    } else if (reader->format == 8) {
++        return read_uint64(&p);
++    } else {
++        fprintf(stderr,"unknown address_size:%d", reader->address_size);
++        abort();
++    }
++}
++
+ static uintptr_t
+ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
+ {
+@@ -1403,8 +1434,50 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
+     }
+     else if (ptr->ranges_set) {
+         /* TODO: support base address selection entry */
+-        char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
++        char *p;
+         uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc;
++        if (reader->obj->debug_rnglists.ptr) {
++            p = reader->obj->debug_rnglists.ptr + ptr->ranges;
++            for (;;) {
++                uint8_t rle = read_uint8(&p);
++                uintptr_t base_address = 0;
++                uintptr_t from, to;
++                if (rle == DW_RLE_end_of_list) break;
++                switch (rle) {
++                  case DW_RLE_base_addressx:
++                    uleb128(&p);
++                    break;
++                  case DW_RLE_startx_endx:
++                    uleb128(&p);
++                    uleb128(&p);
++                    break;
++                  case DW_RLE_startx_length:
++                    uleb128(&p);
++                    uleb128(&p);
++                    break;
++                  case DW_RLE_offset_pair:
++                    from = base_address + uleb128(&p);
++                    to = base_address + uleb128(&p);
++                    if (base + from <= addr && addr < base + to) {
++                        return from;
++                    }
++                    break;
++                  case DW_RLE_base_address:
++                    base_address = read_dw_form_addr(reader, &p);
++                    break;
++                  case DW_RLE_start_end:
++                    read_dw_form_addr(reader, &p);
++                    read_dw_form_addr(reader, &p);
++                    break;
++                  case DW_RLE_start_length:
++                    read_dw_form_addr(reader, &p);
++                    uleb128(&p);
++                    break;
++                }
++            }
++            return false;
++        }
++        p = reader->obj->debug_ranges.ptr + ptr->ranges;
+         for (;;) {
+             uintptr_t from = read_uintptr(&p);
+             uintptr_t to = read_uintptr(&p);
+@@ -1750,6 +1823,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
+                     ".debug_info",
+                     ".debug_line",
+                     ".debug_ranges",
++                    ".debug_rnglists",
+                     ".debug_str"
+                 };
+ 
+@@ -2006,6 +2080,7 @@ found_mach_header:
+                     "__debug_info",
+                     "__debug_line",
+                     "__debug_ranges",
++                    "__debug_rnglists",
+                     "__debug_str"
+                 };
+                 struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd;
diff --git a/SOURCES/ruby-3.1.0-Use-mmap-for-allocating-heap-pages-in-the-GC.patch b/SOURCES/ruby-3.1.0-Use-mmap-for-allocating-heap-pages-in-the-GC.patch
new file mode 100644
index 0000000..512be18
--- /dev/null
+++ b/SOURCES/ruby-3.1.0-Use-mmap-for-allocating-heap-pages-in-the-GC.patch
@@ -0,0 +1,359 @@
+From bcab8c3cd877506de75f50e0f9ed98827ed554b0 Mon Sep 17 00:00:00 2001
+From: Peter Zhu <peter@peterzhu.ca>
+Date: Tue, 23 Feb 2021 16:28:56 -0500
+Subject: [PATCH] Use mmap for allocating heap pages
+
+---
+ configure.ac                 |  16 ++++
+ gc.c                         | 149 ++++++++++++++++++++++++++---------
+ test/ruby/test_gc_compact.rb |  41 ++++++----
+ 3 files changed, 155 insertions(+), 51 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 2dcebdde9f..b1b190004d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1944,6 +1944,7 @@ AC_CHECK_FUNCS(memmem)
+ AC_CHECK_FUNCS(mkfifo)
+ AC_CHECK_FUNCS(mknod)
+ AC_CHECK_FUNCS(mktime)
++AC_CHECK_FUNCS(mmap)
+ AC_CHECK_FUNCS(openat)
+ AC_CHECK_FUNCS(pipe2)
+ AC_CHECK_FUNCS(poll)
+@@ -2666,6 +2667,21 @@ main(int argc, char *argv[])
+ 	rb_cv_fork_with_pthread=yes)])
+     test x$rb_cv_fork_with_pthread = xyes || AC_DEFINE(CANNOT_FORK_WITH_PTHREAD)
+ ])
++
++AC_CHECK_HEADERS([sys/user.h])
++AS_IF([test "x$ac_cv_func_mmap" = xyes], [
++    AC_CACHE_CHECK([whether PAGE_SIZE is compile-time const], rb_cv_const_page_size,
++	[malloc_headers=`sed -n '/MALLOC_HEADERS_BEGIN/,/MALLOC_HEADERS_END/p' ${srcdir}/gc.c`
++	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$malloc_headers
++            typedef char conftest_page[PAGE_SIZE];
++        ]], [[]])],
++        [rb_cv_const_page_size=yes],
++        [rb_cv_const_page_size=no])])
++])
++AS_IF([test "x$rb_cv_const_page_size" = xyes],
++    [AC_DEFINE(HAVE_CONST_PAGE_SIZE, 1)],
++    [AC_DEFINE(HAVE_CONST_PAGE_SIZE, 0)]
++)
+ }
+ 
+ : "runtime section" && {
+diff --git a/gc.c b/gc.c
+index f6acf3e117..6f8e5f242d 100644
+--- a/gc.c
++++ b/gc.c
+@@ -32,6 +32,7 @@
+ #include <stdarg.h>
+ #include <stdio.h>
+ 
++/* MALLOC_HEADERS_BEGIN */
+ #ifndef HAVE_MALLOC_USABLE_SIZE
+ # ifdef _WIN32
+ #  define HAVE_MALLOC_USABLE_SIZE
+@@ -54,6 +55,12 @@
+ # endif
+ #endif
+ 
++#if !defined(PAGE_SIZE) && defined(HAVE_SYS_USER_H)
++/* LIST_HEAD conflicts with sys/queue.h on macOS */
++# include <sys/user.h>
++#endif
++/* MALLOC_HEADERS_END */
++
+ #ifdef HAVE_SYS_TIME_H
+ # include <sys/time.h>
+ #endif
+@@ -821,6 +828,25 @@ enum {
+     HEAP_PAGE_BITMAP_SIZE = (BITS_SIZE * HEAP_PAGE_BITMAP_LIMIT),
+     HEAP_PAGE_BITMAP_PLANES = 4 /* RGENGC: mark, unprotected, uncollectible, marking */
+ };
++#define HEAP_PAGE_ALIGN (1 << HEAP_PAGE_ALIGN_LOG)
++#define HEAP_PAGE_SIZE HEAP_PAGE_ALIGN
++
++#ifdef HAVE_MMAP
++# if HAVE_CONST_PAGE_SIZE
++/* If we have the HEAP_PAGE and it is a constant, then we can directly use it. */
++static const bool USE_MMAP_ALIGNED_ALLOC = (PAGE_SIZE <= HEAP_PAGE_SIZE);
++# elif defined(PAGE_MAX_SIZE) && (PAGE_MAX_SIZE <= HEAP_PAGE_SIZE)
++/* PAGE_SIZE <= HEAP_PAGE_SIZE */
++static const bool USE_MMAP_ALIGNED_ALLOC = true;
++# else
++/* Otherwise, fall back to determining if we can use mmap during runtime. */
++#  define USE_MMAP_ALIGNED_ALLOC (use_mmap_aligned_alloc != false)
++
++static bool use_mmap_aligned_alloc;
++# endif
++#elif !defined(__MINGW32__) && !defined(_WIN32)
++static const bool USE_MMAP_ALIGNED_ALLOC = false;
++#endif
+ 
+ struct heap_page {
+     short total_slots;
+@@ -1760,14 +1786,14 @@ heap_unlink_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *pag
+     heap->total_slots -= page->total_slots;
+ }
+ 
+-static void rb_aligned_free(void *ptr);
++static void rb_aligned_free(void *ptr, size_t size);
+ 
+ static void
+ heap_page_free(rb_objspace_t *objspace, struct heap_page *page)
+ {
+     heap_allocated_pages--;
+     objspace->profile.total_freed_pages++;
+-    rb_aligned_free(GET_PAGE_BODY(page->start));
++    rb_aligned_free(GET_PAGE_BODY(page->start), HEAP_PAGE_SIZE);
+     free(page);
+ }
+ 
+@@ -1819,7 +1845,7 @@ heap_page_allocate(rb_objspace_t *objspace)
+     /* assign heap_page entry */
+     page = calloc1(sizeof(struct heap_page));
+     if (page == 0) {
+-        rb_aligned_free(page_body);
++        rb_aligned_free(page_body, HEAP_PAGE_SIZE);
+ 	rb_memerror();
+     }
+ 
+@@ -3159,15 +3185,18 @@ Init_heap(void)
+ {
+     rb_objspace_t *objspace = &rb_objspace;
+ 
+-#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+-    /* If Ruby's heap pages are not a multiple of the system page size, we
+-     * cannot use mprotect for the read barrier, so we must disable automatic
+-     * compaction. */
+-    int pagesize;
+-    pagesize = (int)sysconf(_SC_PAGE_SIZE);
+-    if ((HEAP_PAGE_SIZE % pagesize) != 0) {
+-        ruby_enable_autocompact = 0;
+-    }
++#if defined(HAVE_MMAP) && !HAVE_CONST_PAGE_SIZE && !defined(PAGE_MAX_SIZE)
++    /* Need to determine if we can use mmap at runtime. */
++# ifdef PAGE_SIZE
++    /* If the PAGE_SIZE macro can be used. */
++    use_mmap_aligned_alloc = PAGE_SIZE <= HEAP_PAGE_SIZE;
++# elif defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
++    /* If we can use sysconf to determine the page size. */
++    use_mmap_aligned_alloc = sysconf(_SC_PAGE_SIZE) <= HEAP_PAGE_SIZE;
++# else
++    /* Otherwise we can't determine the system page size, so don't use mmap. */
++    use_mmap_aligned_alloc = FALSE;
++# endif
+ #endif
+ 
+     objspace->next_object_id = INT2FIX(OBJ_ID_INITIAL);
+@@ -8533,6 +8562,14 @@ gc_start_internal(rb_execution_context_t *ec, VALUE self, VALUE full_mark, VALUE
+ 
+     /* For now, compact implies full mark / sweep, so ignore other flags */
+     if (RTEST(compact)) {
++        /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for
++         * the read barrier, so we must disable compaction. */
++#if !defined(__MINGW32__) && !defined(_WIN32)
++        if (!USE_MMAP_ALIGNED_ALLOC) {
++            rb_raise(rb_eNotImpError, "Compaction isn't available on this platform");
++        }
++#endif
++
+         reason |= GPR_FLAG_COMPACT;
+     } else {
+         if (!RTEST(full_mark))       reason &= ~GPR_FLAG_FULL_MARK;
+@@ -9944,16 +9981,14 @@ gc_disable(rb_execution_context_t *ec, VALUE _)
+ static VALUE
+ gc_set_auto_compact(rb_execution_context_t *ec, VALUE _, VALUE v)
+ {
+-#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+-    /* If Ruby's heap pages are not a multiple of the system page size, we
+-     * cannot use mprotect for the read barrier, so we must disable automatic
+-     * compaction. */
+-    int pagesize;
+-    pagesize = (int)sysconf(_SC_PAGE_SIZE);
+-    if ((HEAP_PAGE_SIZE % pagesize) != 0) {
++    /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for
++     * the read barrier, so we must disable automatic compaction. */
++#if !defined(__MINGW32__) && !defined(_WIN32)
++    if (!USE_MMAP_ALIGNED_ALLOC) {
+         rb_raise(rb_eNotImpError, "Automatic compaction isn't available on this platform");
+     }
+ #endif
++
+     ruby_enable_autocompact = RTEST(v);
+     return v;
+ }
+@@ -10350,22 +10385,54 @@ rb_aligned_malloc(size_t alignment, size_t size)
+ #elif defined _WIN32
+     void *_aligned_malloc(size_t, size_t);
+     res = _aligned_malloc(size, alignment);
+-#elif defined(HAVE_POSIX_MEMALIGN)
+-    if (posix_memalign(&res, alignment, size) == 0) {
+-        return res;
++#else
++    if (USE_MMAP_ALIGNED_ALLOC) {
++        GC_ASSERT(alignment % sysconf(_SC_PAGE_SIZE) == 0);
++
++        char *ptr = mmap(NULL, alignment + size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
++        if (ptr == MAP_FAILED) {
++            return NULL;
++        }
++
++        char *aligned = ptr + alignment;
++        aligned -= ((VALUE)aligned & (alignment - 1));
++        GC_ASSERT(aligned > ptr);
++        GC_ASSERT(aligned <= ptr + alignment);
++
++        size_t start_out_of_range_size = aligned - ptr;
++        GC_ASSERT(start_out_of_range_size % sysconf(_SC_PAGE_SIZE) == 0);
++        if (start_out_of_range_size > 0) {
++            if (munmap(ptr, start_out_of_range_size)) {
++                rb_bug("rb_aligned_malloc: munmap failed for start");
++            }
++        }
++
++        size_t end_out_of_range_size = alignment - start_out_of_range_size;
++        GC_ASSERT(end_out_of_range_size % sysconf(_SC_PAGE_SIZE) == 0);
++        if (end_out_of_range_size > 0) {
++            if (munmap(aligned + size, end_out_of_range_size)) {
++                rb_bug("rb_aligned_malloc: munmap failed for end");
++            }
++        }
++
++        res = (void *)aligned;
+     }
+     else {
+-        return NULL;
++# if defined(HAVE_POSIX_MEMALIGN)
++        if (posix_memalign(&res, alignment, size) != 0) {
++            return NULL;
++        }
++# elif defined(HAVE_MEMALIGN)
++        res = memalign(alignment, size);
++# else
++        char* aligned;
++        res = malloc(alignment + size + sizeof(void*));
++        aligned = (char*)res + alignment + sizeof(void*);
++        aligned -= ((VALUE)aligned & (alignment - 1));
++        ((void**)aligned)[-1] = res;
++        res = (void*)aligned;
++# endif
+     }
+-#elif defined(HAVE_MEMALIGN)
+-    res = memalign(alignment, size);
+-#else
+-    char* aligned;
+-    res = malloc(alignment + size + sizeof(void*));
+-    aligned = (char*)res + alignment + sizeof(void*);
+-    aligned -= ((VALUE)aligned & (alignment - 1));
+-    ((void**)aligned)[-1] = res;
+-    res = (void*)aligned;
+ #endif
+ 
+     /* alignment must be a power of 2 */
+@@ -10375,16 +10442,26 @@ rb_aligned_malloc(size_t alignment, size_t size)
+ }
+ 
+ static void
+-rb_aligned_free(void *ptr)
++rb_aligned_free(void *ptr, size_t size)
+ {
+ #if defined __MINGW32__
+     __mingw_aligned_free(ptr);
+ #elif defined _WIN32
+     _aligned_free(ptr);
+-#elif defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN)
+-    free(ptr);
+ #else
+-    free(((void**)ptr)[-1]);
++    if (USE_MMAP_ALIGNED_ALLOC) {
++        GC_ASSERT(size % sysconf(_SC_PAGE_SIZE) == 0);
++        if (munmap(ptr, size)) {
++            rb_bug("rb_aligned_free: munmap failed");
++        }
++    }
++    else {
++# if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_MEMALIGN)
++        free(ptr);
++# else
++        free(((void**)ptr)[-1]);
++# endif
++    }
+ #endif
+ }
+ 
+diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
+index 4a8cff33f4..f5cab55ba7 100644
+--- a/test/ruby/test_gc_compact.rb
++++ b/test/ruby/test_gc_compact.rb
+@@ -4,12 +4,32 @@
+ require 'etc'
+ 
+ class TestGCCompact < Test::Unit::TestCase
+-  class AutoCompact < Test::Unit::TestCase
++  module SupportsCompact
+     def setup
+       skip "autocompact not supported on this platform" unless supports_auto_compact?
+       super
+     end
+ 
++    private
++
++    def supports_auto_compact?
++      return true unless defined?(Etc::SC_PAGE_SIZE)
++
++      begin
++        return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0
++      rescue NotImplementedError
++      rescue ArgumentError
++      end
++
++      true
++    end
++  end
++
++  include SupportsCompact
++
++  class AutoCompact < Test::Unit::TestCase
++    include SupportsCompact
++
+     def test_enable_autocompact
+       before = GC.auto_compact
+       GC.auto_compact = true
+@@ -59,26 +79,17 @@ def test_implicit_compaction_does_something
+     ensure
+       GC.auto_compact = before
+     end
+-
+-    private
+-
+-    def supports_auto_compact?
+-      return true unless defined?(Etc::SC_PAGE_SIZE)
+-
+-      begin
+-        return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0
+-      rescue NotImplementedError
+-      rescue ArgumentError
+-      end
+-
+-      true
+-    end
+   end
+ 
+   def os_page_size
+     return true unless defined?(Etc::SC_PAGE_SIZE)
+   end
+ 
++  def setup
++    skip "autocompact not supported on this platform" unless supports_auto_compact?
++    super
++  end
++
+   def test_gc_compact_stats
+     list = []
+ 
+-- 
+2.30.1 (Apple Git-130)
+
diff --git a/SOURCES/ruby-dwarf5-avoid_crash-r1.patch b/SOURCES/ruby-dwarf5-avoid_crash-r1.patch
deleted file mode 100644
index c14642b..0000000
--- a/SOURCES/ruby-dwarf5-avoid_crash-r1.patch
+++ /dev/null
@@ -1,217 +0,0 @@
---- a/addr2line.c
-+++ b/addr2line.c
-@@ -159,11 +159,12 @@
-     struct dwarf_section debug_info;
-     struct dwarf_section debug_line;
-     struct dwarf_section debug_ranges;
-+    struct dwarf_section debug_rnglists;
-     struct dwarf_section debug_str;
-     struct obj_info *next;
- } obj_info_t;
- 
--#define DWARF_SECTION_COUNT 5
-+#define DWARF_SECTION_COUNT 6
- 
- static struct dwarf_section *
- obj_dwarf_section_at(obj_info_t *obj, int n)
-@@ -173,6 +174,7 @@
-         &obj->debug_info,
-         &obj->debug_line,
-         &obj->debug_ranges,
-+        &obj->debug_rnglists,
-         &obj->debug_str
-     };
-     if (n < 0 || DWARF_SECTION_COUNT <= n) {
-@@ -411,7 +413,7 @@
- 	    FILL_LINE();
- 	    break;
- 	case DW_LNS_advance_pc:
--	    a = uleb128((char **)&p);
-+	    a = uleb128((char **)&p) * header.minimum_instruction_length;
- 	    addr += a;
- 	    break;
- 	case DW_LNS_advance_line: {
-@@ -450,7 +452,7 @@
- 	    /* isa = (unsigned int)*/(void)uleb128((char **)&p);
- 	    break;
- 	case 0:
--	    a = *(unsigned char *)p++;
-+	    a = uleb128((char **)&p);
- 	    op = *p++;
- 	    switch (op) {
- 	    case DW_LNE_end_sequence:
-@@ -807,6 +809,18 @@
-     DW_FORM_addrx4 = 0x2c
- };
- 
-+/* Range list entry encodings */
-+enum {
-+    DW_RLE_end_of_list = 0x00,
-+    DW_RLE_base_addressx = 0x01,
-+    DW_RLE_startx_endx = 0x02,
-+    DW_RLE_startx_length = 0x03,
-+    DW_RLE_offset_pair = 0x04,
-+    DW_RLE_base_address = 0x05,
-+    DW_RLE_start_end = 0x06,
-+    DW_RLE_start_length = 0x07
-+};
-+
- enum {
-     VAL_none = 0,
-     VAL_cstr = 1,
-@@ -961,6 +975,23 @@
- }
- 
- static void
-+di_skip_die_attributes(char **p)
-+{
-+    for (;;) {
-+        uint64_t at = uleb128(p);
-+        uint64_t form = uleb128(p);
-+        if (!at && !form) break;
-+        switch (form) {
-+          default:
-+            break;
-+          case DW_FORM_implicit_const:
-+            sleb128(p);
-+            break;
-+        }
-+    }
-+}
-+
-+static void
- di_read_debug_abbrev_cu(DebugInfoReader *reader)
- {
-     uint64_t prev = 0;
-@@ -974,12 +1005,7 @@
-         prev = abbrev_number;
-         uleb128(&p); /* tag */
-         p++; /* has_children */
--        /* skip content */
--        for (;;) {
--            uint64_t at = uleb128(&p);
--            uint64_t form = uleb128(&p);
--            if (!at && !form) break;
--        }
-+        di_skip_die_attributes(&p);
-     }
- }
- 
-@@ -1243,12 +1269,7 @@
-     /* skip 255th record */
-     uleb128(&p); /* tag */
-     p++; /* has_children */
--    /* skip content */
--    for (;;) {
--        uint64_t at = uleb128(&p);
--        uint64_t form = uleb128(&p);
--        if (!at && !form) break;
--    }
-+    di_skip_die_attributes(&p);
-     for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) {
-         if (n == 0) {
-             fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
-@@ -1256,12 +1277,7 @@
-         }
-         uleb128(&p); /* tag */
-         p++; /* has_children */
--        /* skip content */
--        for (;;) {
--            uint64_t at = uleb128(&p);
--            uint64_t form = uleb128(&p);
--            if (!at && !form) break;
--        }
-+        di_skip_die_attributes(&p);
-     }
-     return p;
- }
-@@ -1389,6 +1405,21 @@
-     }
- }
- 
-+static uint64_t
-+read_dw_form_addr(DebugInfoReader *reader, char **ptr)
-+{
-+    char *p = *ptr;
-+    *ptr = p + reader->format;
-+    if (reader->format == 4) {
-+        return read_uint32(&p);
-+    } else if (reader->format == 8) {
-+        return read_uint64(&p);
-+    } else {
-+        fprintf(stderr,"unknown address_size:%d", reader->address_size);
-+        abort();
-+    }
-+}
-+
- static uintptr_t
- ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
- {
-@@ -1402,8 +1433,50 @@
-     }
-     else if (ptr->ranges_set) {
-         /* TODO: support base address selection entry */
--        char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
-+        char *p;
-         uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc;
-+        if (reader->obj->debug_rnglists.ptr) {
-+            p = reader->obj->debug_rnglists.ptr + ptr->ranges;
-+            for (;;) {
-+                uint8_t rle = read_uint8(&p);
-+                uintptr_t base_address = 0;
-+                uintptr_t from, to;
-+                if (rle == DW_RLE_end_of_list) break;
-+                switch (rle) {
-+                  case DW_RLE_base_addressx:
-+                    uleb128(&p);
-+                    break;
-+                  case DW_RLE_startx_endx:
-+                    uleb128(&p);
-+                    uleb128(&p);
-+                    break;
-+                  case DW_RLE_startx_length:
-+                    uleb128(&p);
-+                    uleb128(&p);
-+                    break;
-+                  case DW_RLE_offset_pair:
-+                    from = base_address + uleb128(&p);
-+                    to = base_address + uleb128(&p);
-+                    if (base + from <= addr && addr < base + to) {
-+                        return from;
-+                    }
-+                    break;
-+                  case DW_RLE_base_address:
-+                    base_address = read_dw_form_addr(reader, &p);
-+                    break;
-+                  case DW_RLE_start_end:
-+                    read_dw_form_addr(reader, &p);
-+                    read_dw_form_addr(reader, &p);
-+                    break;
-+                  case DW_RLE_start_length:
-+                    read_dw_form_addr(reader, &p);
-+                    uleb128(&p);
-+                    break;
-+                }
-+            }
-+            return false;
-+        }
-+        p = reader->obj->debug_ranges.ptr + ptr->ranges;
-         for (;;) {
-             uintptr_t from = read_uintptr(&p);
-             uintptr_t to = read_uintptr(&p);
-@@ -1747,6 +1820,7 @@
-                     ".debug_info",
-                     ".debug_line",
-                     ".debug_ranges",
-+                    ".debug_rnglists",
-                     ".debug_str"
-                 };
- 
-@@ -2003,6 +2077,7 @@
-                     "__debug_info",
-                     "__debug_line",
-                     "__debug_ranges",
-+                    "__debug_rnglists",
-                     "__debug_str"
-                 };
-                 struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd;
diff --git a/SOURCES/rubygems-3.2.33-Fix-loading-operating_system-rb-customizations-too-late.patch b/SOURCES/rubygems-3.2.33-Fix-loading-operating_system-rb-customizations-too-late.patch
new file mode 100644
index 0000000..d5a0673
--- /dev/null
+++ b/SOURCES/rubygems-3.2.33-Fix-loading-operating_system-rb-customizations-too-late.patch
@@ -0,0 +1,261 @@
+From e80e7a3d0b3d72f7af7286b935702b3fab117008 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
+Date: Wed, 8 Dec 2021 21:12:24 +0100
+Subject: [PATCH 1/5] More explicit require
+
+This class does not use `rubygems/deprecate`. It uses
+`rubygems/version`, which in turn uses `rubygems/deprecate`. Make this
+explicit.
+---
+ lib/rubygems/requirement.rb | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
+index d2e28fab5b4..9edd6aa7d3c 100644
+--- a/lib/rubygems/requirement.rb
++++ b/lib/rubygems/requirement.rb
+@@ -1,5 +1,5 @@
+ # frozen_string_literal: true
+-require_relative "deprecate"
++require_relative "version"
+ 
+ ##
+ # A Requirement is a set of one or more version restrictions. It supports a
+
+From 4e46dcc17ee5cabbde43b8a34063b8ab042536f9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
+Date: Wed, 8 Dec 2021 21:17:30 +0100
+Subject: [PATCH 2/5] Remove ineffective autoloads
+
+These files are loaded on startup unconditionally, so we can require
+them relatively when needed.
+---
+ lib/rubygems.rb               | 4 +---
+ lib/rubygems/specification.rb | 2 ++
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/lib/rubygems.rb b/lib/rubygems.rb
+index f803e47628e..b8747409304 100644
+--- a/lib/rubygems.rb
++++ b/lib/rubygems.rb
+@@ -1310,19 +1310,17 @@ def default_gem_load_paths
+   autoload :Licenses,           File.expand_path('rubygems/util/licenses', __dir__)
+   autoload :NameTuple,          File.expand_path('rubygems/name_tuple', __dir__)
+   autoload :PathSupport,        File.expand_path('rubygems/path_support', __dir__)
+-  autoload :Platform,           File.expand_path('rubygems/platform', __dir__)
+   autoload :RequestSet,         File.expand_path('rubygems/request_set', __dir__)
+-  autoload :Requirement,        File.expand_path('rubygems/requirement', __dir__)
+   autoload :Resolver,           File.expand_path('rubygems/resolver', __dir__)
+   autoload :Source,             File.expand_path('rubygems/source', __dir__)
+   autoload :SourceList,         File.expand_path('rubygems/source_list', __dir__)
+   autoload :SpecFetcher,        File.expand_path('rubygems/spec_fetcher', __dir__)
+-  autoload :Specification,      File.expand_path('rubygems/specification', __dir__)
+   autoload :Util,               File.expand_path('rubygems/util', __dir__)
+   autoload :Version,            File.expand_path('rubygems/version', __dir__)
+ end
+ 
+ require_relative 'rubygems/exceptions'
++require_relative 'rubygems/specification'
+ 
+ # REFACTOR: This should be pulled out into some kind of hacks file.
+ begin
+diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
+index d3b96491a28..dc5e5ba0138 100644
+--- a/lib/rubygems/specification.rb
++++ b/lib/rubygems/specification.rb
+@@ -9,6 +9,8 @@
+ require_relative 'deprecate'
+ require_relative 'basic_specification'
+ require_relative 'stub_specification'
++require_relative 'platform'
++require_relative 'requirement'
+ require_relative 'specification_policy'
+ require_relative 'util/list'
+ 
+
+From 96b6b3e04e8e4fec17f63079a0caf999a2709d71 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
+Date: Wed, 8 Dec 2021 21:45:16 +0100
+Subject: [PATCH 3/5] Load `operating_system.rb` customizations before setting
+ up default gems
+
+It's very common for packagers to configure gem paths in this file, for
+example, `Gem.default_dir`. Also, setting up default gems requires these
+paths to be set, so that we know which default gems need to be setup.
+
+If we setup default gems before loading `operatin_system.rb`
+customizations, the wrong default gems will be setup.
+
+Unfortunately, default gems loaded by `operating_system.rb` can't be
+upgraded if we do this, but it seems much of a smaller issue. I wasn't
+even fully sure it was the right thing to do when I added that, and it
+was not the culprit of the end user issue that led to making that
+change.
+---
+ lib/rubygems.rb                | 32 ++++++++++++++++----------------
+ test/rubygems/test_rubygems.rb | 23 +++++++++++++++++++++++
+ 2 files changed, 39 insertions(+), 16 deletions(-)
+
+diff --git a/lib/rubygems.rb b/lib/rubygems.rb
+index b8747409304..11474b6554c 100644
+--- a/lib/rubygems.rb
++++ b/lib/rubygems.rb
+@@ -1323,22 +1323,6 @@ def default_gem_load_paths
+ require_relative 'rubygems/specification'
+ 
+ # REFACTOR: This should be pulled out into some kind of hacks file.
+-begin
+-  ##
+-  # Defaults the Ruby implementation wants to provide for RubyGems
+-
+-  require "rubygems/defaults/#{RUBY_ENGINE}"
+-rescue LoadError
+-end
+-
+-##
+-# Loads the default specs.
+-Gem::Specification.load_defaults
+-
+-require_relative 'rubygems/core_ext/kernel_gem'
+-require_relative 'rubygems/core_ext/kernel_require'
+-require_relative 'rubygems/core_ext/kernel_warn'
+-
+ begin
+   ##
+   # Defaults the operating system (or packager) wants to provide for RubyGems.
+@@ -1354,3 +1338,19 @@ def default_gem_load_paths
+     "the problem and ask for help."
+   raise e.class, msg
+ end
++
++begin
++  ##
++  # Defaults the Ruby implementation wants to provide for RubyGems
++
++  require "rubygems/defaults/#{RUBY_ENGINE}"
++rescue LoadError
++end
++
++##
++# Loads the default specs.
++Gem::Specification.load_defaults
++
++require_relative 'rubygems/core_ext/kernel_gem'
++require_relative 'rubygems/core_ext/kernel_require'
++require_relative 'rubygems/core_ext/kernel_warn'
+diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb
+index 493b9fdf4a3..fa77a299322 100644
+--- a/test/rubygems/test_rubygems.rb
++++ b/test/rubygems/test_rubygems.rb
+@@ -22,6 +22,29 @@ def test_operating_system_other_exceptions
+     "the problem and ask for help."
+   end
+ 
++  def test_operating_system_customizing_default_dir
++    pend "does not apply to truffleruby" if RUBY_ENGINE == 'truffleruby'
++    pend "loads a custom defaults/jruby file that gets in the middle" if RUBY_ENGINE == 'jruby'
++
++    # On a non existing default dir, there should be no gems
++
++    path = util_install_operating_system_rb <<-RUBY
++      module Gem
++        def self.default_dir
++          File.expand_path("foo")
++        end
++      end
++    RUBY
++
++    output = Gem::Util.popen(
++      *ruby_with_rubygems_and_fake_operating_system_in_load_path(path),
++      '-e',
++      "require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)",
++      {:err => [:child, :out]}
++    ).strip
++    assert_empty output
++  end
++
+   private
+ 
+   def util_install_operating_system_rb(content)
+
+From 52cfdd14fd1213a97aac12f01177e27779de9035 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
+Date: Thu, 9 Dec 2021 06:08:31 +0100
+Subject: [PATCH 4/5] Install default fiddle on latest ruby on specs that need
+ it
+
+Otherwise first OS customizations load and activate that fiddle version,
+but then when we change to `Gem.default_dir`, that fiddle version is no
+longer there.
+---
+ spec/bundler/commands/clean_spec.rb          | 2 +-
+ spec/bundler/install/gems/standalone_spec.rb | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
+index ffaf22dbb32..65231b35fac 100644
+--- a/spec/bundler/commands/clean_spec.rb
++++ b/spec/bundler/commands/clean_spec.rb
+@@ -638,7 +638,7 @@ def should_not_have_gems(*gems)
+       s.executables = "irb"
+     end
+ 
+-    realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
++    realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
+ 
+     install_gemfile <<-G
+       source "#{file_uri_for(gem_repo2)}"
+diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb
+index db16a1b0e13..faefda25f45 100644
+--- a/spec/bundler/install/gems/standalone_spec.rb
++++ b/spec/bundler/install/gems/standalone_spec.rb
+@@ -113,7 +113,7 @@
+       skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2
+       skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
+ 
+-      realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0"
++      realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0"
+ 
+       necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.0"]
+       necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.3.a")
+
+From c6a9c81021092c9157f5616a2bbe1323411a5bf8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
+Date: Thu, 9 Dec 2021 12:46:23 +0100
+Subject: [PATCH 5/5] Resolve symlinks in LOAD_PATH when activating
+ pre-required default gems
+
+Some double load issues were reported a while ago by OS packagers where
+if a gem has been required before rubygems, and then after, rubygems
+require would cause a double load.
+
+We avoid this issue by activating the corresponding gem if we detect
+that a file in the default LOAD_PATH that belongs to a default gem has
+already been required when rubygems registers default gems.
+
+However, the fix does not take into account that the default LOAD_PATH
+could potentially include symlinks. This change fixes the same double
+load issue described above but for situations where the default
+LOAD_PATH includes symlinks.
+---
+ lib/rubygems.rb | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/lib/rubygems.rb b/lib/rubygems.rb
+index 11474b6554c..b7dda38d522 100644
+--- a/lib/rubygems.rb
++++ b/lib/rubygems.rb
+@@ -1293,7 +1293,12 @@ def already_loaded?(file)
+     end
+ 
+     def default_gem_load_paths
+-      @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1]
++      @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1].map do |lp|
++        expanded = File.expand_path(lp)
++        next expanded unless File.exist?(expanded)
++
++        File.realpath(expanded)
++      end
+     end
+   end
+ 
diff --git a/SPECS/ruby.spec b/SPECS/ruby.spec
index 65a13e7..5b92e33 100644
--- a/SPECS/ruby.spec
+++ b/SPECS/ruby.spec
@@ -1,6 +1,6 @@
 %global major_version 3
 %global minor_version 0
-%global teeny_version 2
+%global teeny_version 4
 %global major_minor_version %{major_version}.%{minor_version}
 
 %global ruby_version %{major_minor_version}.%{teeny_version}
@@ -22,7 +22,7 @@
 %endif
 
 
-%global release 140
+%global release 141
 %{!?release_string:%define release_string %{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
 
 # The RubyGems library has to stay out of Ruby directory tree, since the
@@ -30,12 +30,12 @@
 %global rubygems_dir %{_datadir}/rubygems
 
 # Bundled libraries versions
-%global rubygems_version 3.2.22
+%global rubygems_version 3.2.33
 %global rubygems_molinillo_version 0.7.0
 
 # Default gems.
-%global bundler_version 2.2.22
-%global bundler_connection_pool_version 2.2.2
+%global bundler_version 2.2.33
+%global bundler_connection_pool_version 2.3.0
 %global bundler_fileutils_version 1.4.1
 %global bundler_molinillo_version 0.7.0
 %global bundler_net_http_persistent_version 4.0.0
@@ -49,20 +49,20 @@
 %global io_console_version 0.5.7
 %global irb_version 1.3.5
 %global json_version 2.5.1
-%global openssl_version 2.2.0
-%global psych_version 3.3.0
-%global racc_version 1.5.1
-%global rdoc_version 6.3.1
+%global openssl_version 2.2.1
+%global psych_version 3.3.2
+%global racc_version 1.5.2
+%global rdoc_version 6.3.3
 
 # Bundled gems.
 %global minitest_version 5.14.2
 %global power_assert_version 1.2.0
 %global rake_version 13.0.3
-%global rbs_version 1.0.4
+%global rbs_version 1.4.0
 %global test_unit_version 3.3.7
 %global rexml_version 3.2.5
 %global rss_version 0.2.9
-%global typeprof_version 0.12.0
+%global typeprof_version 0.15.2
 
 %global tapset_libdir %(echo %{_libdir} | sed 's/64//')*
 
@@ -142,17 +142,33 @@ Patch5: ruby-1.9.3-mkmf-verbose.patch
 # https://lists.fedoraproject.org/archives/list/ruby-sig@lists.fedoraproject.org/message/LH6L6YJOYQT4Y5ZNOO4SLIPTUWZ5V45Q/
 # For now, load the ABRT hook via this simple patch:
 Patch6: ruby-2.7.0-Initialize-ABRT-hook.patch
-# Workaround "an invalid stdio handle" error on PPC, due to recently introduced
-# hardening features of glibc (rhbz#1361037).
-# https://bugs.ruby-lang.org/issues/12666
-Patch9: ruby-2.3.1-Rely-on-ldd-to-detect-glibc.patch
+# Prevent segfaults running with SystemTap due to `RubyVM::FrozenCore` being
+# corrupted by GC.
+# https://bugzilla.redhat.com/show_bug.cgi?id=2015441
+# https://bugzilla.redhat.com/show_bug.cgi?id=1986206
+# https://bugs.ruby-lang.org/issues/18257
+Patch7: ruby-3.1.0-Don-t-query-RubyVM-FrozenCore-for-class-path.patch
 # Fix DWARF5 support.
 # https://bugzilla.redhat.com/show_bug.cgi?id=1920533
 # https://bugs.ruby-lang.org/issues/17585
-Patch15: ruby-dwarf5-avoid_crash-r1.patch
+# https://github.com/ruby/ruby/pull/4240
+Patch15: ruby-3.1.0-Support-GCCs-DWARF-5.patch
 # Avoid possible timeout errors in TestBugReporter#test_bug_reporter_add.
 # https://bugs.ruby-lang.org/issues/16492
 Patch19: ruby-2.7.1-Timeout-the-test_bug_reporter_add-witout-raising-err.patch
+# Fix /test_\(ast_compacts\|compact_count\|complex_hash_keys\|gc_compact_stats\)/
+# test failures on ppc64le.
+# https://bugs.ruby-lang.org/issues/18746
+# https://bugs.ruby-lang.org/issues/18394
+Patch20: ruby-3.1.0-Use-mmap-for-allocating-heap-pages-in-the-GC.patch
+# Allow to exclude test with fully qualified name.
+# https://bugs.ruby-lang.org/issues/16936
+# https://github.com/ruby/ruby/pull/5026
+Patch21: ruby-3.1.0-Properly-exclude-test-cases.patch
+# Fix loading of default gems.
+# https://bugzilla.redhat.com/show_bug.cgi?id=2027099
+# https://github.com/rubygems/rubygems/pull/5154
+Patch22: rubygems-3.2.33-Fix-loading-operating_system-rb-customizations-too-late.patch
 
 Requires: %{name}-libs%{?_isa} = %{version}-%{release}
 Suggests: rubypick
@@ -586,9 +602,12 @@ rm -rf ext/fiddle/libffi*
 %patch4 -p1
 %patch5 -p1
 %patch6 -p1
-%patch9 -p1
+%patch7 -p1
 %patch15 -p1
 %patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
 
 # Provide an example of usage of the tapset:
 cp -a %{SOURCE3} .
@@ -1124,30 +1143,30 @@ MSPECOPTS=""
 %{_rpmconfigdir}/rubygems.con
 
 %files default-gems
-%{gem_dir}/specifications/default/english-0.7.1.gemspec
 %{gem_dir}/specifications/default/abbrev-0.1.0.gemspec
 %{gem_dir}/specifications/default/base64-0.1.0.gemspec
 %{gem_dir}/specifications/default/benchmark-0.1.1.gemspec
-%{gem_dir}/specifications/default/cgi-0.2.0.gemspec
+%{gem_dir}/specifications/default/cgi-0.2.1.gemspec
 %{gem_dir}/specifications/default/csv-3.1.9.gemspec
-%{gem_dir}/specifications/default/date-3.1.0.gemspec
+%{gem_dir}/specifications/default/date-3.1.3.gemspec
 %{gem_dir}/specifications/default/dbm-1.1.0.gemspec
-%{gem_dir}/specifications/default/debug-0.1.0.gemspec
+%{gem_dir}/specifications/default/debug-0.2.1.gemspec
 %{gem_dir}/specifications/default/delegate-0.2.0.gemspec
 %{gem_dir}/specifications/default/did_you_mean-%{did_you_mean_version}.gemspec
 %{gem_dir}/specifications/default/digest-3.0.0.gemspec
-%{gem_dir}/specifications/default/drb-2.0.4.gemspec
+%{gem_dir}/specifications/default/drb-2.0.5.gemspec
+%{gem_dir}/specifications/default/english-0.7.1.gemspec
 %{gem_dir}/specifications/default/erb-%{erb_version}.gemspec
-%{gem_dir}/specifications/default/etc-1.2.0.gemspec
-%{gem_dir}/specifications/default/fcntl-1.0.0.gemspec
-%{gem_dir}/specifications/default/fiddle-1.0.6.gemspec
+%{gem_dir}/specifications/default/etc-1.3.0.gemspec
+%{gem_dir}/specifications/default/fcntl-1.0.1.gemspec
+%{gem_dir}/specifications/default/fiddle-1.0.8.gemspec
 %{gem_dir}/specifications/default/fileutils-1.5.0.gemspec
 %{gem_dir}/specifications/default/find-0.1.0.gemspec
 %{gem_dir}/specifications/default/forwardable-1.3.2.gemspec
 %{gem_dir}/specifications/default/gdbm-2.1.0.gemspec
 %{gem_dir}/specifications/default/getoptlong-0.1.1.gemspec
 %{gem_dir}/specifications/default/io-nonblock-0.1.0.gemspec
-%{gem_dir}/specifications/default/io-wait-0.1.0.gemspec
+%{gem_dir}/specifications/default/io-wait-0.2.0.gemspec
 %{gem_dir}/specifications/default/ipaddr-1.2.2.gemspec
 %{gem_dir}/specifications/default/logger-1.4.3.gemspec
 %{gem_dir}/specifications/default/matrix-0.3.1.gemspec
@@ -1156,33 +1175,33 @@ MSPECOPTS=""
 %{gem_dir}/specifications/default/net-http-0.1.1.gemspec
 %{gem_dir}/specifications/default/net-imap-0.1.1.gemspec
 %{gem_dir}/specifications/default/net-pop-0.1.1.gemspec
-%{gem_dir}/specifications/default/net-protocol-0.1.0.gemspec
+%{gem_dir}/specifications/default/net-protocol-0.1.1.gemspec
 %{gem_dir}/specifications/default/net-smtp-0.2.1.gemspec
 %{gem_dir}/specifications/default/nkf-0.1.0.gemspec
 %{gem_dir}/specifications/default/observer-0.1.1.gemspec
 %{gem_dir}/specifications/default/open3-0.1.1.gemspec
 %{gem_dir}/specifications/default/open-uri-0.1.0.gemspec
-%{gem_dir}/specifications/default/optparse-0.1.0.gemspec
+%{gem_dir}/specifications/default/optparse-0.1.1.gemspec
 %{gem_dir}/specifications/default/openssl-%{openssl_version}.gemspec
 %{gem_dir}/specifications/default/ostruct-0.3.1.gemspec
 %{gem_dir}/specifications/default/pathname-0.1.0.gemspec
-%{gem_dir}/specifications/default/pp-0.1.0.gemspec
-%{gem_dir}/specifications/default/prettyprint-0.1.0.gemspec
+%{gem_dir}/specifications/default/pp-0.2.1.gemspec
+%{gem_dir}/specifications/default/prettyprint-0.1.1.gemspec
 %{gem_dir}/specifications/default/prime-0.1.2.gemspec
 %{gem_dir}/specifications/default/pstore-0.1.1.gemspec
 %{gem_dir}/specifications/default/racc-%{racc_version}.gemspec
 %{gem_dir}/specifications/default/readline-0.0.2.gemspec
 %{gem_dir}/specifications/default/readline-ext-0.1.1.gemspec
 %{gem_dir}/specifications/default/reline-0.2.5.gemspec
-%{gem_dir}/specifications/default/resolv-0.2.0.gemspec
+%{gem_dir}/specifications/default/resolv-0.2.1.gemspec
 %{gem_dir}/specifications/default/resolv-replace-0.1.0.gemspec
-%{gem_dir}/specifications/default/rinda-0.1.0.gemspec
+%{gem_dir}/specifications/default/rinda-0.1.1.gemspec
 %{gem_dir}/specifications/default/securerandom-0.1.0.gemspec
 %{gem_dir}/specifications/default/set-1.0.1.gemspec
 %{gem_dir}/specifications/default/shellwords-0.1.0.gemspec
 %{gem_dir}/specifications/default/singleton-0.1.1.gemspec
-%{gem_dir}/specifications/default/stringio-3.0.0.gemspec
-%{gem_dir}/specifications/default/strscan-3.0.0.gemspec
+%{gem_dir}/specifications/default/stringio-3.0.1.gemspec
+%{gem_dir}/specifications/default/strscan-3.0.1.gemspec
 %{gem_dir}/specifications/default/syslog-0.1.0.gemspec
 %{gem_dir}/specifications/default/tempfile-0.1.1.gemspec
 %{gem_dir}/specifications/default/time-0.1.0.gemspec
@@ -1195,7 +1214,7 @@ MSPECOPTS=""
 %{gem_dir}/specifications/default/weakref-0.1.1.gemspec
 #%%{gem_dir}/specifications/default/win32ole-1.8.8.gemspec
 %{gem_dir}/specifications/default/yaml-0.1.1.gemspec
-%{gem_dir}/specifications/default/zlib-1.1.0.gemspec
+%{gem_dir}/specifications/default/zlib-2.0.0.gemspec
 
 %{gem_dir}/gems/erb-%{erb_version}
 # Use standalone rubygem-racc if Racc binary is required. Shipping this
@@ -1289,7 +1308,6 @@ MSPECOPTS=""
 %doc %{gem_dir}/gems/rbs-%{rbs_version}/README.md
 %{gem_dir}/gems/rbs-%{rbs_version}/Rakefile
 %{gem_dir}/gems/rbs-%{rbs_version}/Steepfile
-%{gem_dir}/gems/rbs-%{rbs_version}/bin
 %{gem_dir}/gems/rbs-%{rbs_version}/core
 %doc %{gem_dir}/gems/rbs-%{rbs_version}/docs
 %{gem_dir}/gems/rbs-%{rbs_version}/exe
@@ -1345,9 +1363,18 @@ MSPECOPTS=""
 
 
 %changelog
+* Tue Jul 26 2022 Jarek Prokop <jprokop@redhat.com> - 3.0.4-141
+- Upgrade to Ruby 3.0.4.
+  Resolves: rhbz#2109431
+  Resolves: rhbz#2110981
+- Fix double free in Regexp compilation.
+  Resolves: CVE-2022-28738
+- Fix buffer overrun in String-to-Float conversion.
+  Resolves: CVE-2022-28739
+
 * Tue Oct 05 2021 Jarek Prokop <jprokop@redhat.com> - 3.0.2-140
 - Fix rubygem-irb upgrade not working due to directory -> symlink conversion.
-  Resolves: rhbz#2010403
+  Resolves: rhbz#2010949
 
 * Tue Jul 13 2021 Jarek Prokop <jprokop@redhat.com> - 3.0.2-139
 - Upgrade to Ruby 3.0.2.