Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.15.5
-
None
-
-
8eaa91e1edd7a2b5849a18487a08c440b2b7a27a (qt/qtserialbus/dev) a0d3bc6512aa9ef79f0a458102224018b5472cd7 (qt/qtserialbus/6.2)
Description
In file qtserialbus\src\plugins\canbus\systeccan\systeccanbackend.cpp
function void SystecCanBackendPrivate::startWrite() starts CAN frame transmission.
Here's the excerpt:
tCanMsgStruct message = {}; message.m_dwID = frame.frameId(); message.m_bDLC = quint8(payload.size()); <--- if (frame.frameType() == QCanBusFrame::RemoteRequestFrame) message.m_bFF |= USBCAN_MSG_FF_RTR; // remote request frame without payload else ::memcpy(message.m_bData, payload.constData(), sizeof(message.m_bData)); <---
So, message DLC field (frame data length) is computed from payload.size(), however memcpy always copies the same fixed number of bytes, calculated by sizeof(message.m_bData). This sizeof is 8.
frame - is QCanBusFrame, provided by user that wants to transmit a frame. frame.payload is QByteArray, also provided by user (via ctor or setPayload method).
Therefore, if user provides payload less than 8 bytes in size, buffer overflow occures; memcpy reads more bytes than payload array has.
Therefore if user wants to avoid buffer overflow, they need to create frames with payloads equal to 8 even if this is more than neccesary. That also affects frames DLC field which is not always acceptable.
Correct code should be something like ::memcpy(message.m_bData, payload.constData(), message.m_bDLC); and, possibly, do Q_ASSERT( message.m_bDLC <= sizeof(message.m_bData).