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


akr (Akira Tanaka) wrote:
>  > However, if the longest path in sockaddr_un is not supported, this code doesn't work.
>  
>  It seems not so trivial.
> 
>  Also, is the code work well with Ruby 1.9.2 (or earlier Ruby 1.9.3)
>  and Ruby 2.0?

Yes.

In Ruby 1.9.2, Socket.pack_sockaddr_un(name) raises an ArgumentError because name contains NUL, and extra NULs are not filled explicitly, but addrlen is always set to sizeof(struct sockaddr_un) by UNIXSocket.open, so the address of the socket is "\0foo" + "\0" * (UNIX_MATH_PATH - "\0foo".bytesize).
In Ruby 2.0, addr.bytesize < SIZE_OF_SOCKADDR_UN evaluates to true, so extra NULs are filled explicitly, and thus the address of the socket is "\0foo" + "\0" * (UNIX_MATH_PATH - "\0foo".bytesize).

"\0foo" + "\0" * (UNIX_MATH_PATH - "\0foo".bytesize) is used as the address of a socket in
the current Ruby 1.9.3 and earlier versions, and it's a valid address, so it should be able to be used as a socket address even if this bug is fixed.

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

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/