由於控制套接字的位置似乎沒有「官方」方式,所以你可以寫下你自己的共享對象,然後在「connect()
」上重寫任何「共享對象」 AF_FILE
地址在/ tmp目錄:
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <assert.h>
#include <linux/un.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen)
{
static int (*real_connect)(int, const struct sockaddr *, socklen_t) = NULL;
if (!real_connect)
real_connect = dlsym(RTLD_NEXT, "connect");
if (addr->sa_family == AF_FILE) {
// mutate sockaddr
assert(addrlen >= sizeof(struct sockaddr_un));
const struct sockaddr_un u = { AF_UNIX, "/foo/bar/path" };
// but only if it is in /tmp
if (!strncmp(((const struct sockaddr_un*)addr)->sun_path, "/tmp", 4)) {
return real_connect(sockfd, (const struct sockaddr*)&u, sizeof u);
}
}
return real_connect(sockfd, addr, addrlen);
}
編譯:
gcc -Wall -Wextra test.c -ldl -shared -o interpose.so -fPIC
然後爲運行:
LD_PRELOAD=./interpose.so soffice -headless -invisible -nocrashreport -nodefault -nologo -nofirststartwizard -norestore -conversionmode -accept='pipe,name=marcin_OOffice;urp;StarOffice.ComponentContext'
這似乎從閱讀strace輸出(但我不知道如何實際運行插座來證明它真的有效)工作。
謝謝,這很迂迴。我無法弄清楚這是對還是錯,但這絕對是我的問題的答案。不過,我會延遲接受/賞金,直到期限結束。 – Marcin
那麼這種方法是否有明顯的缺點? – Marcin
這有點脆弱 - 如果有其他調用以相同方式連接(包括子進程),那麼它可能有點意外。由於它不是受支持的接口,因此在任何升級時都有可能中斷。 – Flexo