Skip to content

Conversation

rlubos
Copy link
Contributor

@rlubos rlubos commented Jun 27, 2025

For details, please check individual commits.

Check if value pointer is not NULL before passing it to memcmp() inside
lwm2m_engine_set(). As the function actually expects that the value
pointer can be NULL in case resource value is cleared (there is a test
case for such behavior), validate that len value is actually 0 if NULL
value is provided, to avoid unexpected behavior in other parts of the
function.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
SeppoTakalo
SeppoTakalo previously approved these changes Jul 1, 2025
Copy link
Contributor

@SeppoTakalo SeppoTakalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good otherwise than I think the int64_t conversion on JSON might still roll-over.

Comment on lines 667 to 670
temp = temp * 10ULL + (c - '0');
if (temp > (INT64_MAX + (neg ? 1ULL : 0ULL))) {
return -EINVAL;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
temp = temp * 10ULL + (c - '0');
if (temp > (INT64_MAX + (neg ? 1ULL : 0ULL))) {
return -EINVAL;
}
if (temp > (INT64_MAX/10)) {
return -EINVAL;
}
temp = temp * 10ULL + (c - '0');

I think the temp might roll-over before the if-check, so maybe it needs to be checked beforehand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I've updated the check for json and plain_text.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the second though, the original proposal was fine, the roll-over is not a concern as we update uint64_t variable and then compare against int64_t limits.

jukkar
jukkar previously approved these changes Jul 2, 2025
@rlubos
Copy link
Contributor Author

rlubos commented Jul 2, 2025

Added fix for memory corruptions in lwm2m_rd_client tests.

jukkar
jukkar previously approved these changes Jul 3, 2025
Comment on lines 667 to 671
if (temp > INT64_MAX / 10ULL) {
return -EINVAL;
}

temp = temp * 10ULL + (c - '0');
Copy link
Contributor

@kartben kartben Jul 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INT64_MAX = 9223372036854775807 so 922337203685477580 once divided by 10, hence you're basically allowing 9223372036854775808 and 9223372036854775809 as valid values (confirmed by testing)

also make sure that when you fix it you still allow -9223372036854775808 (INT64_MIN) to be a valid input. Currently if the highlighted code were to work as I think you wanted it to, it would have not allowed for temp to end up being 9223372036854775808

Copy link
Contributor

@kartben kartben Jul 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a good idea to also add some tests, I guess :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, on the second thought my original proposal (#92317 (comment)) was fine, the overflow is not a concern as temp is uint64_t and we compare against int64_t limits. I'll add a test for the overflow case too.

rlubos added 7 commits July 24, 2025 10:29
Verify if the integer value being parsed does not overflow int64_t type
and report an error in such cases.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Verify if the integer value being parsed does not overflow int64_t type
and report an error in such cases.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
* Simplify the logic of the get_number() function to address the corner
  cases reported by UBSAN regarding byte-swapping signed integer values.

  The existing logic was actually only valid for little-endian systems,
  as it expected that the bytes written from the packet buffer will be
  stored at the beginning of the int64_t memory, plus the actual
  byte-swapping with signed integer casts inside was hard to follow.
  Switch to a plain uint8_t buffer for integer readout, and use
  dedicated system function to convert the big-endian data in the buffer
  into unsigned integer in the system endianness, followed by the final
  cast to a signed value.

* Add explicit cast to uint32_t in put_objlnk() to prevent warning about
  not-fitting integer after byte shift, and update the result type to
  uint32_t as well.

* Switch to buffer with sys_put_be16/32/64 when writing integers due to
  similar warnings about byte-swapping signed values.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Check if there actually is data to copy before calling memcpy() to
prevent potentially calling memcpy() with NULL value pointer.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
LwM2M client context was defined on stack in the test function, however
it could still be in use when the test ended, as the actual LwM2M
teardown took place in a common "after" test function. In result, the
Lwm2M context content could be corrupted.

Additionally, increase the system work queue stack size, as the stack
overflowed.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add checks for int64_t overflows when parsing.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add checks for int64_t overflows when parsing.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
@rlubos rlubos force-pushed the net/lwm2m-fix-ubsan-warning branch from a11a335 to 67e65bf Compare July 24, 2025 08:30
@rlubos
Copy link
Contributor Author

rlubos commented Jul 24, 2025

Updated the int64_t overflow check + added some extra test coverage for this.

@rlubos rlubos requested review from SeppoTakalo and kartben July 24, 2025 08:31
@rlubos rlubos requested a review from jukkar July 24, 2025 08:32
@sonarqubecloud
Copy link

@fabiobaltieri fabiobaltieri merged commit 7b73998 into zephyrproject-rtos:main Jul 24, 2025
36 of 38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants