0

Is there any way to manipulate (read, write, etc..) a file descriptor for any app which can be found in the path /proc/{pid}/fd?

Especially for sockets.

$ ll /proc/4229/fd
total 0
lrwx------. 1 vagrant vagrant 64 May 18 01:10 0 -> socket:[34147]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 1 -> socket:[34149]
lr-x------. 1 vagrant vagrant 64 May 18 01:10 10 -> /dev/null
lrwx------. 1 vagrant vagrant 64 May 18 01:10 11 -> socket:[34943]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 13 -> socket:[34945]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 14 -> socket:[34948]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 15 -> socket:[34950]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 2 -> socket:[34151]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 3 -> socket:[34153]
lr-x------. 1 vagrant vagrant 64 May 18 01:10 4 -> pipe:[34155]
l-wx------. 1 vagrant vagrant 64 May 18 01:10 5 -> pipe:[34155]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 6 -> anon_inode:[eventpoll]
lr-x------. 1 vagrant vagrant 64 May 18 01:10 7 -> pipe:[34156]
l-wx------. 1 vagrant vagrant 64 May 18 01:10 8 -> pipe:[34156]
lrwx------. 1 vagrant vagrant 64 May 18 01:10 9 -> anon_inode:[eventfd]
  • 2
    Please don't post screenshots when you can simply copy/paste text. Text is searchable, but images are not. Remote images can also disappear over time. – garethTheRed May 17 '16 at 20:25
  • @garethTheRed you are right, done. – faressoft May 18 '16 at 1:16
0

Technically, almost anything is possible with ptrace() / gdb. Search results.

Using ptrace() is arch-dependent, awkward, and AFAICT no-one's implemented it for you. The popular application is to inject an fd into the process, but that's about the opposite of what you want.

I thought about what would be required and it looks very painful.

You could use the gdb script approach, and look at the source code of screenify. It's probably still very awkward to communicate FDs from within gdb. The way you communicate fds is to send them as "ancillary data" using sendmsg() over a unix socket.

Unfortunately sending ancillary data is usually done using a macro. While gdb does an amazing impression of a C interpreter, I don't think it's possible to use macros.

The other way you pass fds is using fork(), so that might provide some slightly easier options (combined with exec()). Unfortunately it looks like ptrace() and fork() are not best friends. There are some linux-specific gdb commands which might do the job, but it only mentions support for breakpoints; it doesn't say whether you can get the gdb command call fork() to work sensibly. Even if it works, you might need to mess with FD_CLOEXEC (close-on-exec) as well. That's a macro too.

It's not too hard to find the numeric value of a simple macro (that's how screenify was written). The macro interface for sending ancillary data isn't very complicated, so it might be easier to reverse engineer that instead.

| improve this answer | |

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