Skip to content

Commit 81f22d6

Browse files
authored
Merge pull request #319 from wolfSSL/NVM-int-overflow
Fix integer overflow-prone offset+len bounds checks in NVM read handlers
2 parents 977bf18 + d43c6d4 commit 81f22d6

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

src/wh_nvm_flash.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,8 @@ static int nfPartition_CheckDataRange(whNvmFlashContext* context,
500500
return WH_ERROR_BADARGS;
501501
}
502502

503-
if (byte_offset + byte_count > maxOffset) {
503+
/* Use overflow-safe comparison */
504+
if (byte_offset > maxOffset || byte_count > maxOffset - byte_offset) {
504505
return WH_ERROR_BADARGS;
505506
}
506507

@@ -665,13 +666,14 @@ static int nfObject_ReadDataBytes(whNvmFlashContext* context, int partition,
665666
start = context->directory.objects[object_index].state.start;
666667
startOffset = nfPartition_DataOffset(context, partition) + start;
667668

668-
/* object bounds checks, do both to avoid integer overflow checks */
669+
/* object bounds checks, use overflow-safe comparison */
669670
if (byte_offset >=
670671
(context->directory.objects[object_index].metadata.len)) {
671672
return WH_ERROR_BADARGS;
672673
}
673-
if ((byte_offset + byte_count) >
674-
(context->directory.objects[object_index].metadata.len)) {
674+
if (byte_count >
675+
(uint32_t)(context->directory.objects[object_index].metadata.len) -
676+
byte_offset) {
675677
return WH_ERROR_BADARGS;
676678
}
677679

src/wh_server_nvm.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ static int _HandleNvmRead(whServerContext* server, uint8_t* out_data,
6767
if (offset >= meta.len)
6868
return WH_ERROR_BADARGS;
6969

70-
/* Clamp length to object size */
71-
if ((offset + len) > meta.len) {
70+
/* Clamp length to object size, use overflow-safe comparison */
71+
if (len > meta.len - offset) {
7272
len = meta.len - offset;
7373
}
7474

@@ -427,8 +427,9 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
427427

428428
if (rc == 0) {
429429
read_len = req.data_len;
430-
/* Clamp length to object size */
431-
if ((req.offset + read_len) > meta.len) {
430+
/* Clamp length to object size, use overflow-safe
431+
* comparison */
432+
if (read_len > meta.len - req.offset) {
432433
read_len = meta.len - req.offset;
433434
}
434435
}

test/wh_test_clientserver.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,29 @@ static int _testOutOfBoundsNvmReads(whClientContext* client,
562562
wh_Client_NvmReadResponse(client, &server_rc, &len, buffer));
563563
WH_TEST_ASSERT_RETURN(server_rc == WH_ERROR_BADARGS);
564564

565+
/* Test with large offset (UINT16_MAX), should fail since offset >=
566+
* meta.len. Regression test for integer overflow safety in the
567+
* offset+len check */
568+
off = UINT16_MAX;
569+
len = 1;
570+
WH_TEST_RETURN_ON_FAIL(wh_Client_NvmReadRequest(client, id, off, len));
571+
WH_TEST_RETURN_ON_FAIL(wh_Server_HandleRequestMessage(server));
572+
WH_TEST_RETURN_ON_FAIL(
573+
wh_Client_NvmReadResponse(client, &server_rc, &len, buffer));
574+
WH_TEST_ASSERT_RETURN(server_rc == WH_ERROR_BADARGS);
575+
576+
/* Test clamping with offset at midpoint and len exceeding remaining object
577+
* size. Verifies the overflow-safe comparison (len > meta.len - offset)
578+
* correctly clamps when offset + len would exceed meta.len */
579+
off = meta.len / 2;
580+
len = meta.len;
581+
WH_TEST_RETURN_ON_FAIL(wh_Client_NvmReadRequest(client, id, off, len));
582+
WH_TEST_RETURN_ON_FAIL(wh_Server_HandleRequestMessage(server));
583+
WH_TEST_RETURN_ON_FAIL(
584+
wh_Client_NvmReadResponse(client, &server_rc, &len, buffer));
585+
WH_TEST_ASSERT_RETURN(server_rc == WH_ERROR_OK);
586+
WH_TEST_ASSERT_RETURN(len == meta.len - meta.len / 2);
587+
565588
return WH_ERROR_OK;
566589
}
567590

0 commit comments

Comments
 (0)