Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffer overrun while receiving 14 bytes payload (string value) using BAOSProtocol 1.2 #24

Open
timo-schlegel opened this issue Feb 8, 2024 · 2 comments

Comments

@timo-schlegel
Copy link

The kdrive framework runs into an buffer overrun, while receiving events with 14 bytes payload (string values) using BAOSProtocol 1.2 (KNX IP BAOS 770).

Log output:
19:15:51:911 [kdrive.baos.ProtocolDecoder] Rx : IndicationFunctions::DatapointValueIndication
F0 C1 A4 01 A4 0E 5A 77 61 6E 67 73
19:15:51:911 [kdrive.baos.StreamConnector12] Error in rxImpl, BAOS Client exception: Invalid Service
19:15:51:911 [kdrive.baos.BaosEvent] BAOS Client exception: Buffer overrun while decoding Datapoint Value (buffer)
19:15:51:911 [kdrive.connector.CallbackThread] Callback thread terminated by unhandled Poco exception [id 2]: BAOS Client exception: Invalid Service
19:15:51:911 [BaosEventListener] BAOS Connector disconnected

The exception occurs in kdrive/src/baos/protocols/Protocol12.cpp line 301:

ServerItem value;
value.id = *ptr++;
const unsigned char stateLength = *ptr++;
value.serviceData = (stateLength << 4) & 0xF0;
value.length = stateLength & 0x0F;

if (static_cast<std::size_t>((ptr + value.length) - begin) > bufferSize)
{
	throw ClientException("Buffer overrun while decoding Datapoint Value (buffer)");
}

Analysis 1:
static_caststd::size_t((ptr + value.length) - begin) returns 16
bufferSize returns 8

Analysis 2:
Received packet (from log output above):
F0 C1 A4 01 A4 0E 5A 77 61 6E 67 73
-> F0 C1 A4 01 A4 0E (received 1 DatapointValue.Ind with ID 164 and 14 bytes payload length)
-> 5A 77 61 6E 67 73 (followed by 6 bytes payload instead of 14 bytes)

Countercheck:
Received packet with KnxBAOS DemoClient for protocol 1.x:
F0 C1 A4 01 A4 0E 5A 77 61 6E 67 73 62 65 74 72 69 65 62 20
-> F0 C1 A4 01 A4 0E (received 1 DatapointValue.Ind with ID 164 and 14 bytes payload length)
-> 5A 77 61 6E 67 73 62 65 74 72 69 65 62 20 (followed by 14 bytes payload)

Conclusion:
The buffer size per received datapoint is set to 8 bytes, which is too small to receive a datapoint packet with 16 bytes (1 bytes for DP ID + 1 byte for DP state/length + 14 bytes payload). Therefore the datapoint packet is not fully received, as it does not fit in the buffer.

Question:
How can the buffer size be increased?

@weinzierl-engineering
Copy link
Owner

weinzierl-engineering commented Feb 12, 2024

After looking into it, I probably pinpointed the problem.
In the line

bufferIterator = rx(buffer, bufferSize, bufferIterator, buffer[bufferIterator - 1] & 0x07); in file kdrive/src/baos/stream/StreamConnector12.cpp the part

buffer[bufferIterator - 1] & 0x07

reads the length from the buffer.

Since 4 bits are the length (Baos protocol 1.1 Page 18 ) and the mask is wrongly set to 0x07 the highest bit is lost here. Changing it to 0x0F should fix the problem.

Please report back if this change is working for you or not.

@timo-schlegel
Copy link
Author

The proposed solution works.

Log output:
18:41:25:209 [kdrive.baos.ProtocolDecoder] Rx : IndicationFunctions::DatapointValueIndication
F0 C1 A8 01 A8 0E 5A 77 61 6E 67 73 62 65 74 72 69 65 62 20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants