Title: [252855] trunk/Source/WTF
Revision
252855
Author
[email protected]
Date
2019-11-25 06:33:13 -0800 (Mon, 25 Nov 2019)

Log Message

REGRESSION(r252770): [GTK][WPE] Remote inspector no longer works if debugger is in a different kind of system
https://bugs.webkit.org/show_bug.cgi?id=204572

Reviewed by Žan Doberšek.

This patch adds the following changes:

 - Use uint32_t instead of size_t to store the body size in the message header, because size_t has a different
   size in 32 and 64 bit platforms.
 - Use htonl/ntohl to write/read the body size in the header.
 - Add a flags byte to the header to include the message byte order. The sender always uses the host byter order
   and the receiver does the byte swapping if needed.

* wtf/glib/SocketConnection.cpp:
(WTF::messageIsByteSwapped):
(WTF::SocketConnection::readMessage):
(WTF::SocketConnection::sendMessage):

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (252854 => 252855)


--- trunk/Source/WTF/ChangeLog	2019-11-25 13:03:24 UTC (rev 252854)
+++ trunk/Source/WTF/ChangeLog	2019-11-25 14:33:13 UTC (rev 252855)
@@ -1,6 +1,26 @@
 2019-11-25  Carlos Garcia Campos  <[email protected]>
 
-        REGRESSION(r252770): [GTK][WPE] Remove inspector broken in debug builds after r252770
+        REGRESSION(r252770): [GTK][WPE] Remote inspector no longer works if debugger is in a different kind of system
+        https://bugs.webkit.org/show_bug.cgi?id=204572
+
+        Reviewed by Žan Doberšek.
+
+        This patch adds the following changes:
+
+         - Use uint32_t instead of size_t to store the body size in the message header, because size_t has a different
+           size in 32 and 64 bit platforms.
+         - Use htonl/ntohl to write/read the body size in the header.
+         - Add a flags byte to the header to include the message byte order. The sender always uses the host byter order
+           and the receiver does the byte swapping if needed.
+
+        * wtf/glib/SocketConnection.cpp:
+        (WTF::messageIsByteSwapped):
+        (WTF::SocketConnection::readMessage):
+        (WTF::SocketConnection::sendMessage):
+
+2019-11-25  Carlos Garcia Campos  <[email protected]>
+
+        REGRESSION(r252770): [GTK][WPE] Remote inspector broken in debug builds after r252770
         https://bugs.webkit.org/show_bug.cgi?id=204569
 
         Reviewed by Žan Doberšek.

Modified: trunk/Source/WTF/wtf/glib/SocketConnection.cpp (252854 => 252855)


--- trunk/Source/WTF/wtf/glib/SocketConnection.cpp	2019-11-25 13:03:24 UTC (rev 252854)
+++ trunk/Source/WTF/wtf/glib/SocketConnection.cpp	2019-11-25 14:33:13 UTC (rev 252855)
@@ -22,6 +22,8 @@
 
 #include <cstring>
 #include <gio/gio.h>
+#include <wtf/ByteOrder.h>
+#include <wtf/CheckedArithmetic.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/RunLoop.h>
 
@@ -93,21 +95,41 @@
     return G_SOURCE_CONTINUE;
 }
 
