Thursday, September 14, 2017

Re: ruby security releases

On 09/14 12:55, Jeremy Evans wrote:
> Ruby 2.2.8, 2.3.5, and 2.4.2 were released today. 2.3.5 and 2.4.2
> contain bugfixes, and all three versions fix security issues.
> See the following release announcements:
>
> https://www.ruby-lang.org/en/news/2017/09/14/ruby-2-4-2-released/
> https://www.ruby-lang.org/en/news/2017/09/14/ruby-2-3-5-released/
> https://www.ruby-lang.org/en/news/2017/09/14/ruby-2-2-8-released/
>
> Below is a diff for upgrading to these versions. I'll be working
> on backporting the security fixes to 2.1 and 1.8 when I have time.

Here's the backport to ruby 1.8 and 2.1, as well as the port of the
webrick security fix to jruby. The backport of the sprintf security fix
to ruby 1.8 was tricky and could benefit from some additional eyes.

Briefly tested on amd64. I'll be committing this weekend unless
I hear objections.

Thanks,
Jeremy

Index: lang/jruby/Makefile
===================================================================
RCS file: /cvs/ports/lang/jruby/Makefile,v
retrieving revision 1.68
diff -u -p -r1.68 Makefile
--- lang/jruby/Makefile 15 Sep 2017 03:06:13 -0000 1.68
+++ lang/jruby/Makefile 15 Sep 2017 03:13:50 -0000
@@ -13,6 +13,8 @@ DISTFILES = ${DISTNAME}.tar.gz \
jnr-jffi-1.2.2-0-g4c196bb.tar.gz:0 \
${JRUBY_LAUNCHER_GEM}:1

+REVISION = 0
+
HOMEPAGE = http://www.jruby.org/

MAINTAINER = Jeremy Evans <jeremy@openbsd.org>
Index: lang/jruby/patches/patch-lib_ruby_stdlib_webrick_httpstatus_rb
===================================================================
RCS file: lang/jruby/patches/patch-lib_ruby_stdlib_webrick_httpstatus_rb
diff -N lang/jruby/patches/patch-lib_ruby_stdlib_webrick_httpstatus_rb
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lang/jruby/patches/patch-lib_ruby_stdlib_webrick_httpstatus_rb 15 Sep 2017 03:13:50 -0000
@@ -0,0 +1,18 @@
+$OpenBSD$
+
+Fix CVE-2017-10784.
+
+Index: lib/ruby/stdlib/webrick/httpstatus.rb
+--- lib/ruby/stdlib/webrick/httpstatus.rb.orig
++++ lib/ruby/stdlib/webrick/httpstatus.rb
+@@ -23,10 +23,6 @@ module WEBrick
+ ##
+ # Root of the HTTP status class hierarchy
+ class Status < StandardError
+- def initialize(*args) # :nodoc:
+- args[0] = AccessLog.escape(args[0]) unless args.empty?
+- super(*args)
+- end
+ class << self
+ attr_reader :code, :reason_phrase # :nodoc:
+ end
Index: lang/jruby/patches/patch-lib_ruby_stdlib_webrick_log_rb
===================================================================
RCS file: lang/jruby/patches/patch-lib_ruby_stdlib_webrick_log_rb
diff -N lang/jruby/patches/patch-lib_ruby_stdlib_webrick_log_rb
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lang/jruby/patches/patch-lib_ruby_stdlib_webrick_log_rb 15 Sep 2017 03:13:50 -0000
@@ -0,0 +1,20 @@
+$OpenBSD$
+
+Fix CVE-2017-10784.
+
+Index: lib/ruby/stdlib/webrick/log.rb
+--- lib/ruby/stdlib/webrick/log.rb.orig
++++ lib/ruby/stdlib/webrick/log.rb
+@@ -118,10 +118,10 @@ module WEBrick
+ # * Otherwise it will return +arg+.inspect.
+ def format(arg)
+ if arg.is_a?(Exception)
+- "#{arg.class}: #{arg.message}\n\t" <<
++ "#{arg.class}: #{AccessLog.escape(arg.message)}\n\t" <<
+ arg.backtrace.join("\n\t") << "\n"
+ elsif arg.respond_to?(:to_str)
+- arg.to_str
++ AccessLog.escape(arg.to_str)
+ else
+ arg.inspect
+ end
Index: lang/ruby/1.8/Makefile
===================================================================
RCS file: /cvs/ports/lang/ruby/1.8/Makefile,v
retrieving revision 1.44
diff -u -p -r1.44 Makefile
--- lang/ruby/1.8/Makefile 12 Jun 2017 10:57:57 -0000 1.44
+++ lang/ruby/1.8/Makefile 15 Sep 2017 03:13:50 -0000
@@ -20,7 +20,7 @@ PKGNAME-ri_docs= ruby-ri_docs-${VERSION}
PKG_ARCH-ri_docs= *
PKGSPEC-main= ruby->=1.8,<1.9

-REVISION-main= 8
+REVISION-main= 9
REVISION-iconv= 0
REVISION-ri_docs= 1

