Context:
recvfrom() stores the source address of a received package in the sockaddr structure pointed to by the address pointer and the length of the address is stored in the memory pointed to by the address_len argument.
Problem description:
However, not all protocol provide source addresses, e.g. AF_UNIX does not.
In this case, the contents of the address parameter is "unspecified" [1] and should not be inspected. I have not found it in the specification, but in practice I have observed that at least on Linux address_len is set to 0
recvBufFrom does not check address_len at all and instead tries to parse the contents of address directly [2]. This leads to an error because it interprets the zeroed memory as AF_UNSPEC which is not supported. The error is ignored and getPeerName is called, which also fails.
The solution is to peek ptr_len and check if it is 0, and if so to return an "unset" address. I'm not sure how best to represent such an address, perhaps SockAddrUnix [] would do the trick?
Compare also how Rust handles the situation [3]
I have included a minimal code example that reproduced the problem [4]
Context:
recvfrom()stores the source address of a received package in thesockaddrstructure pointed to by theaddresspointer and the length of the address is stored in the memory pointed to by theaddress_lenargument.Problem description:
However, not all protocol provide source addresses, e.g. AF_UNIX does not.
In this case, the contents of the
addressparameter is "unspecified" [1] and should not be inspected. I have not found it in the specification, but in practice I have observed that at least on Linuxaddress_lenis set to 0recvBufFromdoes not checkaddress_lenat all and instead tries to parse the contents ofaddressdirectly [2]. This leads to an error because it interprets the zeroed memory asAF_UNSPECwhich is not supported. The error is ignored andgetPeerNameis called, which also fails.The solution is to
peek ptr_lenand check if it is0, and if so to return an "unset" address. I'm not sure how best to represent such an address, perhapsSockAddrUnix []would do the trick?Compare also how Rust handles the situation [3]
I have included a minimal code example that reproduced the problem [4]
network/Network/Socket/Buffer.hsc
Lines 114 to 126 in 26e9d3c