+enum {
+    ByteOrderLittleEndian = 1 << 0
+};
+typedef uint8_t MessageFlags;
+
+static inline bool messageIsByteSwapped(MessageFlags flags)
+{
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    return !(flags & ByteOrderLittleEndian);
+#else
+    return (flags & ByteOrderLittleEndian);
+#endif
+}
+
 bool SocketConnection::readMessage()
 {
-    if (m_readBuffer.size() < sizeof(size_t))
+    if (m_readBuffer.size() < sizeof(uint32_t))
         return false;
 
     auto* messageData = m_readBuffer.data();
-    size_t bodySize;
-    memcpy(&bodySize, messageData, sizeof(size_t));
-    messageData += sizeof(size_t);
-    auto messageSize = sizeof(size_t) + bodySize;
-    if (m_readBuffer.size() < messageSize)
+    uint32_t bodySizeHeader;
+    memcpy(&bodySizeHeader, messageData, sizeof(uint32_t));
+    messageData += sizeof(uint32_t);
+    bodySizeHeader = ntohl(bodySizeHeader);
+    Checked<size_t> bodySize = bodySizeHeader;
+    MessageFlags flags;
+    memcpy(&flags, messageData, sizeof(MessageFlags));
+    messageData += sizeof(MessageFlags);
+    auto messageSize = sizeof(uint32_t) + sizeof(MessageFlags) + bodySize;
+    if (m_readBuffer.size() < messageSize.unsafeGet())
         return false;
 
-    auto messageNameLength = strlen(messageData) + 1;
-    if (m_readBuffer.size() < messageNameLength) {
+    Checked<size_t> messageNameLength = strlen(messageData);
+    messageNameLength++;
+    if (m_readBuffer.size() < messageNameLength.unsafeGet()) {
         ASSERT_NOT_REACHED();
         return false;
     }
@@ -114,24 +136,27 @@
 
     const auto it = m_messageHandlers.find(messageData);
     if (it != m_messageHandlers.end()) {
-        messageData += messageNameLength;
+        messageData += messageNameLength.unsafeGet();
         GRefPtr<GVariant> parameters;
         if (!it->value.first.isNull()) {
             GUniquePtr<GVariantType> variantType(g_variant_type_new(it->value.first.data()));
+            size_t parametersSize = bodySize.unsafeGet() - messageNameLength.unsafeGet();
             // g_variant_new_from_data() requires the memory to be properly aligned for the type being loaded,
             // but it's not possible to know the alignment because g_variant_type_info_query() is not public API.
             // Since GLib 2.60 g_variant_new_from_data() already checks the alignment and reallocates the buffer
             // in aligned memory only if needed. For older versions we can simply ensure the memory is 8 aligned.
 #if GLIB_CHECK_VERSION(2, 60, 0)
-            parameters = g_variant_new_from_data(variantType.get(), messageData, bodySize - messageNameLength, FALSE, nullptr, nullptr);
+            parameters = g_variant_new_from_data(variantType.get(), messageData, parametersSize, FALSE, nullptr, nullptr);
 #else
-            auto* alignedMemory = fastAlignedMalloc(8, bodySize - messageNameLength);
-            memcpy(alignedMemory, messageData, bodySize - messageNameLength);
-            GRefPtr<GBytes> bytes = g_bytes_new_with_free_func(alignedMemory, bodySize - messageNameLength, [](gpointer data) {
+            auto* alignedMemory = fastAlignedMalloc(8, parametersSize);
+            memcpy(alignedMemory, messageData, parametersSize);
+            GRefPtr<GBytes> bytes = g_bytes_new_with_free_func(alignedMemory, parametersSize, [](gpointer data) {
                 fastAlignedFree(data);
             }, alignedMemory);
             parameters = g_variant_new_from_bytes(variantType.get(), bytes.get(), FALSE);
 #endif
+            if (messageIsByteSwapped(flags))
+                parameters = adoptGRef(g_variant_byteswap(parameters.get()));
         }
         it->value.second(*this, parameters.get(), m_userData);
         if (isClosed())
@@ -138,9 +163,9 @@
             return false;
     }
 
-    if (m_readBuffer.size() > messageSize) {
-        std::memmove(m_readBuffer.data(), m_readBuffer.data() + messageSize, m_readBuffer.size() - messageSize);
-        m_readBuffer.shrink(m_readBuffer.size() - messageSize);
+    if (m_readBuffer.size() > messageSize.unsafeGet()) {
+        std::memmove(m_readBuffer.data(), m_readBuffer.data() + messageSize.unsafeGet(), m_readBuffer.size() - messageSize.unsafeGet());
+        m_readBuffer.shrink(m_readBuffer.size() - messageSize.unsafeGet());
     } else
         m_readBuffer.shrink(0);
 
@@ -154,16 +179,32 @@
 {
     GRefPtr<GVariant> adoptedParameters = parameters;
     size_t parametersSize = parameters ? g_variant_get_size(parameters) : 0;
-    auto messageNameLength = strlen(messageName) + 1;
-    size_t bodySize = messageNameLength + parametersSize;
+    Checked<size_t, RecordOverflow> messageNameLength = strlen(messageName);
+    messageNameLength++;
+    if (UNLIKELY(messageNameLength.hasOverflowed())) {
+        g_warning("Trying to send message with invalid too long name");
+        return;
+    }
+    Checked<uint32_t, RecordOverflow> bodySize = messageNameLength + parametersSize;
+    if (UNLIKELY(bodySize.hasOverflowed())) {
+        g_warning("Trying to send message '%s' with invalid too long body", messageName);
+        return;
+    }
     size_t previousBufferSize = m_writeBuffer.size();
-    m_writeBuffer.grow(previousBufferSize + sizeof(size_t) + bodySize);
+    m_writeBuffer.grow(previousBufferSize + sizeof(uint32_t) + sizeof(MessageFlags) + bodySize.unsafeGet());
 
     auto* messageData = m_writeBuffer.data() + previousBufferSize;
-    memcpy(messageData, &bodySize, sizeof(size_t));
-    messageData += sizeof(size_t);
-    memcpy(messageData, messageName, messageNameLength);
-    messageData += messageNameLength;
+    uint32_t bodySizeHeader = htonl(bodySize.unsafeGet());
+    memcpy(messageData, &bodySizeHeader, sizeof(uint32_t));
+    messageData += sizeof(uint32_t);
+    MessageFlags flags = 0;
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    flags |= ByteOrderLittleEndian;
+#endif
+    memcpy(messageData, &flags, sizeof(MessageFlags));
+    messageData += sizeof(MessageFlags);
+    memcpy(messageData, messageName, messageNameLength.unsafeGet());
+    messageData += messageNameLength.unsafeGet();
     if (parameters)
         memcpy(messageData, g_variant_get_data(parameters), parametersSize);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to