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)
다른 프로세스에서 실행하면 오류가 반환됩니다.해당 장치 또는 주소가 없습니다.. 작동하는 다른 것이 있습니까? 아마도ptrace?
답변1
이는 의도적으로 설계된 것입니다. 파일 설명자를 다른 프로세스와 공유하는 것은 명시적입니다. 기본적으로 파일 설명자는 프로세스 자체 메모리만큼 비공개입니다.
평소와 같이, 귀하에게 다음과 같은 권리가 있다면ptrace이 과정에서 전화 걸기를 포함하여 원하는 모든 작업을 수행할 수 있습니다 sendmsg
. 전통적으로 전화를 걸려면 ptrace
동일한 사용자 ID로 실행해야 합니다. 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
답변2
관련 없는 프로세스의 메모리에 접근할 수 없는 것과 같은 이유로 이 작업을 수행할 수 없습니다.~이다다른 프로세스의 메모리 일부. 이와 같은 정보가 있는 유일한 이유 /proc
는 커널이 해당 정보를 제공하고 읽기 전용이기 때문입니다.사본프로세스 메모리).
파일과 관련된 경우에는 물론 파일에 액세스해 볼 수도 있습니다. 소켓인 경우 다음을 사용하여 스누핑할 수 있습니다.libpcap또는 그것에서 파생된 것.
기본적으로 상황은 다음과 같습니다. 파일 설명자는 (다시) 프로세스 메모리의 일부입니다. 설명자는 커널 공간에 존재하는 기본 버퍼를 가지고 있습니다. 프로세스가 설명자에서 읽거나 쓸 때 이 버퍼에 쓰고 있습니다. 데이터가 나가는 경우 커널은 버퍼를 하드웨어로 적절하게 플러시합니다. 들어오는 데이터의 경우 프로세스가 버퍼를 비울 때 하드웨어에서 버퍼를 다시 채웁니다. 이러한 버퍼는 AFAIK에서 다른 프로세스에 액세스할 수 없지만 일부 수단(예: libpcap)이 있습니다.독서proc 인터페이스가 프로세스의 사용자 공간 메모리에서 일부 데이터를 제공할 수 있는 것처럼 특정 커널 인터페이스에 의해 결정되는 어떤 형태의 데이터입니다.