lwm2m: Check CoAP header offset #84550
Open
+128
−46
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There is a possibility where the Registration message is silently dropped when the header, as well as, the payload get too large. This primarily affects applications using long endpoint names and large messages or block transfer.
The LwM2M client has a Kconfig option
CONFIG_LWM2M_ENGINE_MESSAGE_HEADER_SIZE
to configure the maximum CoAP header length. The header length defaults to 48 bytes in a range from 24 to 128. For Registration messages, the header size is dynamic and specific to an application. The endpoint name max length configured withCONFIG_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH
defaults to 33 (32 characters and a zero termination byte). This may cause the header ending up larger than configured.When constructing a header for a LwM2M message, the final size is not checked. If the header is larger than the configured maximum size, it is writing into the area meant for the payload in the network packet buffer. In most cases this is not an issue, because the Registration message is rather small. However, if the Registration message would exceed the buffer reserved for the whole packet (determined by the block size), the packet can't be assembled (-ENOMEM). This prevents the packet to be sent, as well as using a block transfer for even larger messages. In addition, since the result of
async_message_send
is not checked, the Registration message would be silently dropped without warning or error to the user.The issue can be reproduced by extending the endpoint name and as a result increase the header size beyond the limit. The registration message is now lost, if the payload would be too larger that the space left in the buffer. Like when having a large number of objects registered with the client.
A Bootstrap message would also exceed the header boundary, but since it has no payload it would no be dropped that easily.
This change adds a boundary check for every constructed CoAP packet, in order to ensure the headers always stay withing the configured limit. A check is also introduced for the result of
async_message_send
to propagate and log an error. This prevents issues with future modifications to the header which might have effects on the size independent ofCONFIG_LWM2M_ENGINE_MESSAGE_HEADER_SIZE
.With the changes the output would look like this
clearly showing the issue. Same for Bootstrap