Opened 7 years ago

Closed 5 years ago

#6937 closed enhancement (implemented)

SocksPipe or SocksSocket - an anonymous pipe to smoke network leakings bug out (of)

Reported by: ioerror Owned by:
Priority: Medium Milestone: Tor: unspecified
Component: Core Tor/Tor Version: Tor: unspecified
Severity: Keywords: security needs-proposal tor-client
Cc: nickm, andrea, arma Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

It seems that to make use of some kernel filtering and sandboxing, we may want to explore alternate ways of performing IPC between Firefox/Pidgin/xmpp-client/Thunderbird/etc and Tor.

I propose that we have a very small shim and call it ort. The job of ort would be to locate a named pipe (such as on windows, where it may be full duplex) or a Unix Domain Socket, connect to it and simply shuffle bytes between the application, ort and Tor. Tor would treat ort clients as SOCKS clients and effectively, we could ban applications for even being allowed to make any kind of network connections.

AppArmor as an example it may allow or deny 'inet stream' or 'inet socket' but it will not do anything useful beyond allowing or denying. So if inet sockets are allowed, they may be for 8.8.8.8 or 127.0.0.1 - we need to allow the latter and so the former would potentially leak out.

Most of the code for Unix Domain Sockets is already implemented in the ControlSocket code, I think. The named pipe or better yet, anonymous (!) pipes approach may be better, as well as more portable. On Solaris, I suppose we could use a door but I'm fairly certain that zero people would use it.

In an ideal case, I think we'd want to use pipes as that would allow us to use ort to shim up any application, simply block all inet/inet6 socket calls and call it a day. In this way, we would also be able to create a different channels for special requests - such as DNS requests that aren't resolvable via SOCKS5 and Tor normally.

Child Tickets

Change History (26)

comment:1 Changed 7 years ago by nickm

Keywords: needs-proposal added

comment:2 Changed 7 years ago by ioerror

If we use Unix Sockets, we can probably use setsocketopt() with SO_PASSCRED to ensure that only authorized clients use the SocksSocket.

I agree with nick that this likely needs a proposal but I also think first I'm going to research it a bit more. The two different ways to implement such a feature have very different semantic security realities.

comment:3 Changed 7 years ago by ioerror

Cc: andrea added; athena removed

comment:4 Changed 7 years ago by ioerror

It appears that on Windows we might want to use a Named Pipe as they are Full Duplex: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365590(v=vs.85).aspx

comment:5 Changed 7 years ago by ioerror

It also seems that we could use a Named Pipe on Linux as long as the hypothetical ort shim ensures that the data is smaller than PIPE_BUF bytes. Anything more and it will interleave client requests (!) to the pipe.

I suggest that at first, we add a Unix Domain Socket simply to have a basic full duplex thing that works, then a full duplex named pipe with PIPE_BUF sized chunks on the client, and finally a full duplex named pipe for win32. We might want to try something with anonymous pipes but I'm not sure of the point - perhaps if we have developed the Tor Browser zygote idea further we might want it in that specific case?

In theory, one of those should work and all of them add security context information, each should bypass a local firewall and allow us to jail applications more effectively.

Thoughts?

comment:6 Changed 7 years ago by ioerror

I'm not exactly sure of how to ensure that we have a known pipe name for all tor enabled applications... On Win32, we could have '
.\pipe\tor-shim' and on GNU/Linux we could have '/tmp/tor-shim' - the main problem is of course that we can't actually ensure that we'd get those names.

I wonder how Tor handles this for the control socket? Won't Unix Domain Sockets have similar problems?

comment:7 Changed 7 years ago by ioerror

This page is really great for summarizing the nightmare that awaits us: http://tinyclouds.org/iocp-links.html

comment:8 Changed 7 years ago by andrea

Named pipes aren't what you want at all. I don't know how portable that assumption about interleaving is, and I think doing something like that most definitely breaks the whole "the interface to this looks like SOCKS5" thing. Stick with AF_UNIX.

As for Windows IPC, I really don't know anything about Windows ... or have the ability to build for it, or test on it.

comment:9 Changed 7 years ago by andrea

I say where I want my control socket in my torrc; I suppose if I tried to run two tor processes it'd break horribly. Yeah, the same thing applies to AF_UNIX as to named pipes; the addresses for the AF_UNIX address family are actually just paths to a socket node. My torrc has:

