Issue #7775 has been updated by usa (Usaku NAKAMURA).

Status changed from Open to Assigned
Assignee set to usa (Usaku NAKAMURA)


----------------------------------------
Backport #7775: backport r38993 (ignore truncated part of socket address) to 1.9.3
https://bugs.ruby-lang.org/issues/7775#change-35855

Author: akr (Akira Tanaka)
Status: Assigned
Priority: Normal
Assignee: usa (Usaku NAKAMURA)
Category: 
Target version: 


Please apply the attached patch,
sockaddr-ignore-truncated-r38993-to-193.patch, to Ruby 1.9.3.

The patch modifies returned addrlen after getsockaddr, getpeername and accept.

They takes a buffer with the length and
kernel returns a socket address in the buffer and returns its length.

When a socket address length is longer than the buffer length,
Most OS returns the real socket address length.
(Exception: NetBSD returns the buffer length.)

Apart from that, some OS provide a way to create Unix domain socket
longer than sockaddr_un.

For example, since GNU/Linux adds a NUL for pathname which is not NUL-terminated,
giving sizeof(sun_path) non-NUL-terminated path to bind() creates a
socket address which is one byte longer than sizeof(struct sockaddr_un).

In that case, rb_str_new(socketaddress->sun_path, returned_length),
rb_str_new reads a byte just after the buffer.

The patch modifies the returned length as shorten to the buffer length
to avoid such read.
It is not a problem on GNU/Linux because the truncated data is always a NUL
because GNU/Linux forbid a pathname longer than sizeof(sun_path) for
Unix domain socket.

Note that providing larger buffer for getsockname/getpeername/accept
seems a practical option but it is another issue.
Also note that retrying the system calls is not general solution because
accept() is not retryable -- retrying accept() waits a next connection.



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