cinemast / libjson-rpc-cpp

C++ framework for json-rpc (json remote procedure call)
MIT License
952 stars 316 forks source link

UNIX domain socket code corrupts memory on Mac #332

Open tyhik opened 7 months ago

tyhik commented 7 months ago

sun_path field of sockaddr_un is 108 bytes on linux, but 104 bytes on Mac. The below patch fixes strncpy() writing over the buffer end on Mac.

diff --git a/src/jsonrpccpp/client/connectors/unixdomainsocketclient.cpp b/src/jsonrpccpp/client/connectors/unixdomainsocketclient.cpp
index 5e97575..0b2bdfc 100644
--- a/src/jsonrpccpp/client/connectors/unixdomainsocketclient.cpp
+++ b/src/jsonrpccpp/client/connectors/unixdomainsocketclient.cpp
@@ -19,6 +19,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <unistd.h>
+#include <stddef.h>

 using namespace jsonrpc;
 using namespace std;
@@ -37,7 +38,7 @@ void UnixDomainSocketClient::SendRPCMessage(const std::string &message, std::str
   memset(&address, 0, sizeof(sockaddr_un));

   address.sun_family = AF_UNIX;
-  strncpy(address.sun_path, this->path.c_str(), 107);
+  strncpy(address.sun_path, this->path.c_str(), sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path) - 1);

   if (connect(socket_fd, (struct sockaddr *)&address, sizeof(sockaddr_un)) != 0) {
     close(socket_fd);
diff --git a/src/jsonrpccpp/server/connectors/unixdomainsocketserver.cpp b/src/jsonrpccpp/server/connectors/unixdomainsocketserver.cpp
index 9dc28f8..1eb83b8 100644
--- a/src/jsonrpccpp/server/connectors/unixdomainsocketserver.cpp
+++ b/src/jsonrpccpp/server/connectors/unixdomainsocketserver.cpp
@@ -18,6 +18,7 @@
 #include <sstream>
 #include <sys/types.h>
 #include <unistd.h>
+#include <stddef.h>

 using namespace jsonrpc;
 using namespace std;
@@ -46,7 +47,7 @@ bool UnixDomainSocketServer::InitializeListener() {

   memset(&(this->address), 0, sizeof(struct sockaddr_un));
   this->address.sun_family = AF_UNIX;
-  strncpy(this->address.sun_path, this->socket_path.c_str(), 107);
+  strncpy(this->address.sun_path, this->socket_path.c_str(), sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path) - 1);

   if (::bind(this->socket_fd, reinterpret_cast<struct sockaddr *>(&(this->address)), sizeof(struct sockaddr_un)) != 0) {
     return false;
tyhik commented 7 months ago

Sorry, didn't know that github Code tags corrupt the patch.

cinemast commented 6 months ago

could you please put that in a proper pullrequest?