ControlSocket /var/run/tor/control
ControlSocketsGroupWritable 1

... and then I get:

root@dysnomia:~ [5]# ls -l /var/run/tor
total 4
srw-rw---- 1 tor tor 0 Sep 16 16:00 control
-rw-r----- 1 tor tor 32 Sep 16 16:00 control_auth_cookie

comment:10 in reply to:  8 Changed 7 years ago by rransom

Replying to andrea:

Named pipes aren't what you want at all. I don't know how portable that assumption about interleaving is, and I think doing something like that most definitely breaks the whole "the interface to this looks like SOCKS5" thing. Stick with AF_UNIX.

From the write(3posix) man page (allegedly based on ‘IEEE Std 1003.1, 2003 Edition’):

       Write  requests to a pipe or FIFO shall be handled in the same way as a
       regular file with the following exceptions:

...

        * Write  requests of {PIPE_BUF} bytes or less shall not be interleaved
          with data from other processes doing writes on the same pipe. Writes
          of greater than {PIPE_BUF} bytes may have data interleaved, on arbi‐
          trary boundaries, with writes by other processes, whether or not the
          O_NONBLOCK flag of the file status flags is set.

(But getting a reply back to the right client is an exercise in reinventing AF_LOCAL.)

As for Windows IPC, I really don't know anything about Windows ... or have the ability to build for it, or test on it.

Wine is not entirely broken for some simple programs, and MinGW can cross-build from a sane environment.

comment:11 Changed 7 years ago by ioerror

At robert's suggestion, I think anything here is really best called 'AF_PIPE_KLUDGE'

comment:13 Changed 7 years ago by ioerror

Hilariously, Solaris Doors are actually used enough that people ported them to GNU/Linux (sadly only the 2.4.x kernel):
http://www.rampant.org/doors/

comment:15 Changed 7 years ago by ioerror

I'll open another ticket about a related idea and I'll also describe it here first. Regardless of what we use as the Application -> Tor transport, we want a way for Applications, including *other* Tor clients on the system, to know that Tor is running and how to reach it. It seems that we could solve a lot of file system permissions by creating a globally shared segment of memory, filling it with information on ways to reach Tor and letting each application pick the most reasonable method for connections.

It seems reasonable to do this with shm_open - regardless of what we stuff inside. We could at least then easily-configure all apps to understand that they should look for a running Tor with shm_open() - we just need to pick a name, such as 'tor-shim' and then stick with it. In this sense, any application could launch a tor and all other applications could find it and use it *but* they wouldn't need to launch a reasonable Tor was already running. shmget, shm_open and others all seem reasonably straight forward on GNU/Linux and CreateSharedMemory is the Win32 cousin.

Tor could have/use this default shred mutex to create or read from at startup.

comment:16 Changed 7 years ago by ioerror

I've opened #6948 to expand the zygote mutex idea.

comment:17 in reply to:  8 ; Changed 7 years ago by arma

Replying to andrea:

Named pipes aren't what you want at all. I don't know how portable that assumption about interleaving is, and I think doing something like that most definitely breaks the whole "the interface to this looks like SOCKS5" thing. Stick with AF_UNIX.

ioerror asked for my feedback here. My feedback is "sounds worth continuing to investigate; I'll defer to nickm and andrea on what is actually worthwhile to implement."

I expect the portability side to be a big hassle. But if it's straightforward to stop using sockets, I agree that it's a big win -- mainly because apparmor and friends are so crappy at handling network permissions with any granularity.

comment:18 in reply to:  17 ; Changed 7 years ago by rransom

Replying to arma:

I expect the portability side to be a big hassle. But if it's straightforward to stop using sockets, I agree that it's a big win -- mainly because apparmor and friends are so crappy at handling network permissions with any granularity.

Every Unixoid GUI program needs to use AF_LOCAL sockets to connect to the X server, so there's absolutely no way that hacking up Tor (and everything that might want to talk to it) to use a crappy kludged-up reimplementation of AF_LOCAL sockets using named pipes and userland parsing/unparsing goo will provide a security benefit.

comment:19 Changed 7 years ago by rransom

I should also add here that adding a crapload of unnecessary complexity to everything other than AppArmor in order to make AppArmor look less ineffective as a ‘security’ feature is utterly stupid. If AppArmor can't block access to some AF_LOCAL sockets without blocking access to all of them, then AppArmor needs to be fixed.

