Changeset 252855 in webkit


Ignore:
Timestamp:
Nov 25, 2019 6:33:13 AM (4 years ago)
Author:
Carlos Garcia Campos
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):

Location:
trunk/Source/WTF
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r252853 r252855  
    112019-11-25  Carlos Garcia Campos  <cgarcia@igalia.com>
    22
    3         REGRESSION(r252770): [GTK][WPE] Remove inspector broken in debug builds after r252770
     3        REGRESSION(r252770): [GTK][WPE] Remote inspector no longer works if debugger is in a different kind of system
     4        https://bugs.webkit.org/show_bug.cgi?id=204572
     5
     6        Reviewed by Žan Doberšek.
     7
     8        This patch adds the following changes:
     9
     10         - Use uint32_t instead of size_t to store the body size in the message header, because size_t has a different
     11           size in 32 and 64 bit platforms.
     12         - Use htonl/ntohl to write/read the body size in the header.
     13         - Add a flags byte to the header to include the message byte order. The sender always uses the host byter order
     14           and the receiver does the byte swapping if needed.
     15
     16        * wtf/glib/SocketConnection.cpp:
     17        (WTF::messageIsByteSwapped):
     18        (WTF::SocketConnection::readMessage):
     19        (WTF::SocketConnection::sendMessage):
     20
     212019-11-25  Carlos Garcia Campos  <cgarcia@igalia.com>
     22
     23        REGRESSION(r252770): [GTK][WPE] Remote inspector broken in debug builds after r252770
    424        https://bugs.webkit.org/show_bug.cgi?id=204569
    525
  • trunk/Source/WTF/wtf/glib/SocketConnection.cpp

    r252853 r252855  
    2323#include <cstring>
    2424#include <gio/gio.h>
     25#include <wtf/ByteOrder.h>
     26#include <wtf/CheckedArithmetic.h>
    2527#include <wtf/FastMalloc.h>
    2628#include <wtf/RunLoop.h>
     
    9496}
    9597
     98enum {
     99    ByteOrderLittleEndian = 1 << 0
     100};
     101typedef uint8_t MessageFlags;
     102
     103static inline bool messageIsByteSwapped(MessageFlags flags)
     104{
     105#if G_BYTE_ORDER == G_LITTLE_ENDIAN
     106    return !(flags & ByteOrderLittleEndian);
     107#else
     108    return (flags & ByteOrderLittleEndian);
     109#endif
     110}
     111
    96112bool SocketConnection::readMessage()
    97113{
    98     if (m_readBuffer.size() < sizeof(size_t))
     114    if (m_readBuffer.size() < sizeof(uint32_t))
    99115        return false;
    100116
    101117    auto* messageData = m_readBuffer.data();
    102     size_t bodySize;
    103     memcpy(&bodySize, messageData, sizeof(size_t));
    104     messageData += sizeof(size_t);
    105     auto messageSize = sizeof(size_t) + bodySize;
    106     if (m_readBuffer.size() < messageSize)
     118    uint32_t bodySizeHeader;
     119    memcpy(&bodySizeHeader, messageData, sizeof(uint32_t));
     120    messageData += sizeof(uint32_t);
     121    bodySizeHeader = ntohl(bodySizeHeader);
     122    Checked<size_t> bodySize = bodySizeHeader;
     123    MessageFlags flags;
     124    memcpy(&flags, messageData, sizeof(MessageFlags));
     125    messageData += sizeof(MessageFlags);
     126    auto messageSize = sizeof(uint32_t) + sizeof(MessageFlags) + bodySize;
     127    if (m_readBuffer.size() < messageSize.unsafeGet())
    107128        return false;
    108129
    109     auto messageNameLength = strlen(messageData) + 1;
    110     if (m_readBuffer.size() < messageNameLength) {
     130    Checked<size_t> messageNameLength = strlen(messageData);
     131    messageNameLength++;
     132    if (m_readBuffer.size() < messageNameLength.unsafeGet()) {
    111133        ASSERT_NOT_REACHED();
    112134        return false;
     
    115137    const auto it = m_messageHandlers.find(messageData);
    116138    if (it != m_messageHandlers.end()) {
    117         messageData += messageNameLength;
     139        messageData += messageNameLength.unsafeGet();
    118140        GRefPtr<GVariant> parameters;
    119141        if (!it->value.first.isNull()) {
    120142            GUniquePtr<GVariantType> variantType(g_variant_type_new(it->value.first.data()));
     143            size_t parametersSize = bodySize.unsafeGet() - messageNameLength.unsafeGet();
    121144            // g_variant_new_from_data() requires the memory to be properly aligned for the type being loaded,
    122145            // but it's not possible to know the alignment because g_variant_type_info_query() is not public API.
     
    124147            // in aligned memory only if needed. For older versions we can simply ensure the memory is 8 aligned.
    125148#if GLIB_CHECK_VERSION(2, 60, 0)
    126             parameters = g_variant_new_from_data(variantType.get(), messageData, bodySize - messageNameLength, FALSE, nullptr, nullptr);
     149            parameters = g_variant_new_from_data(variantType.get(), messageData, parametersSize, FALSE, nullptr, nullptr);
    127150#else
    128             auto* alignedMemory = fastAlignedMalloc(8, bodySize - messageNameLength);
    129             memcpy(alignedMemory, messageData, bodySize - messageNameLength);
    130             GRefPtr<GBytes> bytes = g_bytes_new_with_free_func(alignedMemory, bodySize - messageNameLength, [](gpointer data) {
     151            auto* alignedMemory = fastAlignedMalloc(8, parametersSize);
     152            memcpy(alignedMemory, messageData, parametersSize);
     153            GRefPtr<GBytes> bytes = g_bytes_new_with_free_func(alignedMemory, parametersSize, [](gpointer data) {
    131154                fastAlignedFree(data);
    132155            }, alignedMemory);
    133156            parameters = g_variant_new_from_bytes(variantType.get(), bytes.get(), FALSE);
    134157#endif
     158            if (messageIsByteSwapped(flags))
     159                parameters = adoptGRef(g_variant_byteswap(parameters.get()));
    135160        }
    136161        it->value.second(*this, parameters.get(), m_userData);
     
    139164    }
    140165
    141     if (m_readBuffer.size() > messageSize) {
    142         std::memmove(m_readBuffer.data(), m_readBuffer.data() + messageSize, m_readBuffer.size() - messageSize);
    143         m_readBuffer.shrink(m_readBuffer.size() - messageSize);
     166    if (m_readBuffer.size() > messageSize.unsafeGet()) {
     167        std::memmove(m_readBuffer.data(), m_readBuffer.data() + messageSize.unsafeGet(), m_readBuffer.size() - messageSize.unsafeGet());
     168        m_readBuffer.shrink(m_readBuffer.size() - messageSize.unsafeGet());
    144169    } else
    145170        m_readBuffer.shrink(0);
     
    155180    GRefPtr<GVariant> adoptedParameters = parameters;
    156181    size_t parametersSize = parameters ? g_variant_get_size(parameters) : 0;
    157     auto messageNameLength = strlen(messageName) + 1;
    158     size_t bodySize = messageNameLength + parametersSize;
     182    Checked<size_t, RecordOverflow> messageNameLength = strlen(messageName);
     183    messageNameLength++;
     184    if (UNLIKELY(messageNameLength.hasOverflowed())) {
     185        g_warning("Trying to send message with invalid too long name");
     186        return;
     187    }
     188    Checked<uint32_t, RecordOverflow> bodySize = messageNameLength + parametersSize;
     189    if (UNLIKELY(bodySize.hasOverflowed())) {
     190        g_warning("Trying to send message '%s' with invalid too long body", messageName);
     191        return;
     192    }
    159193    size_t previousBufferSize = m_writeBuffer.size();
    160     m_writeBuffer.grow(previousBufferSize + sizeof(size_t) + bodySize);
     194    m_writeBuffer.grow(previousBufferSize + sizeof(uint32_t) + sizeof(MessageFlags) + bodySize.unsafeGet());
    161195
    162196    auto* messageData = m_writeBuffer.data() + previousBufferSize;
    163     memcpy(messageData, &bodySize, sizeof(size_t));
    164     messageData += sizeof(size_t);
    165     memcpy(messageData, messageName, messageNameLength);
    166     messageData += messageNameLength;
     197    uint32_t bodySizeHeader = htonl(bodySize.unsafeGet());
     198    memcpy(messageData, &bodySizeHeader, sizeof(uint32_t));
     199    messageData += sizeof(uint32_t);
     200    MessageFlags flags = 0;
     201#if G_BYTE_ORDER == G_LITTLE_ENDIAN
     202    flags |= ByteOrderLittleEndian;
     203#endif
     204    memcpy(messageData, &flags, sizeof(MessageFlags));
     205    messageData += sizeof(MessageFlags);
     206    memcpy(messageData, messageName, messageNameLength.unsafeGet());
     207    messageData += messageNameLength.unsafeGet();
    167208    if (parameters)
    168209        memcpy(messageData, g_variant_get_data(parameters), parametersSize);
Note: See TracChangeset for help on using the changeset viewer.