Bug #11877
closedSocket.gethostname will fail when the hostname length == RUBY_MAX_HOST_NAME_LEN
Description
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
Updated by nagachika (Tomoyuki Chikanaga) about 8 years ago
- Status changed from Open to Closed
- Assignee set to nobu (Nobuyoshi Nakada)
fixed in trunk at r53677.
Updated by usa (Usaku NAKAMURA) about 8 years ago
- Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED
Updated by usa (Usaku NAKAMURA) about 8 years ago
- Backport changed from 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED to 2.1: DONE, 2.2: REQUIRED, 2.3: REQUIRED
ruby_2_1 r53936 merged revision(s) 53677.
Updated by nagachika (Tomoyuki Chikanaga) about 8 years ago
- Backport changed from 2.1: DONE, 2.2: REQUIRED, 2.3: REQUIRED to 2.1: DONE, 2.2: DONE, 2.3: REQUIRED
Backported into ruby_2_2
branch at r54070.
Updated by naruse (Yui NARUSE) about 8 years ago
- Backport changed from 2.1: DONE, 2.2: DONE, 2.3: REQUIRED to 2.1: DONE, 2.2: DONE, 2.3: DONE
ruby_2_3 r54360 merged revision(s) 53677.