Project

General

Profile

Actions

Bug #12185

closed

Missing symbol inspect_tcpi_msec

Added by wiz (Thomas Klausner) about 8 years ago. Updated about 8 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:74388]

Description

I originally reported this issue on ruby-talk, but Ryan Davis told me to file a bug report instead.

I'm building ruby (2.2.x and 2.3.x) on NetBSD 7.99.26/amd64 from
pkgsrc.

Recently we have discussed improving the security features, and added
some options to pkgsrc for that. One of them is relro ("Full RELRO" as
per
http://tk-blog.blogspot.co.at/2009/02/relro-not-so-well-known-memory.html;
i.e. add "-Wl,-z,relro,-z,now" to the compiler flags) which maps the
GOT read-only.

I've enabled this in my local builds, and most stuff still builds.
However there are problems with ruby-2.2.4 and ruby-2.3.0.

For ruby-2.2.4, relro breaks the installation phase:

installing bundle gems:       /usr/pkg/lib/ruby/gems/2.2.0 (build_info, cache, doc, extensions, gems, specifications)
/scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require': /scratch/lang/ruby22-base/work/ruby-2.2.4/.ext/x86_64-netbsd/socket.so: Undefined
+symbol "inspect_tcpi_msec" (symnum = 74) - /scratch/lang/ruby22-base/work/ruby-2.2.4/.ext/x86_64-netbsd/socket.so (LoadError)
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/.ext/common/socket.rb:1:in `<top (required)>'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/net/protocol.rb:21:in `<top (required)>'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/net/http.rb:22:in `<top (required)>'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/request.rb:1:in `<top (required)>'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/remote_fetcher.rb:2:in `<top (required)>'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/spec_fetcher.rb:1:in `<top (required)>'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/dependency_installer.rb:5:in `<top (required)>'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /scratch/lang/ruby22-base/work/ruby-2.2.4/lib/rubygems.rb:562:in `install'
        from ./tool/rbinstall.rb:722:in `block (2 levels) in <main>'
        from ./tool/rbinstall.rb:721:in `each'
        from ./tool/rbinstall.rb:721:in `block in <main>'
        from ./tool/rbinstall.rb:757:in `call'
        from ./tool/rbinstall.rb:757:in `block in <main>'
        from ./tool/rbinstall.rb:754:in `each'
        from ./tool/rbinstall.rb:754:in `<main>'
*** Error code 1

The rbconfig.rb diffs between a working and a breaking build are:

176c176
<   CONFIG["LDFLAGS"] = "-L. -L/usr/lib -Wl,-R/usr/lib -L/usr/pkg/lib -Wl,-R/usr/pkg/lib -pthread -fstack-protector -Wl,-export-dynamic"
---
>   CONFIG["LDFLAGS"] = "-L. -Wl,-z,relro -Wl,-z,now -L/usr/lib -Wl,-R/usr/lib -L/usr/pkg/lib -Wl,-R/usr/pkg/lib -pthread -fstack-protector -Wl,-export-dynamic"

For ruby-2.3.0, the breakage is different. Ruby itself builds and
installs without problems, but some modules fail to install. For me
locally, e.g. colorator, ffi, kramdown, liquid, mercenary, ....

The breakage looks happens in the configuration stage and looks like
this:

===> Extracting for ruby23-colorator-0.1
ERROR:  Loading command: unpack (LoadError)
        /usr/pkg/lib/ruby/2.3.0/x86_64-netbsd/socket.so: Undefined symbol "inspect_tcpi_msec" (symnum = 74) - /usr/pkg/lib/ruby/2.3.0/x86_64-netbsd/socket.so
ERROR:  While executing gem ... (NoMethodError)
    undefined method `invoke_with_build_args' for nil:NilClass
*** Error code 1

I started looking for this symbol and found for ruby-2.2.4 in ext/socket/option.c

#if defined(__linux__) || defined(__sun)
static void
inspect_tcpi_msec(VALUE ret, const char *prefix, uint32_t t)
{
    rb_str_catf(ret, "%s%u.%03us", prefix, t / 1000, t % 1000);
}
#endif

#ifdef __FreeBSD__
# define inspect_tcpi_rto(ret, t) inspect_tcpi_usec(ret, " rto=", t)
# define inspect_tcpi_last_data_recv(ret, t) inspect_tcpi_usec(ret, " last_data_recv=", t)
# define inspect_tcpi_rtt(ret, t) inspect_tcpi_usec(ret, " rtt=", t)
# define inspect_tcpi_rttvar(ret, t) inspect_tcpi_usec(ret, " rttvar=", t)
#else
# define inspect_tcpi_rto(ret, t) inspect_tcpi_usec(ret, " rto=", t)
# define inspect_tcpi_ato(ret, t) inspect_tcpi_usec(ret, " ato=", t)
# define inspect_tcpi_last_data_sent(ret, t) inspect_tcpi_msec(ret, " last_data_sent=", t)
# define inspect_tcpi_last_data_recv(ret, t) inspect_tcpi_msec(ret, " last_data_recv=", t)
# define inspect_tcpi_last_ack_sent(ret, t) inspect_tcpi_msec(ret, " last_ack_sent=", t)
# define inspect_tcpi_last_ack_recv(ret, t) inspect_tcpi_msec(ret, " last_ack_recv=", t)
# define inspect_tcpi_rtt(ret, t) inspect_tcpi_usec(ret, " rtt=", t)
# define inspect_tcpi_rttvar(ret, t) inspect_tcpi_usec(ret, " rttvar=", t)
# define inspect_tcpi_rcv_rtt(ret, t) inspect_tcpi_usec(ret, " rcv_rtt=", t)
#endif

This code hasn't changed for ruby-2.3.0.

So it looks like this symbol is missing for !Linux && !Solaris, and
FreeBSD works around it. I don't see why these operating systems are
handled specially, it looks straightforward enough to use it
everywhere.

Can this please be made unconditional?

Bonus question:
I don't understand why this only makes a difference with relro.
Does anyone have an idea about that?
The symbol is missing the socket.so file even with relro, but doesn't cause an issue.

Updated by nobu (Nobuyoshi Nakada) about 8 years ago

  • Description updated (diff)
  • Status changed from Open to Feedback

Does ext/socket/extconf.h differ between with and without relro?

Actions #2

Updated by nobu (Nobuyoshi Nakada) about 8 years ago

  • Status changed from Feedback to Closed

Applied in changeset r54139.


socket/option.c: accurate condition

  • ext/socket/option.c (inspect_tcpi_msec): more accurate condition
    for TCPI msec member inspection function.
    [ruby-core:74388] [Bug #12185]

Updated by wiz (Thomas Klausner) about 8 years ago

ext/socket/extconf.h does not differ between with and without relro.

Thank you for the quick commit. I can confirm that it fixes the problem for me.

Updated by usa (Usaku NAKAMURA) about 8 years ago

  • Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: DONTNEED, 2.2: REQUIRED, 2.3: REQUIRED

Updated by nagachika (Tomoyuki Chikanaga) about 8 years ago

  • Backport changed from 2.1: DONTNEED, 2.2: REQUIRED, 2.3: REQUIRED to 2.1: DONTNEED, 2.2: DONE, 2.3: REQUIRED

Backported into ruby_2_2 branch at r54247.

Updated by naruse (Yui NARUSE) about 8 years ago

  • Backport changed from 2.1: DONTNEED, 2.2: DONE, 2.3: REQUIRED to 2.1: DONTNEED, 2.2: DONE, 2.3: DONE

ruby_2_3 r54363 merged revision(s) 54139.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0