Hello CycloneTCP maintainers,
I would like to report a current-head bug in mqttClientSetWillMessage().
Project: CycloneTCP
Affected file: mqtt/mqtt_client.c
Affected function: mqttClientSetWillMessage()
Tested current code: tested on the then-current master branch as of 2026-03-07
The issue is a validation/copy mismatch in the handling of the Will payload.
At current head, the API accepts the payload as const void *, so binary data is allowed by the interface. However, the validation still uses strlen()-style logic, while the actual copy uses the caller-provided length argument.
This means a payload containing an early NUL byte can pass the length check while the function still copies the full raw length into the fixed-size destination buffer.
Why I believe this is a real bug:
the API accepts const void *, not a text string
strlen()-style validation does not make sense for arbitrary binary MQTT payloads
the checked length is not the same length that is actually copied
A simple example is:
payload starts with 0x41 0x00 ...
actual length = 64
In that case, the string-length validation can see only length 1, but the copy still uses the full length value.
My current local proof results are:
strlen((char*)payload) = 1
actual_length = 64
payload_field_size = 16
return_code = 0
recorded_length = 64
The proof also shows the copy escaping the 16-byte payload field and corrupting following fields/object tail.
Suggested fix:
validate against the caller-provided length, not strlen()
reject length > MQTT_CLIENT_MAX_WILL_PAYLOAD_LEN
keep the copy logic keyed to length
I can provide a minimal reproducer, proof notes, or a patch if helpful.
Best regards,
Pengpeng Hou
pengpeng@iscas.ac.cn
Hello CycloneTCP maintainers,
I would like to report a current-head bug in mqttClientSetWillMessage().
Project: CycloneTCP
Affected file: mqtt/mqtt_client.c
Affected function: mqttClientSetWillMessage()
Tested current code: tested on the then-current master branch as of 2026-03-07
The issue is a validation/copy mismatch in the handling of the Will payload.
At current head, the API accepts the payload as const void *, so binary data is allowed by the interface. However, the validation still uses strlen()-style logic, while the actual copy uses the caller-provided length argument.
This means a payload containing an early NUL byte can pass the length check while the function still copies the full raw length into the fixed-size destination buffer.
Why I believe this is a real bug:
the API accepts const void *, not a text string
strlen()-style validation does not make sense for arbitrary binary MQTT payloads
the checked length is not the same length that is actually copied
A simple example is:
payload starts with 0x41 0x00 ...
actual length = 64
In that case, the string-length validation can see only length 1, but the copy still uses the full length value.
My current local proof results are:
strlen((char*)payload) = 1
actual_length = 64
payload_field_size = 16
return_code = 0
recorded_length = 64
The proof also shows the copy escaping the 16-byte payload field and corrupting following fields/object tail.
Suggested fix:
validate against the caller-provided length, not strlen()
reject length > MQTT_CLIENT_MAX_WILL_PAYLOAD_LEN
keep the copy logic keyed to length
I can provide a minimal reproducer, proof notes, or a patch if helpful.
Best regards,
Pengpeng Hou
pengpeng@iscas.ac.cn