Fix MakeAddress for Unix domain sockets.
Only copy up to the length of the socket name and also return the length
for later use in bind() and connect().
Bug: 62392415
Test: Boots and can connect to metadata_proxy from Android side
Change-Id: I1fcd8ae67d99efcf3d589db2c8f30aa3c42bd894
diff --git a/common/libs/fs/shared_fd.cpp b/common/libs/fs/shared_fd.cpp
index c75e7fb..8028bd0 100644
--- a/common/libs/fs/shared_fd.cpp
+++ b/common/libs/fs/shared_fd.cpp
@@ -17,6 +17,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <cstddef>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
@@ -163,16 +164,30 @@
}
static void MakeAddress(
- const char* name, bool abstract, struct sockaddr_un* dest) {
+ const char* name, bool abstract, struct sockaddr_un* dest,
+ socklen_t* len) {
memset(dest, 0, sizeof(*dest));
dest->sun_family = AF_UNIX;
// sun_path is NOT expected to be nul-terminated.
// See man 7 unix.
+ size_t namelen;
if (abstract) {
- strncpy(dest->sun_path + 1, name, sizeof(dest->sun_path) - 1);
+ // ANDROID_SOCKET_NAMESPACE_ABSTRACT
+ namelen = strlen(name);
+ CHECK_LE(namelen, sizeof(dest->sun_path) - 1)
+ << "MakeAddress failed. Name=" << name << " is longer than allowed.";
+ dest->sun_path[0] = 0;
+ memcpy(dest->sun_path + 1, name, namelen);
} else {
- strncpy(dest->sun_path, name, sizeof(dest->sun_path));
+ // ANDROID_SOCKET_NAMESPACE_RESERVED
+ // ANDROID_SOCKET_NAMESPACE_FILESYSTEM
+ // TODO(pinghao): Distinguish between them?
+ namelen = strlen(name);
+ CHECK_LE(namelen, sizeof(dest->sun_path))
+ << "MakeAddress failed. Name=" << name << " is longer than allowed.";
+ strncpy(dest->sun_path, name, strlen(name));
}
+ *len = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
}
SharedFD SharedFD::SocketSeqPacketServer(const char* name, mode_t mode) {
@@ -280,12 +295,13 @@
SharedFD SharedFD::SocketLocalClient(
const char* name, bool abstract, int in_type) {
struct sockaddr_un addr;
- MakeAddress(name, abstract, &addr);
+ socklen_t addrlen;
+ MakeAddress(name, abstract, &addr, &addrlen);
SharedFD rval = SharedFD::Socket(PF_UNIX, in_type, 0);
if (!rval->IsOpen()) {
return rval;
}
- if (rval->Connect((struct sockaddr *) &addr, sizeof(addr)) == -1) {
+ if (rval->Connect((struct sockaddr *) &addr, addrlen) == -1) {
LOG(ERROR) << "Connect failed; name=" << name << ": " << rval->StrError();
return SharedFD(std::shared_ptr<FileInstance>(
new FileInstance(-1, rval->GetErrno())));
@@ -300,7 +316,8 @@
if (!abstract) (void)unlink(name);
struct sockaddr_un addr;
- MakeAddress(name, abstract, &addr);
+ socklen_t addrlen;
+ MakeAddress(name, abstract, &addr, &addrlen);
SharedFD rval = SharedFD::Socket(PF_UNIX, in_type, 0);
if (!rval->IsOpen()) {
return rval;
@@ -312,7 +329,7 @@
return SharedFD(std::shared_ptr<FileInstance>(
new FileInstance(-1, rval->GetErrno())));
}
- if (rval->Bind((struct sockaddr *) &addr, sizeof(addr)) == -1) {
+ if (rval->Bind((struct sockaddr *) &addr, addrlen) == -1) {
LOG(ERROR) << "Bind failed; name=" << name << ": " << rval->StrError();
return SharedFD(std::shared_ptr<FileInstance>(
new FileInstance(-1, rval->GetErrno())));