I'm building a POC Android app that needs to communicate with an ELF binary over a Unix domain socket server that the binary binds to and listens on. The app is meant for rooted phones and executes the binary as a superuser upon launch. I need to connect with the binary from my client residing in native code, which I'm presently failing to do.
I'm using a self-ported, stripped down version of libsocket to implement the domain socket functionality for both the binary and the Android app (through JNI). The binary communicates perfectly with a command line client, however, it fails to connect with the client that I've implemented in JNI code. I've made sure that the binary is running from /data/data/<my_package_name>/files
and that the server socket has public access (777).
While researching the above problem, I stumbled across the fact that NDK requires LocalSockets to be in the Linux abstract namespace. My server (arm binary) binds to an absolute path (/data/data/<my_package_name>/files/serversocket
) as libsocket does not support the abstract namespace for unix domain sockets (due to the usage of strlen()
and strncopy()
which do not support strings beginning with \0
).
The following is the code for create_socket from libsocket that's failing with a negative fd.
int create_socket(const char* path, int flags) {
if (path == NULL) {
return -1;
}
if (strlen(path) > sizeof(((struct sockaddr_un*) 0)->sun_path) - 1) {
return -1;
}
int fd = socket(AF_LOCAL, SOCK_STREAM | flags, 0);
if (fd < 0) {
return -1;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_LOCAL;
strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
// the connect call below fails, errno is set to 13 (EACCESS)
if (connect(fd, (struct sockaddr*) &addr, sizeof(addr.sun_family) + strlen(addr.sun_path))) {
close(fd);
return -1;
}
return fd;
}
EDIT : In the above code, the call to connect() fails, with errno being set to 13 (EACCESS). This seems to be an insufficient privileges problem.
I'm wondering if there's any way for me to connect my client to an absolute path from within NDK. It works just fine when I package the client in an ELF executable that runs as superuser, am I missing something obvious here?