Browse Source

[1452] impose upper limit on the data length for SocketSessionForwarder::push,
too.

JINMEI Tatuya 13 years ago
parent
commit
4d5f96b4d0
2 changed files with 15 additions and 2 deletions
  1. 8 2
      src/lib/util/io/socketsession.cc
  2. 7 0
      src/lib/util/tests/socketsession_unittest.cc

+ 8 - 2
src/lib/util/io/socketsession.cc

@@ -179,6 +179,10 @@ SocketSessionForwarder::push(int sock, int family, int sock_type, int protocol,
         isc_throw(SocketSessionError,
         isc_throw(SocketSessionError,
                   "Data for a socket session must not be empty");
                   "Data for a socket session must not be empty");
     }
     }
+    if (data_len > MAX_DATASIZE) {
+        isc_throw(SocketSessionError, "Invalid socket session data size: " <<
+                  data_len << ", must not exceed " << MAX_DATASIZE);
+    }
 
 
     if (send_fd(impl_->fd_, sock) != 0) {
     if (send_fd(impl_->fd_, sock) != 0) {
         isc_throw(SocketSessionError, "FD passing failed: " <<
         isc_throw(SocketSessionError, "FD passing failed: " <<
@@ -198,8 +202,10 @@ SocketSessionForwarder::push(int sock, int family, int sock_type, int protocol,
     // Remote endpoint
     // Remote endpoint
     impl_->buf_.writeUint32(static_cast<uint32_t>(getSALength(remote_end)));
     impl_->buf_.writeUint32(static_cast<uint32_t>(getSALength(remote_end)));
     impl_->buf_.writeData(&remote_end, getSALength(remote_end));
     impl_->buf_.writeData(&remote_end, getSALength(remote_end));
-    // Data length
-    impl_->buf_.writeUint32(static_cast<uint32_t>(data_len));
+    // Data length.  Must be fit uint32 due to the range check above.
+    const uint32_t data_len32 = static_cast<uint32_t>(data_len);
+    assert(data_len == data_len32); // shouldn't cause overflow.
+    impl_->buf_.writeUint32(data_len32);
     // Write the resulting header length at the beginning of the buffer
     // Write the resulting header length at the beginning of the buffer
     impl_->buf_.writeUint16At(impl_->buf_.getLength() - sizeof(uint16_t), 0);
     impl_->buf_.writeUint16At(impl_->buf_.getLength() - sizeof(uint16_t), 0);
 
 

+ 7 - 0
src/lib/util/tests/socketsession_unittest.cc

@@ -626,6 +626,13 @@ TEST_F(ForwarderTest, badPush) {
                                  NULL, sizeof(TEST_DATA)),
                                  NULL, sizeof(TEST_DATA)),
                  SocketSessionError);
                  SocketSessionError);
 
 
+    // Too big data: we reject them at least for now
+    EXPECT_THROW(forwarder_.push(1, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
+                                 *getSockAddr("192.0.2.1", "53").first,
+                                 *getSockAddr("192.0.2.2", "53").first,
+                                 string(65536, 'd').c_str(), 65536),
+                 SocketSessionError);
+
     // Close the receptor before push.  It will result in SIGPIPE (should be
     // Close the receptor before push.  It will result in SIGPIPE (should be
     // ignored) and EPIPE, which will be converted to SocketSessionError.
     // ignored) and EPIPE, which will be converted to SocketSessionError.
     const int receptor_fd = acceptForwarder();
     const int receptor_fd = acceptForwarder();