Skip to content

mqttClientSetWillMessage validates binary payload with strlen() but copies the raw length #30

@neosys007

Description

@neosys007

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions