Linuxでは、関係のないプロセスで実行されているファイル記述子をコピーしたいと思います。私は知っていますメッセージを送信(2)そしてSCM_RIGHTS
(例えばhttps://stackoverflow.com/questions/4489433/sending-file-descriptor-over-unix-domain-socket-and-select)、しかし、これは他のプロセスが協力している場合にのみ機能します。他のプロセスの積極的な協力を必要としないソリューションが必要です。また、ファイル記述子を最初に作成し、コピーをアーカイブしてから別のプロセスを作成できることもわかっていますが、他のプロセスが独自のファイル記述子を作成できるようにするソリューションが必要です。
ファイル記述子を見ることができます。
$ ls -l /proc/13115/fd/3
lrwx------ 1 pts pts 64 2013-05-04 13:15 /proc/13115/fd/3 -> socket:[19445454]
ただし、open("/proc/13115/fd/3", O_RDWR)
別のプロセスで実行するとエラーが返されます。対応するデバイスまたはアドレスがありません。。他の効率的な方法がありますか?一緒にいるかもしれない道?
ベストアンサー1
これは意図的に設計されています。ファイル記述子を他のプロセスと共有することは明示的です。デフォルトでは、ファイル記述子はプロセス自身のメモリと同じくらいプライベートです。
いつものように、権利があれば道このプロセス中に呼び出しを含め、必要なすべての操作を実行できますsendmsg
。伝統的に、呼び出しはptrace
SELinux、機能、刑務所などのセキュリティ制限で実行する必要があり、ptrace
制限がさらに厳しくなる可能性があります。たとえば、デフォルトのUbuntu設定では、非ルートプロセスはptrace
AppArmorを介して独自のサブプロセスのみを呼び出すことができます。
強く使用するのは少し面倒ですptrace
。正しいデータを注入し、何も上書きしていないことを確認し、自分で整理する必要があります。だから私が提案するのは、ロータリー方式でコードを挿入し、既存のツールを使用してコードをトリガーすることです。
コードを含む小さな共有ライブラリを作成しsendmsg
、LD_PRELOAD
他のプロセスで使用できるようにします。ここにいくつかあります未テストスケルトンコードの欠落エラーチェック。
int pts_gift_fd (char *path, int fd) {
int sock;
struct sockaddr_un addr = {0};
struct msghdr msg = {0};
struct iovec iov = {0};
addr.sun_family = AF_UNIX;
strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
/* Populate msg, iov as in the code you've already found */
sock = socket(AF_UNIX, SOCK_STREAM, 0);
connect(sock, (struct sockaddr*)&addr, sizeof(addr));
sendmsg(sock, &msg, 0);
close(sock);
}
その後、コードをトリガーするには、次のように実行してgdb -n -pid 13115 -batch -x /dev/stdin
入力popen
します(%d
インポートするfdはどこにあり、%s
以前に作成してリッスンしているUnixソケットのパスはどこにありますか?)。
call pts_gift_fd("%s", %d)
detach
quit