Index: lang/ruby/1.8/patches/patch-lib_webrick_httpstatus_rb
===================================================================
RCS file: lang/ruby/1.8/patches/patch-lib_webrick_httpstatus_rb
diff -N lang/ruby/1.8/patches/patch-lib_webrick_httpstatus_rb
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lang/ruby/1.8/patches/patch-lib_webrick_httpstatus_rb 15 Sep 2017 03:13:50 -0000
@@ -0,0 +1,16 @@
+$OpenBSD$
+
+Index: lib/webrick/httpstatus.rb
+--- lib/webrick/httpstatus.rb.orig
++++ lib/webrick/httpstatus.rb
+@@ -13,10 +13,6 @@ module WEBrick
+ module HTTPStatus
+
+ class Status < StandardError
+- def initialize(*args)
+- args[0] = AccessLog.escape(args[0]) unless args.empty?
+- super(*args)
+- end
+ class << self
+ attr_reader :code, :reason_phrase
+ end
Index: lang/ruby/1.8/patches/patch-lib_webrick_log_rb
===================================================================
RCS file: lang/ruby/1.8/patches/patch-lib_webrick_log_rb
diff -N lang/ruby/1.8/patches/patch-lib_webrick_log_rb
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lang/ruby/1.8/patches/patch-lib_webrick_log_rb 15 Sep 2017 03:13:50 -0000
@@ -0,0 +1,18 @@
+$OpenBSD$
+
+Index: lib/webrick/log.rb
+--- lib/webrick/log.rb.orig
++++ lib/webrick/log.rb
+@@ -61,10 +61,10 @@ module WEBrick
+
+ def format(arg)
+ str = if arg.is_a?(Exception)
+- "#{arg.class}: #{arg.message}\n\t" <<
++ "#{arg.class}: #{AccessLog.escape(arg.message)}\n\t" <<
+ arg.backtrace.join("\n\t") << "\n"
+ elsif arg.respond_to?(:to_str)
+- arg.to_str
++ AccessLog.escape(arg.to_str)
+ else
+ arg.inspect
+ end
Index: lang/ruby/1.8/patches/patch-sprintf_c
===================================================================
RCS file: lang/ruby/1.8/patches/patch-sprintf_c
diff -N lang/ruby/1.8/patches/patch-sprintf_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lang/ruby/1.8/patches/patch-sprintf_c 15 Sep 2017 03:13:50 -0000
@@ -0,0 +1,93 @@
+$OpenBSD$
+
+Index: sprintf.c
+--- sprintf.c.orig
++++ sprintf.c
+@@ -728,6 +728,8 @@ rb_str_format(argc, argv, fmt)
+ #if defined(_WIN32) && !defined(__BORLANDC__)
+ if (isnan(fval) || isinf(fval)) {
+ const char *expr;
++ int elen;
++ char sign = '\0';
+
+ if (isnan(fval)) {
+ expr = "NaN";
+@@ -736,51 +738,40 @@ rb_str_format(argc, argv, fmt)
+ expr = "Inf";
+ }
+ need = strlen(expr);
+- if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
+- need++;
+- else if (flags & FSPACE)
+- need++;
++ elen = need;
++ i = 0;
++ if (!isnan(fval) && fval < 0.0)
++ sign = '-';
++ else if (flags & (FPLUS|FSPACE))
++ sign = (flags & FPLUS) ? '+' : ' ';
++ if (sign)
++ ++need;
+ if ((flags & FWIDTH) && need < width)
+ need = width;
+
+- CHECK(need);
+- sprintf(&buf[blen], "%*s", need, "");
++#define FILL(c, l) do { \
++ if ((l) <= 0) break;\
++ CHECK(l);\
++ FILL_(c, l);\
++} while (0)
++
++#define FILL_(c, l) do { \
++ memset(&buf[blen], (c), (l));\
++ blen += (l);\
++} while (0)
++
++
++ FILL(' ', need);
+ if (flags & FMINUS) {
+- if (!isnan(fval) && fval < 0.0)
+- buf[blen++] = '-';
+- else if (flags & FPLUS)
+- buf[blen++] = '+';
+- else if (flags & FSPACE)
+- blen++;
+- strncpy(&buf[blen], expr, strlen(expr));
++ if (sign)
++ buf[blen - need--] = sign;
++ memcpy(&buf[blen - need], expr, elen);
+ }
+- else if (flags & FZERO) {
+- if (!isnan(fval) && fval < 0.0) {
+- buf[blen++] = '-';
+- need--;
+- }
+- else if (flags & FPLUS) {
+- buf[blen++] = '+';
+- need--;
+- }
+- else if (flags & FSPACE) {
+- blen++;
+- need--;
+- }
+- while (need-- - strlen(expr) > 0) {
+- buf[blen++] = '0';
+- }
+- strncpy(&buf[blen], expr, strlen(expr));
+- }
+ else {
+- if (!isnan(fval) && fval < 0.0)
+- buf[blen + need - strlen(expr) - 1] = '-';
+- else if (flags & FPLUS)
+- buf[blen + need - strlen(expr) - 1] = '+';
+- strncpy(&buf[blen + need - strlen(expr)], expr,
+- strlen(expr));
++ if (sign)
++ buf[blen - elen - 1] = sign;
++ memcpy(&buf[blen - elen], expr, elen);
+ }
+- blen += strlen(&buf[blen]);
+ break;
+ }
+

No comments:

Post a Comment