And then we'll finally be assured that TBB-Firefox on Linux can't do anything worse than send a log of my keystrokes out over Tor and run and control arbitrary GUI ‘apps’ on my X display. How comforting -- NOT.

comment:20 in reply to:  18 Changed 7 years ago by ioerror

Replying to rransom:

Replying to arma:

I expect the portability side to be a big hassle. But if it's straightforward to stop using sockets, I agree that it's a big win -- mainly because apparmor and friends are so crappy at handling network permissions with any granularity.

Every Unixoid GUI program needs to use AF_LOCAL sockets to connect to the X server, so there's absolutely no way that hacking up Tor (and everything that might want to talk to it) to use a crappy kludged-up reimplementation of AF_LOCAL sockets using named pipes and userland parsing/unparsing goo will provide a security benefit.

Which is why at the very least AF_LOCAL is a reasonable way to allow programs to connect to Tor's SOCKS interface. However, AF_UNIX is not available on Win32 and so we'll need to find another way to connect Tor Browser to Tor's SOCKS port that is the equivalent of AF_UNIX.

comment:21 in reply to:  19 Changed 7 years ago by ioerror

Replying to rransom:

I should also add here that adding a crapload of unnecessary complexity to everything other than AppArmor in order to make AppArmor look less ineffective as a ‘security’ feature is utterly stupid. If AppArmor can't block access to some AF_LOCAL sockets without blocking access to all of them, then AppArmor needs to be fixed.

Adding a SocksSocket to Tor isn't a crapload of unnecessary complexity. We already have the code for most of it in the implementation of ControlSocket. Furthermore, we already have some code for the client side ControlSocket in Vidalia.

And then we'll finally be assured that TBB-Firefox on Linux can't do anything worse than send a log of my keystrokes out over Tor and run and control arbitrary GUI ‘apps’ on my X display. How comforting -- NOT.

On Windows we'll solve a lot of problems. We'll finally be rid of the local firewall problem for one. We'll also be able to isolate bundled apps from programs that use a SOCKS port without opening many socks ports or (confusing to the user) adding usernames/passwords, and so on. Additionally, we'll be able to write more confining jails for each platform for our bundled applications like Tor Browser.

On GNU/Linux and other similar platforms, we'll similarly resolve the local firewall problem - which should allow us to jail users from sending *any* network traffic in many ways and without having to enable a TransPort. We'll also be able to solve our bundled app issues as well.

Replying to rransom:

I should also add here that adding a crapload of unnecessary complexity to everything other than AppArmor in order to make AppArmor look less ineffective as a ‘security’ feature is utterly stupid. If AppArmor can't block access to some AF_LOCAL sockets without blocking access to all of them, then AppArmor needs to be fixed.

Adding a SocksSocket to Tor isn't a crapload of unnecessary complexity. We already have the code for most of it in the implementation of ControlSocket. Furthermore, we already have some code for the client side ControlSocket in Vidalia.

And then we'll finally be assured that TBB-Firefox on Linux can't do anything worse than send a log of my keystrokes out over Tor and run and control arbitrary GUI ‘apps’ on my X display. How comforting -- NOT.

On Windows we'll solve a lot of problems. We'll finally be rid of the local firewall problem for one. We'll also be able to isolate bundled apps from programs that use a SOCKS port without opening many socks ports or (confusing to the user) adding usernames/passwords, and so on. Additionally, we'll be able to write more confining jails for each platform for our bundled applications like Tor Browser.

This SocksSocket idea won't do anything to solve the fundamental X windows problems and that is fine. That isn't a problem that we're trying to solve and it seems like a red herring.

comment:22 Changed 7 years ago by nickm

Keywords: tor-client added

comment:23 Changed 7 years ago by nickm

Component: Tor ClientTor

comment:24 Changed 7 years ago by nickm

Milestone: Tor: 0.2.4.x-finalTor: unspecified

comment:25 Changed 5 years ago by ioerror

I've implemented something like this in #12585.

comment:26 Changed 5 years ago by dgoulet

Resolution: implemented
Status: newclosed

#12585 has been implemented and now in 0.2.6. SocksPort unix:<path> is the way to use a Unix socket as a SocksPort.

Closing this one and marking it as implemented. Please reopen if you think #12585 was not enough.

Note: See TracTickets for help on using tickets.