diff --git a/CVE-2021-29509.patch b/CVE-2021-29509.patch deleted file mode 100644 index 8b0267b90762e1de4d38dcfb3dbb058731db4c8e..0000000000000000000000000000000000000000 --- a/CVE-2021-29509.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 2e9cf0b63b8de904d6ebca9fb1474cf0f979c53b Mon Sep 17 00:00:00 2001 -From: Nate Berkopec -Date: Tue, 11 May 2021 07:43:32 -0600 -Subject: [PATCH] Close keepalive connections after MAX_FAST_INLINE requests - ---- - lib/puma/server.rb | 21 +++++++++++++-------- - 1 file changed, 13 insertions(+), 8 deletions(-) - -diff --git a/lib/puma/server.rb b/lib/puma/server.rb -index 5b2cd94..4ce0c74 100644 ---- a/lib/puma/server.rb -+++ b/lib/puma/server.rb -@@ -487,15 +487,20 @@ module Puma - - requests += 1 - -- check_for_more_data = @status == :run -+ # Closing keepalive sockets after they've made a reasonable -+ # number of requests allows Puma to service many connections -+ # fairly, even when the number of concurrent connections exceeds -+ # the size of the threadpool. It also allows cluster mode Pumas -+ # to keep load evenly distributed across workers, because clients -+ # are randomly assigned a new worker when opening a new connection. -+ # -+ # Previously, Puma would kick connections in this conditional back -+ # to the reactor. However, because this causes the todo set to increase -+ # in size, the wait_until_full mutex would never unlock, leaving -+ # any additional connections unserviced. -+ break if requests >= MAX_FAST_INLINE - -- if requests >= MAX_FAST_INLINE -- # This will mean that reset will only try to use the data it already -- # has buffered and won't try to read more data. What this means is that -- # every client, independent of their request speed, gets treated like a slow -- # one once every MAX_FAST_INLINE requests. -- check_for_more_data = false -- end -+ check_for_more_data = @status == :run - - unless client.reset(check_for_more_data) - close_socket = false --- -2.23.0 - diff --git a/Support-for-cert_pem-and-key_pem-with-ssl_bind-DSL.patch b/Support-for-cert_pem-and-key_pem-with-ssl_bind-DSL.patch new file mode 100644 index 0000000000000000000000000000000000000000..8caca1f5cd550987cb5d39e3e8a1c7b241155e76 --- /dev/null +++ b/Support-for-cert_pem-and-key_pem-with-ssl_bind-DSL.patch @@ -0,0 +1,559 @@ +From 5608248c13130740ca94697b63a59245140e8092 Mon Sep 17 00:00:00 2001 +From: Dalibor Nasevic +Date: Sun, 31 Oct 2021 14:59:21 +0100 +Subject: [PATCH] Support for cert_pem and key_pem with ssl_bind DSL (#2728) + +* Fix deprecation warning + +DEPRECATED: Use assert_nil if expecting nil from test/test_binder.rb:265. This will fail in Minitest 6. + +* Extend MiniSSL with support for cert_pem and key_pem + +* Extend Puma ssl_bind DSL with support for cert_pem and cert_key + +* Make some variables in binder test more readable +--- + ext/puma_http11/mini_ssl.c | 38 ++++++++-- + lib/puma/binder.rb | 13 +++- + lib/puma/dsl.rb | 29 ++++++++ + lib/puma/minissl.rb | 20 +++++- + lib/puma/minissl/context_builder.rb | 14 ++-- + test/test_binder.rb | 14 ++-- + test/test_config.rb | 22 ++++++ + test/test_integration_ssl.rb | 105 ++++++++++++++++++---------- + test/test_minissl.rb | 14 ++++ + test/test_puma_server_ssl.rb | 41 +++++++++++ + 10 files changed, 253 insertions(+), 57 deletions(-) + +diff --git a/ext/puma_http11/mini_ssl.c b/ext/puma_http11/mini_ssl.c +index 04bd1462d..6974b6349 100644 +--- a/ext/puma_http11/mini_ssl.c ++++ b/ext/puma_http11/mini_ssl.c +@@ -208,8 +208,11 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) { + #endif + int ssl_options; + VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1, +- verification_flags, session_id_bytes; ++ verification_flags, session_id_bytes, cert_pem, key_pem; + DH *dh; ++ BIO *bio; ++ X509 *x509; ++ EVP_PKEY *pkey; + + #if OPENSSL_VERSION_NUMBER < 0x10002000L + EC_KEY *ecdh; +@@ -218,13 +221,15 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) { + TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx); + + key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0); +- StringValue(key); + + cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0); +- StringValue(cert); + + ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0); + ++ cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0); ++ ++ key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0); ++ + verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0); + + ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0); +@@ -233,8 +238,31 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) { + + no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0); + +- SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert)); +- SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM); ++ if (!NIL_P(cert)) { ++ StringValue(cert); ++ SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert)); ++ } ++ ++ if (!NIL_P(key)) { ++ StringValue(key); ++ SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM); ++ } ++ ++ if (!NIL_P(cert_pem)) { ++ bio = BIO_new(BIO_s_mem()); ++ BIO_puts(bio, RSTRING_PTR(cert_pem)); ++ x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); ++ ++ SSL_CTX_use_certificate(ctx, x509); ++ } ++ ++ if (!NIL_P(key_pem)) { ++ bio = BIO_new(BIO_s_mem()); ++ BIO_puts(bio, RSTRING_PTR(key_pem)); ++ pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); ++ ++ SSL_CTX_use_PrivateKey(ctx, pkey); ++ } + + verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0); + +diff --git a/lib/puma/binder.rb b/lib/puma/binder.rb +index 6151889e7..3d688296b 100644 +--- a/lib/puma/binder.rb ++++ b/lib/puma/binder.rb +@@ -30,6 +30,7 @@ class Binder + + def initialize(events, conf = Configuration.new) + @events = events ++ @conf = conf + @listeners = [] + @inherited_fds = {} + @activated_sockets = {} +@@ -234,7 +235,17 @@ def parse(binds, logger, log_msg = 'Listening') + # Load localhost authority if not loaded. + ctx = localhost_authority && localhost_authority_context if params.empty? + +- ctx ||= MiniSSL::ContextBuilder.new(params, @events).context ++ ctx ||= ++ begin ++ # Extract cert_pem and key_pem from options[:store] if present ++ ['cert', 'key'].each do |v| ++ if params[v] && params[v].start_with?('store:') ++ index = Integer(params.delete(v).split('store:').last) ++ params["#{v}_pem"] = @conf.options[:store][index] ++ end ++ end ++ MiniSSL::ContextBuilder.new(params, @events).context ++ end + + if fd = @inherited_fds.delete(str) + logger.log "* Inherited #{str}" +diff --git a/lib/puma/dsl.rb b/lib/puma/dsl.rb +index c3e933751..65b3bbed9 100644 +--- a/lib/puma/dsl.rb ++++ b/lib/puma/dsl.rb +@@ -447,6 +447,14 @@ def threads(min, max) + # verify_mode: verify_mode, # default 'none' + # verification_flags: flags, # optional, not supported by JRuby + # } ++ # ++ # Alternatively, you can provide the cert_pem and key_pem: ++ # @example ++ # ssl_bind '127.0.0.1', '9292', { ++ # cert_pem: File.read(path_to_cert), ++ # key_pem: File.read(path_to_key), ++ # } ++ # + # @example For JRuby, two keys are required: keystore & keystore_pass. + # ssl_bind '127.0.0.1', '9292', { + # keystore: path_to_keystore, +@@ -455,6 +463,7 @@ def threads(min, max) + # verify_mode: verify_mode # default 'none' + # } + def ssl_bind(host, port, opts) ++ add_pem_values_to_options_store(opts) + bind self.class.ssl_bind_str(host, port, opts) + end + +@@ -927,5 +936,25 @@ def io_selector_backend(backend) + def mutate_stdout_and_stderr_to_sync_on_write(enabled=true) + @options[:mutate_stdout_and_stderr_to_sync_on_write] = enabled + end ++ ++ private ++ ++ # To avoid adding cert_pem and key_pem as URI params, we store them on the ++ # options[:store] from where Puma binder knows how to find and extract them. ++ def add_pem_values_to_options_store(opts) ++ return if defined?(JRUBY_VERSION) ++ ++ @options[:store] ||= [] ++ ++ # Store cert_pem and key_pem to options[:store] if present ++ [:cert, :key].each do |v| ++ opt_key = :"#{v}_pem" ++ if opts[opt_key] ++ index = @options[:store].length ++ @options[:store] << opts[opt_key] ++ opts[v] = "store:#{index}" ++ end ++ end ++ end + end + end +diff --git a/lib/puma/minissl.rb b/lib/puma/minissl.rb +index 9f1bc8185..f9161af76 100644 +--- a/lib/puma/minissl.rb ++++ b/lib/puma/minissl.rb +@@ -208,6 +208,10 @@ class Context + def initialize + @no_tlsv1 = false + @no_tlsv1_1 = false ++ @key = nil ++ @cert = nil ++ @key_pem = nil ++ @cert_pem = nil + end + + if IS_JRUBY +@@ -230,6 +234,8 @@ def check + attr_reader :key + attr_reader :cert + attr_reader :ca ++ attr_reader :cert_pem ++ attr_reader :key_pem + attr_accessor :ssl_cipher_filter + attr_accessor :verification_flags + +@@ -248,9 +254,19 @@ def ca=(ca) + @ca = ca + end + ++ def cert_pem=(cert_pem) ++ raise ArgumentError, "'cert_pem' is not a String" unless cert_pem.is_a? String ++ @cert_pem = cert_pem ++ end ++ ++ def key_pem=(key_pem) ++ raise ArgumentError, "'key_pem' is not a String" unless key_pem.is_a? String ++ @key_pem = key_pem ++ end ++ + def check +- raise "Key not configured" unless @key +- raise "Cert not configured" unless @cert ++ raise "Key not configured" if @key.nil? && @key_pem.nil? ++ raise "Cert not configured" if @cert.nil? && @cert_pem.nil? + end + end + +diff --git a/lib/puma/minissl/context_builder.rb b/lib/puma/minissl/context_builder.rb +index a30a26dc3..8cf16bbd3 100644 +--- a/lib/puma/minissl/context_builder.rb ++++ b/lib/puma/minissl/context_builder.rb +@@ -23,17 +23,19 @@ def context + ctx.keystore_pass = params['keystore-pass'] + ctx.ssl_cipher_list = params['ssl_cipher_list'] if params['ssl_cipher_list'] + else +- unless params['key'] +- events.error "Please specify the SSL key via 'key='" ++ if params['key'].nil? && params['key_pem'].nil? ++ events.error "Please specify the SSL key via 'key=' or 'key_pem='" + end + +- ctx.key = params['key'] ++ ctx.key = params['key'] if params['key'] ++ ctx.key_pem = params['key_pem'] if params['key_pem'] + +- unless params['cert'] +- events.error "Please specify the SSL cert via 'cert='" ++ if params['cert'].nil? && params['cert_pem'].nil? ++ events.error "Please specify the SSL cert via 'cert=' or 'cert_pem='" + end + +- ctx.cert = params['cert'] ++ ctx.cert = params['cert'] if params['cert'] ++ ctx.cert_pem = params['cert_pem'] if params['cert_pem'] + + if ['peer', 'force_peer'].include?(params['verify_mode']) + unless params['ca'] +diff --git a/test/test_binder.rb b/test/test_binder.rb +index c4a027ab6..4dddbcce5 100644 +--- a/test/test_binder.rb ++++ b/test/test_binder.rb +@@ -262,7 +262,7 @@ def test_env_contains_protoenv + env_hash = @binder.envs[@binder.ios.first] + + @binder.proto_env.each do |k,v| +- assert_equal env_hash[k], v ++ assert env_hash[k] == v + end + end + +@@ -308,11 +308,11 @@ def test_redirects_for_restart_env + def test_close_listeners_closes_ios + @binder.parse ["tcp://127.0.0.1:#{UniquePort.call}"], @events + +- refute @binder.listeners.any? { |u, l| l.closed? } ++ refute @binder.listeners.any? { |_l, io| io.closed? } + + @binder.close_listeners + +- assert @binder.listeners.all? { |u, l| l.closed? } ++ assert @binder.listeners.all? { |_l, io| io.closed? } + end + + def test_close_listeners_closes_ios_unless_closed? +@@ -322,11 +322,11 @@ def test_close_listeners_closes_ios_unless_closed? + bomb.close + def bomb.close; raise "Boom!"; end # the bomb has been planted + +- assert @binder.listeners.any? { |u, l| l.closed? } ++ assert @binder.listeners.any? { |_l, io| io.closed? } + + @binder.close_listeners + +- assert @binder.listeners.all? { |u, l| l.closed? } ++ assert @binder.listeners.all? { |_l, io| io.closed? } + end + + def test_listeners_file_unlink_if_unix_listener +@@ -344,8 +344,8 @@ def test_import_from_env_listen_inherit + @binder.parse ["tcp://127.0.0.1:0"], @events + removals = @binder.create_inherited_fds(@binder.redirects_for_restart_env) + +- @binder.listeners.each do |url, io| +- assert_equal io.to_i, @binder.inherited_fds[url] ++ @binder.listeners.each do |l, io| ++ assert_equal io.to_i, @binder.inherited_fds[l] + end + assert_includes removals, "PUMA_INHERIT_0" + end +diff --git a/test/test_config.rb b/test/test_config.rb +index 9ba564653..758910ca1 100644 +--- a/test/test_config.rb ++++ b/test/test_config.rb +@@ -77,6 +77,28 @@ def test_ssl_bind + assert_equal [ssl_binding], conf.options[:binds] + end + ++ def test_ssl_bind_with_cert_and_key_pem ++ skip_if :jruby ++ skip_unless :ssl ++ ++ cert_path = File.expand_path "../examples/puma/client-certs", __dir__ ++ cert_pem = File.read("#{cert_path}/server.crt") ++ key_pem = File.read("#{cert_path}/server.key") ++ ++ conf = Puma::Configuration.new do |c| ++ c.ssl_bind "0.0.0.0", "9292", { ++ cert_pem: cert_pem, ++ key_pem: key_pem, ++ verify_mode: "the_verify_mode", ++ } ++ end ++ ++ conf.load ++ ++ ssl_binding = "ssl://0.0.0.0:9292?cert=store:0&key=store:1&verify_mode=the_verify_mode" ++ assert_equal [ssl_binding], conf.options[:binds] ++ end ++ + def test_ssl_bind_jruby + skip_unless :jruby + skip_unless :ssl +diff --git a/test/test_integration_ssl.rb b/test/test_integration_ssl.rb +index 8f746e5ab..9c3409a7b 100644 +--- a/test/test_integration_ssl.rb ++++ b/test/test_integration_ssl.rb +@@ -21,17 +21,47 @@ def teardown + super + end + +- def generate_config(opts = nil) +- @bind_port = UniquePort.call +- @control_tcp_port = UniquePort.call ++ def bind_port ++ @bind_port ||= UniquePort.call ++ end ++ ++ def control_tcp_port ++ @control_tcp_port ||= UniquePort.call ++ end ++ ++ def with_server(config) ++ config_file = Tempfile.new %w(config .rb) ++ config_file.write config ++ config_file.close ++ config_file.path ++ ++ # start server ++ cmd = "#{BASE} bin/puma -C #{config_file.path}" ++ @server = IO.popen cmd, 'r' ++ wait_for_server_to_boot ++ @pid = @server.pid + ++ http = Net::HTTP.new HOST, bind_port ++ http.use_ssl = true ++ http.verify_mode = OpenSSL::SSL::VERIFY_NONE ++ ++ yield http ++ ++ # stop server ++ sock = TCPSocket.new HOST, control_tcp_port ++ @ios_to_close << sock ++ sock.syswrite "GET /stop?token=#{TOKEN} HTTP/1.1\r\n\r\n" ++ sock.read ++ assert_match 'Goodbye!', @server.read ++ end ++ ++ def test_ssl_run + config = < e ++ # Errno::ECONNRESET TruffleRuby ++ client_error = e ++ # closes socket if open, may not close on error ++ http.send :do_finish ++ end ++ ++ assert_nil client_error ++ ensure ++ server.stop(true) if server ++ end ++end if ::Puma::HAS_SSL && !Puma::IS_JRUBY diff --git a/puma-3.12.6.gem b/puma-3.12.6.gem deleted file mode 100644 index 64d2a5b236a1e589e4e31770a6f5aeb20e233c70..0000000000000000000000000000000000000000 Binary files a/puma-3.12.6.gem and /dev/null differ diff --git a/puma-5.5.2.gem b/puma-5.5.2.gem new file mode 100644 index 0000000000000000000000000000000000000000..e78209f0547ea189625ccf271402ea249b3cd929 Binary files /dev/null and b/puma-5.5.2.gem differ diff --git a/rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch b/rubygem-puma-3.6.0-crypto-policy-cipher-list.patch similarity index 76% rename from rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch rename to rubygem-puma-3.6.0-crypto-policy-cipher-list.patch index b4e8a2cea5945c0359fa3e819b413af31d9e6806..1e9954f50e9bdd92ecafcc274350e6a5e774672a 100644 --- a/rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch +++ b/rubygem-puma-3.6.0-crypto-policy-cipher-list.patch @@ -2,7 +2,7 @@ diff --git a/ext/puma_http11/mini_ssl.c b/ext/puma_http11/mini_ssl.c index 7e0fd5e..88c4652 100644 --- a/ext/puma_http11/mini_ssl.c +++ b/ext/puma_http11/mini_ssl.c -@@ -183,7 +183,7 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) { +@@ -286,7 +286,7 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) { SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(ssl_cipher_filter)); } else { @@ -10,7 +10,7 @@ index 7e0fd5e..88c4652 100644 + SSL_CTX_set_cipher_list(ctx, "PROFILE=SYSTEM"); } - DH *dh = get_dh1024(); + dh = get_dh2048(); -- -2.5.5 +2.30.0 diff --git a/rubygem-puma.spec b/rubygem-puma.spec index 82154e039855f8bbc7d67a2f49bc7444fcf714e1..c205e8c38c1af9bcbd5c84cef6e388d42ee9b261 100644 --- a/rubygem-puma.spec +++ b/rubygem-puma.spec @@ -1,20 +1,21 @@ %global gem_name puma %bcond_with ragel Name: rubygem-%{gem_name} -Version: 3.12.6 -Release: 2 +Version: 5.5.2 +Release: 1 Summary: A simple, fast, threaded, and highly concurrent HTTP 1.1 server -License: BSD +License: BSD-3-Clause URL: http://puma.io Source0: https://rubygems.org/gems/%{gem_name}-%{version}.gem -Source1: https://github.com/puma/%{gem_name}/archive/v%{version}.tar.gz +Source1: https://github.com/puma/%{gem_name}/archive/refs/tags/v%{version}.tar.gz # Set the default cipher list "PROFILE=SYSTEM". # https://fedoraproject.org/wiki/Packaging:CryptoPolicies -Patch0: rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch -Patch1: CVE-2021-29509.patch +Patch0: rubygem-puma-3.6.0-crypto-policy-cipher-list.patch +Patch1: Support-for-cert_pem-and-key_pem-with-ssl_bind-DSL.patch BuildRequires: openssl-devel ruby(release) rubygems-devel ruby-devel rubygem(rack) -BuildRequires: rubygem(minitest) +BuildRequires: rubygem(minitest) rubygem(sd_notify) +BuildRequires: rubygem(nio4r) %if %{with ragel} BuildRequires: %{_bindir}/ragel %endif @@ -64,22 +65,40 @@ find %{buildroot}%{gem_instdir}/bin -type f | \ pushd .%{gem_instdir} ln -s %{_builddir}/%{gem_name}-%{version}/test test ln -s %{_builddir}/%{gem_name}-%{version}/examples examples -sed -i "/require 'minitest\/retry'/ s/^/#/" test/helper.rb + +sed -i -e "/require..minitest\/\(retry\|proveit\)./ s/^/#/" test/helper.rb sed -i "/Minitest::Retry/ s/^/#/" test/helper.rb +sed -i '/prove_it!/ s/^/#/' test/helper.rb +sed -i "/minitest\/stub_const/ s/^/#/" test/helper.rb +sed -i '/::Timeout.timeout/ s/45/300/' test/helper.rb + +mv test/test_preserve_bundler_env.rb{,.disable} +mv test/test_thread_pool.rb{,.disable} +mv test/test_worker_gem_independence.rb{,.disable} +sed -i -e '/^\s*def test_prune_bundler_with_multiple_workers$/a\ + skip' \ + -e '/^\s*def test_phased_restart_cluster$/a\ + skip' test/test_integration_pumactl.rb + +mv test/test_puma_localhost_authority.rb{,.disable} +mv test/test_integration_single.rb{,.disable} +mv test/test_integration_cluster.rb{,.disable} + +%ifarch aarch64 +sed -i '/^ def test_control$/,/^ end$/ s/^/#/' test/test_cli.rb +%endif + sed -i '/^ def test_timeout_in_data_phase$/a\ - skip "Unstable test"' test/test_puma_server.rb -sed -i "s/X_FORWARDED_PROTO/X-FORWARDED-PROTO/g" test/test_puma_server.rb -sed -i '/^ def test_control_url$/a\ - skip "Unstable test"' test/test_pumactl.rb -sed -i '/^ def test_ssl_v3_rejection$/a\ + skip' test/test_puma_server.rb +sed -i '/^ def test_plugin$/a\ + skip' test/test_plugin.rb +sed -i '/^ def test_verify_fail_if_client_unknown_ca$/a\ skip' test/test_puma_server_ssl.rb -sed -i '/^ def test_term_signal_exit_code_in_clustered_mode$/a\ - skip "Clustered server does not stop properly"' test/test_integration.rb -RUBYOPT="-Ilib:$(dirs +1 -l)%{gem_extdir_mri}" CI=1 ruby \ - -e 'Dir.glob "./test/**/test_*.rb", &method(:require)' \ - -- -v -RUBYOPT="-I$(dirs +1 -l)%{gem_extdir_mri}" ruby test/shell/run.rb -popd + +RUBYOPT="-Ilib:$(dirs +1 -l)%{gem_extdir_mri}" \ +CI=1 \ +LC_ALL=C.UTF-8 \ +ruby -e 'Dir.glob "./test/**/test_*.rb", &method(:require)' %files %dir %{gem_instdir} @@ -100,6 +119,9 @@ popd %{gem_instdir}/tools %changelog +* Tue Nov 1 2022 cadongxia - 5.5.2-1 +- Upgrade to 5.5.2 + * Mon May 31 2021 wangyue - 3.12.6-2 - Fix CVE-2021-29509 diff --git a/v3.12.6.tar.gz b/v3.12.6.tar.gz deleted file mode 100644 index 9e3356df14e27dbc7146c37911f996ff5cba04c3..0000000000000000000000000000000000000000 Binary files a/v3.12.6.tar.gz and /dev/null differ diff --git a/v5.5.2.tar.gz b/v5.5.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c56b95b5cac993b75fb62780531bf03a07676b2b Binary files /dev/null and b/v5.5.2.tar.gz differ