Issue #7786 has been updated by shugo (Shugo Maeda).


akr (Akira Tanaka) wrote:
> 2013/2/5 shugo (Shugo Maeda) <redmine / ruby-lang.org>:
>  
>  > * support the longest path in sockaddr_un.
>  >   * This change is necessary for backward compatibility.  Without it, the old name filled with extra NULs cannot be specified like UNIXSocket.open(name + "\0" * (108 - name.bytesize)).
>  
>  I'm not sure about compatibility here.
>  
>  If someone uses UNIXServer.open("\0foo") and UNIXSocket.open("\0foo") for
>  current Ruby, how they should be modified with compatible fasion?

The following code uses the name "\0foo\0\0\0....." even if the patch is applied.
  require "socket"
  
  OFFSET_OF_SUN_PATH = 2
  UNIX_PATH_MAX = 108
  SIZE_OF_SOCKADDR_UN = OFFSET_OF_SUN_PATH + UNIX_PATH_MAX
  name = "\0foo"
  begin
    addr = Socket.pack_sockaddr_un(name)
    if addr.bytesize < SIZE_OF_SOCKADDR_UN
      # append extra NULs for broken abstract namespace handling.
      sun_path = name + "\0" * (UNIX_PATH_MAX - name.bytesize)
    else
      sun_path = name
    end
  rescue ArgumentError
    sun_path = name
  end
  UNIXSocket.open(sun_path) do
    # ...
  end

However, if the longest path in sockaddr_un is not supported, this code doesn't work.

----------------------------------------
Backport #7786: fix for abstract namespace
https://bugs.ruby-lang.org/issues/7786#change-35874

Author: shugo (Shugo Maeda)
Status: Assigned
Priority: Normal
Assignee: usa (Usaku NAKAMURA)
Category: 
Target version: 


=begin
Please apply the attached patch to Ruby 1.9.3.

In Ruby 1.9.3, the addrlen argument for bind(2) and connect(2) is set to sizeof(struct sockaddr_un).
However, on Linux, if sun_path starts with NUL, which means that the socket's address is in abstract namespace, the first (addrlen  - sizeof(sa_family_t)) bytes of sun_path is used as the name of the socket, so the socket name is filled with extra NULs unintentionally.  Please see unix(7) for details.

The patch introduces a new function rsock_unix_sockaddr_len() to calculate the correct address length on Linux.

Besides that, the patch includes the following changes.

* fix Socket.unix_server_socket not to access the file system if the specified name is in abstract namespace.
* fix rsock_init_unixsock to use rb_inspect() to avoid ArgumentError in rb_sys_fail_str() when path includes NUL.
* support the longest path in sockaddr_un.
  * This change is necessary for backward compatibility.  Without it, the old name filled with extra NULs cannot be specified like UNIXSocket.open(name + "\0" * (108 - name.bytesize)).
=end



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