Version in base suite: 2.5.5-3 Base version: ruby2.5_2.5.5-3 Target version: ruby2.5_2.5.5-3+deb10u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/r/ruby2.5/ruby2.5_2.5.5-3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/r/ruby2.5/ruby2.5_2.5.5-3+deb10u1.dsc changelog | 11 + patches/0012-Fix-for-wrong-fnmatch-patttern.patch | 44 ++++ patches/0013-Loop-with-String-scan-without-creating-substrings.patch | 79 +++++++ patches/0014-WEBrick-prevent-response-splitting-and-header-inject.patch | 107 ++++++++++ patches/0015-lib-shell-command-processor.rb-Shell-prevent-unknown.patch | 63 +++++ patches/series | 4 6 files changed, 308 insertions(+) diff -Nru ruby2.5-2.5.5/debian/changelog ruby2.5-2.5.5/debian/changelog --- ruby2.5-2.5.5/debian/changelog 2019-06-02 13:16:57.000000000 +0000 +++ ruby2.5-2.5.5/debian/changelog 2019-12-15 12:58:03.000000000 +0000 @@ -1,3 +1,14 @@ +ruby2.5 (2.5.5-3+deb10u1) buster-security; urgency=high + + * Non-maintainer upload by the Security Team. + * Fix for wrong fnmatch patttern (CVE-2019-15845) + * Loop with String#scan without creating substrings (CVE-2019-16201) + * WEBrick: prevent response splitting and header injection (CVE-2019-16254) + * lib/shell/command-processor.rb (Shell#[]): prevent unknown command + (CVE-2019-16255) + + -- Salvatore Bonaccorso Sun, 15 Dec 2019 13:58:03 +0100 + ruby2.5 (2.5.5-3) unstable; urgency=medium * ia64: Don't clear register_stack_start (Closes: #928068) diff -Nru ruby2.5-2.5.5/debian/patches/0012-Fix-for-wrong-fnmatch-patttern.patch ruby2.5-2.5.5/debian/patches/0012-Fix-for-wrong-fnmatch-patttern.patch --- ruby2.5-2.5.5/debian/patches/0012-Fix-for-wrong-fnmatch-patttern.patch 1970-01-01 00:00:00.000000000 +0000 +++ ruby2.5-2.5.5/debian/patches/0012-Fix-for-wrong-fnmatch-patttern.patch 2019-12-15 12:58:03.000000000 +0000 @@ -0,0 +1,44 @@ +From: Nobuyoshi Nakada +Date: Wed, 12 Dec 2018 14:38:09 +0900 +Subject: Fix for wrong fnmatch patttern +Origin: https://github.com/ruby/ruby/commit/a0a2640b398cffd351f87d3f6243103add66575b +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-15845 + +* dir.c (file_s_fnmatch): ensure that pattern does not contain a + NUL character. https://hackerone.com/reports/449617 +--- + dir.c | 2 +- + test/ruby/test_fnmatch.rb | 6 ++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/dir.c b/dir.c +index 6d1f50192743..d20cf60a7f4e 100644 +--- a/dir.c ++++ b/dir.c +@@ -3211,7 +3211,7 @@ file_s_fnmatch(int argc, VALUE *argv, VALUE obj) + else + flags = 0; + +- StringValue(pattern); ++ StringValueCStr(pattern); + FilePathStringValue(path); + + if (flags & FNM_EXTGLOB) { +diff --git a/test/ruby/test_fnmatch.rb b/test/ruby/test_fnmatch.rb +index f594a00ad3d6..16f1076e48cc 100644 +--- a/test/ruby/test_fnmatch.rb ++++ b/test/ruby/test_fnmatch.rb +@@ -160,4 +160,10 @@ def test_unicode + assert_file.fnmatch("[a-\u3042]*", "\u3042") + assert_file.not_fnmatch("[a-\u3042]*", "\u3043") + end ++ ++ def test_nullchar ++ assert_raise(ArgumentError) { ++ File.fnmatch("a\0z", "a") ++ } ++ end + end +-- +2.20.1 + diff -Nru ruby2.5-2.5.5/debian/patches/0013-Loop-with-String-scan-without-creating-substrings.patch ruby2.5-2.5.5/debian/patches/0013-Loop-with-String-scan-without-creating-substrings.patch --- ruby2.5-2.5.5/debian/patches/0013-Loop-with-String-scan-without-creating-substrings.patch 1970-01-01 00:00:00.000000000 +0000 +++ ruby2.5-2.5.5/debian/patches/0013-Loop-with-String-scan-without-creating-substrings.patch 2019-12-15 12:58:03.000000000 +0000 @@ -0,0 +1,79 @@ +From: Nobuyoshi Nakada +Date: Tue, 13 Aug 2019 12:14:28 +0900 +Subject: Loop with String#scan without creating substrings +Origin: https://github.com/ruby/ruby/commit/36e057e26ef2104bc2349799d6c52d22bb1c7d03 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-16201 + +Create the substrings necessary parts only, instead of cutting the +rest of the buffer. Also removed a useless, probable typo, regexp. +--- + lib/webrick/httpauth/digestauth.rb | 19 ++----------------- + test/webrick/test_httpauth.rb | 22 ++++++++++++++++++++++ + 2 files changed, 24 insertions(+), 17 deletions(-) + +diff --git a/lib/webrick/httpauth/digestauth.rb b/lib/webrick/httpauth/digestauth.rb +index 6416a40998f5..3cf12899d2f2 100644 +--- a/lib/webrick/httpauth/digestauth.rb ++++ b/lib/webrick/httpauth/digestauth.rb +@@ -290,23 +290,8 @@ def _authenticate(req, res) + + def split_param_value(string) + ret = {} +- while string.bytesize != 0 +- case string +- when /^\s*([\w\-\.\*\%\!]+)=\s*\"((\\.|[^\"])*)\"\s*,?/ +- key = $1 +- matched = $2 +- string = $' +- ret[key] = matched.gsub(/\\(.)/, "\\1") +- when /^\s*([\w\-\.\*\%\!]+)=\s*([^,\"]*),?/ +- key = $1 +- matched = $2 +- string = $' +- ret[key] = matched.clone +- when /^s*^,/ +- string = $' +- else +- break +- end ++ string.scan(/\G\s*([\w\-.*%!]+)=\s*(?:\"((?>\\.|[^\"])*)\"|([^,\"]*))\s*,?/) do ++ ret[$1] = $3 || $2.gsub(/\\(.)/, "\\1") + end + ret + end +diff --git a/test/webrick/test_httpauth.rb b/test/webrick/test_httpauth.rb +index 4df7141e857a..9fe8af8be215 100644 +--- a/test/webrick/test_httpauth.rb ++++ b/test/webrick/test_httpauth.rb +@@ -310,6 +310,28 @@ def test_digest_auth_int + } + end + ++ def test_digest_auth_invalid ++ digest_auth = WEBrick::HTTPAuth::DigestAuth.new(Realm: 'realm', UserDB: '') ++ ++ def digest_auth.error(fmt, *) ++ end ++ ++ def digest_auth.try_bad_request(len) ++ request = {"Authorization" => %[Digest a="#{'\b'*len}]} ++ authenticate request, nil ++ end ++ ++ bad_request = WEBrick::HTTPStatus::BadRequest ++ t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) ++ assert_raise(bad_request) {digest_auth.try_bad_request(10)} ++ limit = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0) ++ [20, 50, 100, 200].each do |len| ++ assert_raise(bad_request) do ++ Timeout.timeout(len*limit) {digest_auth.try_bad_request(len)} ++ end ++ end ++ end ++ + private + def credentials_for_request(user, password, params, body = nil) + cnonce = "hoge" +-- +2.20.1 + diff -Nru ruby2.5-2.5.5/debian/patches/0014-WEBrick-prevent-response-splitting-and-header-inject.patch ruby2.5-2.5.5/debian/patches/0014-WEBrick-prevent-response-splitting-and-header-inject.patch --- ruby2.5-2.5.5/debian/patches/0014-WEBrick-prevent-response-splitting-and-header-inject.patch 1970-01-01 00:00:00.000000000 +0000 +++ ruby2.5-2.5.5/debian/patches/0014-WEBrick-prevent-response-splitting-and-header-inject.patch 2019-12-15 12:58:03.000000000 +0000 @@ -0,0 +1,107 @@ +From: Yusuke Endoh +Date: Tue, 1 Oct 2019 12:29:18 +0900 +Subject: WEBrick: prevent response splitting and header injection +Origin: https://github.com/ruby/ruby/commit/3ce238b5f9795581eb84114dcfbdf4aa086bfecc +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-16254 + +This is a follow up to d9d4a28f1cdd05a0e8dabb36d747d40bbcc30f16. +The commit prevented CRLR, but did not address an isolated CR or an +isolated LF. + +Co-Authored-By: NARUSE, Yui +[Salvatore Bonaccorso: Backport to 2.5.5: + - Context changes in test/webrick/test_httpresponse.rb +] +--- + lib/webrick/httpresponse.rb | 3 +- + test/webrick/test_httpresponse.rb | 46 +++++++++++++++++++++++++++++-- + 2 files changed, 46 insertions(+), 3 deletions(-) + +diff --git a/lib/webrick/httpresponse.rb b/lib/webrick/httpresponse.rb +index 62d8056cf70b..f61d53230a8c 100644 +--- a/lib/webrick/httpresponse.rb ++++ b/lib/webrick/httpresponse.rb +@@ -400,7 +400,8 @@ def set_error(ex, backtrace=false) + private + + def check_header(header_value) +- if header_value =~ /\r\n/ ++ header_value = header_value.to_s ++ if /[\r\n]/ =~ header_value + raise InvalidHeader + else + header_value +diff --git a/test/webrick/test_httpresponse.rb b/test/webrick/test_httpresponse.rb +index 6263e0a71044..24a6968582e9 100644 +--- a/test/webrick/test_httpresponse.rb ++++ b/test/webrick/test_httpresponse.rb +@@ -29,7 +29,7 @@ def setup + @res.keep_alive = true + end + +- def test_prevent_response_splitting_headers ++ def test_prevent_response_splitting_headers_crlf + res['X-header'] = "malicious\r\nCookie: hack" + io = StringIO.new + res.send_response io +@@ -39,7 +39,7 @@ def test_prevent_response_splitting_headers + refute_match 'hack', io.string + end + +- def test_prevent_response_splitting_cookie_headers ++ def test_prevent_response_splitting_cookie_headers_crlf + user_input = "malicious\r\nCookie: hack" + res.cookies << WEBrick::Cookie.new('author', user_input) + io = StringIO.new +@@ -50,6 +50,48 @@ def test_prevent_response_splitting_cookie_headers + refute_match 'hack', io.string + end + ++ def test_prevent_response_splitting_headers_cr ++ res['X-header'] = "malicious\rCookie: hack" ++ io = StringIO.new ++ res.send_response io ++ io.rewind ++ res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) ++ assert_equal '500', res.code ++ refute_match 'hack', io.string ++ end ++ ++ def test_prevent_response_splitting_cookie_headers_cr ++ user_input = "malicious\rCookie: hack" ++ res.cookies << WEBrick::Cookie.new('author', user_input) ++ io = StringIO.new ++ res.send_response io ++ io.rewind ++ res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) ++ assert_equal '500', res.code ++ refute_match 'hack', io.string ++ end ++ ++ def test_prevent_response_splitting_headers_lf ++ res['X-header'] = "malicious\nCookie: hack" ++ io = StringIO.new ++ res.send_response io ++ io.rewind ++ res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) ++ assert_equal '500', res.code ++ refute_match 'hack', io.string ++ end ++ ++ def test_prevent_response_splitting_cookie_headers_lf ++ user_input = "malicious\nCookie: hack" ++ res.cookies << WEBrick::Cookie.new('author', user_input) ++ io = StringIO.new ++ res.send_response io ++ io.rewind ++ res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) ++ assert_equal '500', res.code ++ refute_match 'hack', io.string ++ end ++ + def test_304_does_not_log_warning + res.status = 304 + res.setup_header +-- +2.20.1 + diff -Nru ruby2.5-2.5.5/debian/patches/0015-lib-shell-command-processor.rb-Shell-prevent-unknown.patch ruby2.5-2.5.5/debian/patches/0015-lib-shell-command-processor.rb-Shell-prevent-unknown.patch --- ruby2.5-2.5.5/debian/patches/0015-lib-shell-command-processor.rb-Shell-prevent-unknown.patch 1970-01-01 00:00:00.000000000 +0000 +++ ruby2.5-2.5.5/debian/patches/0015-lib-shell-command-processor.rb-Shell-prevent-unknown.patch 2019-12-15 12:58:03.000000000 +0000 @@ -0,0 +1,63 @@ +From: usa +Date: Tue, 1 Oct 2019 11:01:53 +0000 +Subject: lib/shell/command-processor.rb (Shell#[]): prevent unknown command +Origin: https://github.com/ruby/ruby/commit/3af01ae1101e0b8815ae5a106be64b0e82a58640 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-16255 + +`FileTest.send(command, ...)` allows to call not only FileTest-related +methods but also any method that belongs to Kernel, Object, etc. +patched by + + +git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@67814 b2dd03c8-39d4-4d8f-98ff-823fe69b080e +--- + lib/shell/command-processor.rb | 3 +++ + test/shell/test_command_processor.rb | 18 ++++++++++++++++++ + 2 files changed, 21 insertions(+) + +diff --git a/lib/shell/command-processor.rb b/lib/shell/command-processor.rb +index b52cb0043f75..08ea5c874c12 100644 +--- a/lib/shell/command-processor.rb ++++ b/lib/shell/command-processor.rb +@@ -180,6 +180,9 @@ def test(command, file1, file2=nil) + top_level_test(command, file1) + end + else ++ unless FileTest.methods(false).include?(command.to_sym) ++ raise "unsupported command: #{ command }" ++ end + if file2 + FileTest.send(command, file1, file2) + else +diff --git a/test/shell/test_command_processor.rb b/test/shell/test_command_processor.rb +index 06b5ecc1d9b4..51e14b5a6954 100644 +--- a/test/shell/test_command_processor.rb ++++ b/test/shell/test_command_processor.rb +@@ -67,6 +67,24 @@ def test_system_directory + Dir.rmdir(path) + end + ++ def test_test ++ name = "foo#{exeext}" ++ path = File.join(@tmpdir, name) ++ open(path, "w", 0644) {} ++ ++ assert_equal(true, @shell[?e, path]) ++ assert_equal(true, @shell[:e, path]) ++ assert_equal(true, @shell["e", path]) ++ assert_equal(true, @shell[:exist?, path]) ++ assert_equal(true, @shell["exist?", path]) ++ assert_raise_with_message(RuntimeError, /unsupported command/) do ++ assert_equal(true, @shell[:instance_eval, path]) ++ end ++ ensure ++ Process.waitall ++ File.unlink(path) ++ end ++ + def test_option_type + name = 'foo.cmd' + path = File.join(@tmpdir, name) +-- +2.20.1 + diff -Nru ruby2.5-2.5.5/debian/patches/series ruby2.5-2.5.5/debian/patches/series --- ruby2.5-2.5.5/debian/patches/series 2019-06-02 13:16:57.000000000 +0000 +++ ruby2.5-2.5.5/debian/patches/series 2019-12-15 12:58:03.000000000 +0000 @@ -9,3 +9,7 @@ 0009-test-test_pair-fix-deadlock-in-test_connect_accept_n.patch 0010-test-use-larger-keys-for-SSL-tests.patch 0011-ia64-Don-t-clear-register_stack_start.patch +0012-Fix-for-wrong-fnmatch-patttern.patch +0013-Loop-with-String-scan-without-creating-substrings.patch +0014-WEBrick-prevent-response-splitting-and-header-inject.patch +0015-lib-shell-command-processor.rb-Shell-prevent-unknown.patch