[ruby-core:123878] [Ruby Bug#21702] `UNIXSocket` on Windows: suprising results in `#recvfrom` and `#remote_address`
Issue #21702 has been reported by trinistr (Alexander Bulancov). ---------------------------------------- Bug #21702: `UNIXSocket` on Windows: suprising results in `#recvfrom` and `#remote_address` https://bugs.ruby-lang.org/issues/21702 * Author: trinistr (Alexander Bulancov) * Status: Open * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Support for `UNIXSocket` on Windows was added in #19135. Through testing in ruby/spec, I identified unexpected results in two methods: 1. `#remote_address.to_s` always returns 110 bytes, compared to `#local_address.to_s` which returns only needed bytes. Example: ```ruby # test (@addr is remote_address, @b is the socket created with UNIXServer#accept): @addr.to_s.should == @b.local_address.to_s # failure: "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" == "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00" ``` Note how the address is correct, and `#unix_path`s are indeed equal, but there are NUL bytes filling the string representation up to 110 bytes. This number does not depend on the length of path name. 2. Much more worryingly, `UNIXSocket#recvfrom` **dumps 2047 bytes of memory** as the remote address: ```ruby # test: @server.recvfrom(5).should == ['hello', ['AF_UNIX', '']] # failure: ["hello",["AF_UNIX","\x14\xB3v\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xAB\xCD\x12C\xFF\x7F<snip>"]] == ["hello", ["AF_UNIX", ""]] ``` This seems to be a result of `union_sockaddr` having a `char place_holder[2048]` member inside, though it isn't clear why is this used instead of `sockaddr_un` member. These results are obtained from GitHub runners, as I don't have a machine to test directly. This is the PR in ruby/spec which brought this up: https://github.com/ruby/spec/pull/1300. -- https://bugs.ruby-lang.org/
Issue #21702 has been updated by nobu (Nobuyoshi Nakada). Status changed from Open to Third Party's Issue Whether it's a bug or a specification, both are the same as winsock. Please report to Microsoft. ---------------------------------------- Bug #21702: `UNIXSocket` on Windows: suprising results in `#recvfrom` and `#remote_address` https://bugs.ruby-lang.org/issues/21702#change-115289 * Author: trinistr (Alexander Bulancov) * Status: Third Party's Issue * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Support for `UNIXSocket` on Windows was added in #19135. Through testing in ruby/spec, I identified unexpected results in two methods: 1. `#remote_address.to_s` always returns 110 bytes, compared to `#local_address.to_s` which returns only needed bytes. Example: ```ruby # test (@addr is remote_address, @b is the socket created with UNIXServer#accept): @addr.to_s.should == @b.local_address.to_s # failure: "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" == "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00" ``` Note how the address is correct, and `#unix_path`s are indeed equal, but there are NUL bytes filling the string representation up to 110 bytes. This number does not depend on the length of path name. This is probably related to `#pack_sockaddr_un`. 2. Much more worryingly, `UNIXSocket#recvfrom` **dumps 2047 bytes of memory** as the remote address: ```ruby # test: @server.recvfrom(5).should == ['hello', ['AF_UNIX', '']] # failure: ["hello",["AF_UNIX","\x14\xB3v\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xAB\xCD\x12C\xFF\x7F<snip>"]] == ["hello", ["AF_UNIX", ""]] ``` This seems to be a result of `union_sockaddr` having a `char place_holder[2048]` member inside, though it isn't clear why is this used instead of `sockaddr_un` member. These results are obtained from GitHub runners, as I don't have a machine to test directly. This is the PR in ruby/spec which brought this up: https://github.com/ruby/spec/pull/1300. -- https://bugs.ruby-lang.org/
Issue #21702 has been updated by Eregon (Benoit Daloze). @nobu The `char place_holder[2048]` is something in Ruby not Windows though. Why does CRuby not stop at the first `\0`? This is path, so it's defined as `\0`-terminated, no? ---------------------------------------- Bug #21702: `UNIXSocket` on Windows: suprising results in `#recvfrom` and `#remote_address` https://bugs.ruby-lang.org/issues/21702#change-115781 * Author: trinistr (Alexander Bulancov) * Status: Third Party's Issue * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Support for `UNIXSocket` on Windows was added in #19135. Through testing in ruby/spec, I identified unexpected results in two methods: 1. `#remote_address.to_s` always returns 110 bytes, compared to `#local_address.to_s` which returns only needed bytes. Example: ```ruby # test (@addr is remote_address, @b is the socket created with UNIXServer#accept): @addr.to_s.should == @b.local_address.to_s # failure: "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" == "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00" ``` Note how the address is correct, and `#unix_path`s are indeed equal, but there are NUL bytes filling the string representation up to 110 bytes. This number does not depend on the length of path name. This is probably related to `#pack_sockaddr_un`. 2. Much more worryingly, `UNIXSocket#recvfrom` **dumps 2047 bytes of memory** as the remote address: ```ruby # test: @server.recvfrom(5).should == ['hello', ['AF_UNIX', '']] # failure: ["hello",["AF_UNIX","\x14\xB3v\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xAB\xCD\x12C\xFF\x7F<snip>"]] == ["hello", ["AF_UNIX", ""]] ``` This seems to be a result of `union_sockaddr` having a `char place_holder[2048]` member inside, though it isn't clear why is this used instead of `sockaddr_un` member. These results are obtained from GitHub runners, as I don't have a machine to test directly. This is the PR in ruby/spec which brought this up: https://github.com/ruby/spec/pull/1300. -- https://bugs.ruby-lang.org/
Issue #21702 has been updated by nobu (Nobuyoshi Nakada). The length is exactly what is returned by winsock. ---------------------------------------- Bug #21702: `UNIXSocket` on Windows: suprising results in `#recvfrom` and `#remote_address` https://bugs.ruby-lang.org/issues/21702#change-116060 * Author: trinistr (Alexander Bulancov) * Status: Open * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Support for `UNIXSocket` on Windows was added in #19135. Through testing in ruby/spec, I identified unexpected results in two methods: 1. `#remote_address.to_s` always returns 110 bytes, compared to `#local_address.to_s` which returns only needed bytes. Example: ```ruby # test (@addr is remote_address, @b is the socket created with UNIXServer#accept): @addr.to_s.should == @b.local_address.to_s # failure: "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" == "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00" ``` Note how the address is correct, and `#unix_path`s are indeed equal, but there are NUL bytes filling the string representation up to 110 bytes. This number does not depend on the length of path name. This is probably related to `#pack_sockaddr_un`. 2. Much more worryingly, `UNIXSocket#recvfrom` **dumps 2047 bytes of memory** as the remote address: ```ruby # test: @server.recvfrom(5).should == ['hello', ['AF_UNIX', '']] # failure: ["hello",["AF_UNIX","\x14\xB3v\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xAB\xCD\x12C\xFF\x7F<snip>"]] == ["hello", ["AF_UNIX", ""]] ``` This seems to be a result of `union_sockaddr` having a `char place_holder[2048]` member inside, though it isn't clear why is this used instead of `sockaddr_un` member. These results are obtained from GitHub runners, as I don't have a machine to test directly. This is the PR in ruby/spec which brought this up: https://github.com/ruby/spec/pull/1300. -- https://bugs.ruby-lang.org/
Issue #21702 has been updated by Eregon (Benoit Daloze). I see, how about we use `strlen()` then since clearly the length returned by winsock is incorrect and we know this is path so it must be \0-terminated? ---------------------------------------- Bug #21702: `UNIXSocket` on Windows: suprising results in `#recvfrom` and `#remote_address` https://bugs.ruby-lang.org/issues/21702#change-116070 * Author: trinistr (Alexander Bulancov) * Status: Open * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Support for `UNIXSocket` on Windows was added in #19135. Through testing in ruby/spec, I identified unexpected results in two methods: 1. `#remote_address.to_s` always returns 110 bytes, compared to `#local_address.to_s` which returns only needed bytes. Example: ```ruby # test (@addr is remote_address, @b is the socket created with UNIXServer#accept): @addr.to_s.should == @b.local_address.to_s # failure: "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" == "\x01\x00D:/a/spec/spec/rubyspec_temp/2032_3/unix.sock\x00" ``` Note how the address is correct, and `#unix_path`s are indeed equal, but there are NUL bytes filling the string representation up to 110 bytes. This number does not depend on the length of path name. This is probably related to `#pack_sockaddr_un`. 2. Much more worryingly, `UNIXSocket#recvfrom` **dumps 2047 bytes of memory** as the remote address: ```ruby # test: @server.recvfrom(5).should == ['hello', ['AF_UNIX', '']] # failure: ["hello",["AF_UNIX","\x14\xB3v\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xAB\xCD\x12C\xFF\x7F<snip>"]] == ["hello", ["AF_UNIX", ""]] ``` This seems to be a result of `union_sockaddr` having a `char place_holder[2048]` member inside, though it isn't clear why is this used instead of `sockaddr_un` member. These results are obtained from GitHub runners, as I don't have a machine to test directly. This is the PR in ruby/spec which brought this up: https://github.com/ruby/spec/pull/1300. -- https://bugs.ruby-lang.org/
participants (3)
-
Eregon (Benoit Daloze) -
nobu (Nobuyoshi Nakada) -
trinistr (Alexander Bulancov)