1

I'm trying to find the file descriptors for all TCP sockets of a given process, ie. given its pid, so that I can get the socket option at another process without modifying the original one.

For example, if I know the file descriptor is fd, then I hope to call getsockopt(fd, ...) to retrieve the options at another process. I'm wondering is this doable? If so, how to get the fd I need outside the original process?

I have tried to print out the return value when creating a socket, ie. s = socket(...); printf("%d\n", s);, keeping the original process running and call getsockopt(s, ...) somewhere else but it doesn't work - it seems that such return value is process-dependent.

I have also found the solution with unix domain sockets but I don't want to modify the codes of original process.

As for reading \proc\<PID>\fd directly or leveraging lsof, I'd like to say I don't know how to find what I need from them. My gut feeling is that they could be potential solutions.

Of course any other ideas are welcome as well. To be honest, I'm not very familiar with the file descriptor mechanism in Linux.

Boris Stitnicky
  • 12,444
  • 5
  • 57
  • 74
zzy
  • 751
  • 1
  • 13
  • 25
  • 2
    File descriptors are process specific. E.g. 0 = stdin 1 = stdout and 2 = stderr. So first socket or file opened in every process will get a fd of 3 or more. – Sameer Naik Aug 07 '16 at 04:06
  • You haven't explained what *exactly* it is you're trying to figure out anyway. What information are you looking for that `lsof` or `ss` cannot provide? – Jonathon Reinhart Aug 07 '16 at 04:09
  • @JonathonReinhart I want to get the socket option from another process. Therefore I hope to somehow retrieve the fd by `lsof`, or any other commands. – zzy Aug 07 '16 at 04:10
  • @SameerNaik Thank you! Yes that's what I find. So is there any global fd for the system? – zzy Aug 07 '16 at 04:11
  • 1
    ***Which*** socket option? Again, a file descriptor is just an integer. By itself it is useless. I don't understand why you won't explain exactly what it is you're trying to do. – Jonathon Reinhart Aug 07 '16 at 04:12
  • *"is there any global fd for the system?"* If you would read any documentation on UNIX, or simply my answer, you would understand that the answer is ***NO***. File descriptors are inherently *per-process*. – Jonathon Reinhart Aug 07 '16 at 04:14
  • @JonathonReinhart Let me make it clear. I opened a browser, the browser opened a TCP socket connection to a website. This socket has its options, such as this one: `getoptsock(s, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen)`. I want to retrieve these options from another process. It doesn't matter which option it is. Please let me know if it's still not clear enough. – zzy Aug 07 '16 at 04:16
  • Look at the man page for `ss`: http://man7.org/linux/man-pages/man8/ss.8.html If this utility cannot show you what you are after, then nothing can. – Jonathon Reinhart Aug 07 '16 at 04:18
  • 1
    This [answer](http://stackoverflow.com/a/15243049/5781248) mentions systemtap that might provide means to extract socket related information from processes. – J.J. Hakala Aug 07 '16 at 04:33
  • @J.J.Hakala Thank you! "intercept socket options set by a process" from the second answer is exactly what I need. Do you have any idea whether it is possible to port to C/JAVA/Python (the author said "this is not possible in Python")? I'm sorry that I know little about "SystemTap". – zzy Aug 07 '16 at 04:44
  • You might like to read around here: https://sourceware.org/systemtap/ – alk Aug 07 '16 at 09:31

1 Answers1

5

No. You simply cannot do what you are asking.

A file descriptor is just an integer, but it refers to an open file object in a given process. That integer value in another process refers to a different, possibly unopened file object.

Without involving the ptrace debugging API, or remote code injection, you are limited to what the kernel exposes to you via /proc.

Check out the man page for ss. If this utility can't show you information about a socket you desire, then nothing can.

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • So does the kernel expose sth like a global fd at `/proc`? – zzy Aug 07 '16 at 04:13
  • *"global fd"* There is no such thing. They are ***per-process***. `/proc//fd` will show you the file desriptors that a process has open. – Jonathon Reinhart Aug 07 '16 at 04:15
  • Thanks! Then is it possible to get access to the file object opened by another process? This file object must exist somewhere I think. – zzy Aug 07 '16 at 04:19
  • 1
    If it were possible to do what you ask, it would be a huge security weakness. Without injecting code into the other process, or writing a custom kernel module, no. You can not access that file descriptor. Period. – Jonathon Reinhart Aug 07 '16 at 04:23
  • OK I got it. Thank you very much! I'll look for other ways from kernel side. – zzy Aug 07 '16 at 04:33