Browse Source

[3918] UNIX socket path length is now checked.

Tomek Mrugalski 10 years ago
parent
commit
7c64a2b924

+ 12 - 3
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc

@@ -71,8 +71,16 @@ public:
             return (false);
             return (false);
         }
         }
 
 
-        // Prepare socket address
         struct sockaddr_un srv_addr;
         struct sockaddr_un srv_addr;
+        if (socket_path.size() > sizeof(srv_addr.sun_path) - 1) {
+            ADD_FAILURE() << "Socket path specified (" << socket_path
+                          << ") is larger than " << (sizeof(srv_addr.sun_path) - 1)
+                          << " allowed.";
+            disconnectFromServer();
+            return (false);
+        }
+
+        // Prepare socket address
         memset(&srv_addr, 0, sizeof(srv_addr));
         memset(&srv_addr, 0, sizeof(srv_addr));
         srv_addr.sun_family = AF_UNIX;
         srv_addr.sun_family = AF_UNIX;
         strncpy(srv_addr.sun_path, socket_path.c_str(),
         strncpy(srv_addr.sun_path, socket_path.c_str(),
@@ -267,8 +275,9 @@ public:
         ASSERT_TRUE(answer);
         ASSERT_TRUE(answer);
 
 
         int status = 0;
         int status = 0;
-        isc::config::parseAnswer(status, answer);
-        ASSERT_EQ(0, status);
+        ConstElementPtr txt = isc::config::parseAnswer(status, answer);
+        // This should succeed. If not, print the error message.
+        ASSERT_EQ(0, status) << txt->str();
 
 
         // Now check that the socket was indeed open.
         // Now check that the socket was indeed open.
         ASSERT_GT(isc::config::CommandMgr::instance().getControlSocketFD(), -1);
         ASSERT_GT(isc::config::CommandMgr::instance().getControlSocketFD(), -1);

+ 11 - 2
src/lib/config/command_socket_factory.cc

@@ -63,6 +63,16 @@ private:
     /// @return socket file descriptor
     /// @return socket file descriptor
     int createUnixSocket(const std::string& file_name) {
     int createUnixSocket(const std::string& file_name) {
 
 
+        struct sockaddr_un addr;
+
+        // string.size() returns number of bytes (without trailing zero)
+        // we need 1 extra byte for terminating 0.
+        if (file_name.size() > sizeof(addr.sun_path) - 1) {
+            isc_throw(SocketError, "Failed to open socket: path specified ("
+                      << file_name << ") is longer than allowed "
+                      << (sizeof(addr.sun_path) - 1) << " bytes.");
+        }
+
         int fd = socket(AF_UNIX, SOCK_STREAM, 0);
         int fd = socket(AF_UNIX, SOCK_STREAM, 0);
         if (fd == -1) {
         if (fd == -1) {
             isc_throw(isc::config::SocketError, "Failed to create AF_UNIX socket:"
             isc_throw(isc::config::SocketError, "Failed to create AF_UNIX socket:"
@@ -83,10 +93,9 @@ private:
         }
         }
 
 
         // Now bind the socket to the specified path.
         // Now bind the socket to the specified path.
-        struct sockaddr_un addr;
         memset(&addr, 0, sizeof(addr));
         memset(&addr, 0, sizeof(addr));
         addr.sun_family = AF_UNIX;
         addr.sun_family = AF_UNIX;
-        strncpy(addr.sun_path, file_name.c_str(), sizeof(addr.sun_path)-1);
+        strncpy(addr.sun_path, file_name.c_str(), sizeof(addr.sun_path) - 1);
         if (bind(fd, (struct sockaddr*)&addr, sizeof(addr))) {
         if (bind(fd, (struct sockaddr*)&addr, sizeof(addr))) {
             const char* errmsg = strerror(errno);
             const char* errmsg = strerror(errno);
             ::close(fd);
             ::close(fd);