Tuesday, November 08, 2022

Re: socksify (from security/dante) and pledged programs

On 2022/11/08 17:05, Caspar Schutijser wrote:
> Hi all,
>
> Using socksify (from the security/dante port) in combination with
> pledged programs doesn't go very well. For those who don't know,
> socksify makes programs communicate through a SOCKS proxy by using
> LD_PRELOAD.
>
> Example:
> # pkg_add dante # No configuration necessary for this example
> $ socksify ftp -o /dev/null https://example.org/
> Trying 93.184.216.34...
> Abort trap (core dumped)
> $ dmesg | tail -1
> ftp[14267]: pledge "inet", syscall 118
>
> Using gdb and reading the code, I found that a call to getsockopt()
> related to multicast stuff in the dante code is to blame:
> lib/socket.c, line 699:
> 683 int
> 684 socks_socketisforlan(s)
> 685 const int s;
> 686 {
> ...
> 693 /*
> 694 * make an educated guess as to whether the socket is intended for
> 695 * lan-only use or not.
> 696 */
> 697
> 698 len = sizeof(addr);
> 699 if (getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &addr, &len) != 0) {
> 700 slog(LOG_DEBUG, "%s: getsockopt(IP_MULTICAST_IF) failed: %s",
> 701 function, strerror(errno));
> 702
> 703 errno = errno_s;
> 704 return 0;
> 705 }
>
> (The socks_socketisforlan() function is called in Rconnect() located
> in lib/Rconnect.c.)
>
> What would be the best way forward here? Patch away the code that calls
> getsockopt(IP_MULTICAST_IF)? Something else? I don't have any good
> ideas, in part because I don't know enough about why dante cares about
> this, and because I'm not a multicast expert.

It's using various heuristics to try to skip SOCKS-wrapping for network
connections which are intended to run over LAN and are not going to be
remote connections.

In the general case it's probably not very useful, but might be needed
to make dante work sanely with some software...though I kind-of doubt
people are very likely to want to run that socksified on OpenBSD,
so it might be good enough to neuter those checks.

Another option might be to add a wrapper for pledge() and set a flag
if it's used, then skip doing this mcast check if the flag is set.
Way more fiddly though.

(no, I'm definitely not going to suggest wrapping calls to pledge() and
s/inet/inet mcast/ in the string, that would be terrible ;)

As you probably found, you are going to have a hard time with web
searches for e.g. "dante multicast" because Dante is also a protocol for
running media over IP on a bunch of pro audio/visual kit, and yes, it
uses multicast too...

No comments:

Post a Comment