Backport #7775

backport r38993 (ignore truncated part of socket address) to 1.9.3

Added by Akira Tanaka about 1 year ago. Updated about 1 year ago.

[ruby-core:51824]
Status:Closed
Priority:Normal
Assignee:Usaku NAKAMURA

Description

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(sunpath) non-NUL-terminated path to bind() creates a
socket address which is one byte longer than sizeof(struct sockaddr
un).

In that case, rbstrnew(socketaddress->sunpath, returnedlength),
rbstrnew 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.

sockaddr-ignore-truncated-r38993-to-193.patch Magnifier (3.8 KB) Akira Tanaka, 02/03/2013 09:04 PM

Associated revisions

Revision 39094
Added by Usaku NAKAMURA about 1 year ago

merge revision(s) 38993: [Backport #7775]

* ext/socket/basicsocket.c (bsock_getsockname): ignore truncated
  part of socket address.
  (bsock_getpeername): ditto.
  (bsock_local_address): ditto.
  (bsock_remote_address): ditto.

* ext/socket/unixsocket.c (unix_path): ditto.
  (unix_addr): ditto.
  (unix_peeraddr): ditto.

* ext/socket/init.c (cloexec_accept): ditto.

History

#1 Updated by Usaku NAKAMURA about 1 year ago

  • Status changed from Open to Assigned
  • Assignee set to Usaku NAKAMURA

#2 Updated by Usaku NAKAMURA about 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r39094.
Akira, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


merge revision(s) 38993: [Backport #7775]

* ext/socket/basicsocket.c (bsock_getsockname): ignore truncated
  part of socket address.
  (bsock_getpeername): ditto.
  (bsock_local_address): ditto.
  (bsock_remote_address): ditto.

* ext/socket/unixsocket.c (unix_path): ditto.
  (unix_addr): ditto.
  (unix_peeraddr): ditto.

* ext/socket/init.c (cloexec_accept): ditto.

Also available in: Atom PDF