You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It would be useful to be able to redirect outgoing TCP traffic over a SOCKS proxy, like what torsocks does. There are at least 2 ways we might be able to do this:
The application will try to issue a connect syscall, followed by a send syscall. We can intercept the connect syscall and change the destination IP/port to that of the SOCKS proxy. Then, we can intercept the send syscall, which will contain a pointer (in tracee memory space) to the buffer that the application wants to send. We can prepend a SOCKS handshake to that buffer. This was my original idea while writing the project proposal for Outreachy. It's not a great design because it requires fiddling with the tracee's memory, which is not consistent with our goal of memory safety.
Linux v5.6 added a new feature that allows the tracer to duplicate a file descriptor from the tracee without needing to mess with the tracee's memory. This is much more in the spirit of security and memory safety [1], and is probably preferable. The relevant feature is called pidfd_getfd. Documentation exists on man7.org, and further context is available at Phoronix, LWN, and copyconstruct.medium.com, among other sites that I found with a quick DuckDuckGo . The implementation would look like this: we intercept the entrance to the connect syscall, and change the destination IP/port like in approach 1. Then we intercept the exit of the connect syscall, which returns a file descriptor containing the established socket. We duplicate that file descriptor to the tracer via pidfd_getfd, and then immediately perform a SOCKS5 handshake with that socket in the tracer. We then resume the tracee, and everything is SOCKSified; no need to intercept the send syscall.
I am not worried about requiring Linux v5.6. It excludes Debian Buster (Linux v4.19), but I don't think anyone is seriously using Buster for anything security-focused. It also excludes environments like Talos Skiroot (Linux v5.5), but I'm quite sure no one is running Tor inside Skiroot. Debian Buster-Backports and Debian Bullseye are both on Linux v5.10, which will handle it fine. There is a security-focused use case where Linux v5.6 isn't available, which is the ast GPU driver; this driver is popular with security-focused users, but is partially broken in Linux releases from v5.6 to v6.2 inclusive. But I do not think that's worth making our code more complex; users who run the ast driver and need to SOCKSify with ptrace can reasonably be expected to install Linux v6.3 or higher.
Maybe there are other approaches, but the above two are the ones that occurred to me.
[1] This is part of a general trend in Linux to try to avoid forcing programs to manually do memory management that the kernel already can easily do. See kexec_file_load, which is a safer replacement for kexec_load, for another example that's directly relevant to u-root.
The text was updated successfully, but these errors were encountered:
It would be useful to be able to redirect outgoing TCP traffic over a SOCKS proxy, like what torsocks does. There are at least 2 ways we might be able to do this:
connect
syscall, followed by asend
syscall. We can intercept theconnect
syscall and change the destination IP/port to that of the SOCKS proxy. Then, we can intercept thesend
syscall, which will contain a pointer (in tracee memory space) to the buffer that the application wants to send. We can prepend a SOCKS handshake to that buffer. This was my original idea while writing the project proposal for Outreachy. It's not a great design because it requires fiddling with the tracee's memory, which is not consistent with our goal of memory safety.pidfd_getfd
. Documentation exists on man7.org, and further context is available at Phoronix, LWN, and copyconstruct.medium.com, among other sites that I found with a quick DuckDuckGo . The implementation would look like this: we intercept the entrance to theconnect
syscall, and change the destination IP/port like in approach 1. Then we intercept the exit of theconnect
syscall, which returns a file descriptor containing the established socket. We duplicate that file descriptor to the tracer viapidfd_getfd
, and then immediately perform a SOCKS5 handshake with that socket in the tracer. We then resume the tracee, and everything is SOCKSified; no need to intercept thesend
syscall.I am not worried about requiring Linux v5.6. It excludes Debian Buster (Linux v4.19), but I don't think anyone is seriously using Buster for anything security-focused. It also excludes environments like Talos Skiroot (Linux v5.5), but I'm quite sure no one is running Tor inside Skiroot. Debian Buster-Backports and Debian Bullseye are both on Linux v5.10, which will handle it fine. There is a security-focused use case where Linux v5.6 isn't available, which is the
ast
GPU driver; this driver is popular with security-focused users, but is partially broken in Linux releases from v5.6 to v6.2 inclusive. But I do not think that's worth making our code more complex; users who run theast
driver and need to SOCKSify with ptrace can reasonably be expected to install Linux v6.3 or higher.Maybe there are other approaches, but the above two are the ones that occurred to me.
[1] This is part of a general trend in Linux to try to avoid forcing programs to manually do memory management that the kernel already can easily do. See
kexec_file_load
, which is a safer replacement forkexec_load
, for another example that's directly relevant to u-root.The text was updated successfully, but these errors were encountered: