Issue #11877 has been updated by Tomoyuki Chikanaga.

Status changed from Open to Closed
Assignee set to Nobuyoshi Nakada

fixed in trunk at r53677.

----------------------------------------
Bug #11877: Socket.gethostname will fail when the hostname length == RUBY_MAX_HOST_NAME_LEN
https://bugs.ruby-lang.org/issues/11877#change-56930

* Author: Niall Sheridan
* Status: Closed
* Priority: Normal
* Assignee: Nobuyoshi Nakada
* ruby -v: 
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
----------------------------------------
When `Socket.gethostname` calls `gethostname()` with a buffer `buf`, the buffer is incorrectly sized (at least on Linux systems).
`RUBY_MAX_HOST_NAME_LEN` is defined as `HOST_NAME_MAX` and the buffer `buf` is sized as `RUBY_MAX_HOST_NAME_LEN + 1`.
But when `gethostname()` is called, the size parameter is passed as `sizeof buf -1`. In effect, `gethostname` is called with `RUBY_MAX_HOST_NAME_LEN` as the size of the receiving buffer.

The string returned by `gethostname()` _includes_ the null-terminating character, so the receiving buffer must be sized accordingly. Because `buf` is created as `buf[RUBY_MAX_HOST_NAME_LEN+1]` it's adequately sized to hold the hostname and null terminator, but actual call is `gethostname(buf, (int)sizeof buf - 1)`. This means that if the length of the hostname is equal to the max hostname length then the call to `gethostname()` will fail as it will not have space for the null terminator.

This can be seen on Linux which has a 64 character limit on hostnames:


Setting a 64 character hostname:

~~~
$ hostname abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01
$ hostname
abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01
$ irb
irb(main):001:0> require 'socket'
=> true
irb(main):002:0> Socket.gethostname
Errno::ENAMETOOLONG: File name too long - gethostname
	from (irb):2:in `gethostname'
	from (irb):2
	from /usr/local/bin/irb:12:in `<main>'
~~~

Setting a 63 character hostname:

~~~
$ hostname abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0
$ hostname
abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0
$ irb
irb(main):001:0> require 'socket'
=> true
irb(main):002:0> Socket.gethostname
=> "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0"
irb(main):003:0> Socket.gethostname.length
=> 63
~~~

The attached patch uses the correctly sized buffer to hold the full hostname, including the null terminator that gethostname() includes.

---Files--------------------------------
hostname_size.patch (408 Bytes)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>