Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is it possible on Linux for a process to write inside a socket open by another one?

Let's say I open a connection to google.com using netcat:

myuser@linux:~$ nc google.com 80

Now I can lookup for the process pid and open its file descriptor folder:

myuser@linux:~$ ls -la /proc/24105/fd
totale 0
dr-x------ 2 myuser myuser  0 2012-03-10 19:01 .
dr-xr-xr-x 7 myuser myuser  0 2012-03-10 19:01 ..
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 0 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 1 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:01 2 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 3 -> socket:[3947162]

So now I would like to make the HTTP request using an echo inside that socket:

myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/3
bash: /proc/24285/fd/3: no such device or address

Doing it as root doesn't change the result.

I can't write inside the socket but I can write inside the stdin:

myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/0
myuser@linux:~$

But it's not what I want to do.

I was thinking: a Linux socket should be treated like a file, isn't it? One or more processes can use the same socket, so why can't I do this?

share|improve this question
    
It doesnt look like it is possible. First this is a socket, not a fifo, so you cant just echo to it like a normal file. nc can do this, but trying to do so results in "Transport endpoint is not connected". Example command nc -v --send-only -U /proc/123/fd/3 <<< 'GET /'$'\n\n' –  Patrick Mar 10 '12 at 18:43
    
what? Why should I use the -U (Unix socket) option? By the way I can't understand how it can be useful –  otaku22 Mar 10 '12 at 21:58
1  
I found a bad workaround using gdb: gdb -p 24285 and then I can write inside the file descriptor using call write(3, "test",4). It works, but I would like to do the same thing from the procfile because the use of gdb requires to stop the process (so rises the risk of crashes or other bad things) –  otaku22 Mar 10 '12 at 22:22
add comment

2 Answers 2

I'd say it is possible, but both processes need to cooperate to do this. You can have one process send a file descriptor over a socket connection to another process. I found this example, which seems to work on an up-to-date Arch linux machine.

share|improve this answer
add comment

This isn't possible because it would be difficult to implement and rarely useful. Sockets are a lot more complex than pipes:

  • Sockets are bidirectional.
  • There are different types of sockets. Some sockets aren't streams of bytes (e.g. UDP sockets are datagram sockets, which send packets and not bytes).
  • Sockets perform multiplexing (and there's some overloading between sockets used by servers waiting for connections and sockets used by actual opened connections).

Because sockets are bidirectional, they are often used to communicate under bidirectional protocols. If you inject data into the conversation, the other side might send a response to your data, and there is no way to dispatch the response to the right requester. This considerably reduces the usefulness of allowing data injection on sockets.

If you're trying to contact the same server as an existing client and not tack onto an existing conversation, there is already a way to do that: contact the server in the same way (open a socket on the filesystem, or to a TCP or UDP port). If the socket is a nameless one between two processes, that's a good hint that you aren't supposed to join in, so the operating system doesn't make it easy.

With a datagram socket (not the case here), you couldn't directly inject data because the shell only understands streams of bytes, it doesn't know to call send instead of write to send a packet.

If you have the cooperation of one endpoint, you can tell make use file descriptor passing 1 2 3.

Otherwise, you can make the process that has the socket open send the data itself, with ptrace (that's what gdb uses under the hood). This suspends the process, very much by design, so that your dirty tricks don't confuse the process too much. Even with the process suspended, you run a major risk of making the process's data structures inconsistent with the reality of the data or environment modifications that you've injected. (Note that even if the system allowed injecting data over a socket, there would be a similar, if lesser, risk of confusing the process with these inconsistencies.)

share|improve this answer
    
Sounds interesting: lxr.linux.no/linux+v3.2.11/net/socket.c#L146 –  otaku22 Mar 14 '12 at 23:33
    
@otaku22 Leading to In theory you can't get an open on this inode, but /proc provides a back door. Remember to keep it shut otherwise you'll let the creepy crawlies in. My answer aims to show what these creepy crawlies are, I don't know if there's a more official or more complete presentation elsewhere. –  Gilles Mar 14 '12 at 23:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.