Skip to content

Commit 4d949ee

Browse files
nandojvejhedberg
authored andcommitted
lib: updatehub: Fix variable-size string copy
A malformed JSON payload that is received from an UpdateHub server may trigger memory corruption in the Zephyr OS. This could result in a denial of service in the best case, or code execution in the worst case. Signed-off-by: Gerson Fernando Budke <[email protected]>
1 parent 8e8ba23 commit 4d949ee

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

lib/updatehub/updatehub.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ LOG_MODULE_REGISTER(updatehub);
4545
#define COAP_MAX_RETRY 3
4646
#define MAX_IP_SIZE 30
4747

48+
#define SHA256_HEX_DIGEST_SIZE ((TC_SHA256_DIGEST_SIZE * 2) + 1)
49+
4850
#if defined(CONFIG_UPDATEHUB_CE)
4951
#define UPDATEHUB_SERVER CONFIG_UPDATEHUB_SERVER
5052
#else
@@ -66,8 +68,8 @@ static struct updatehub_context {
6668
} ctx;
6769

6870
static struct update_info {
69-
char package_uid[TC_SHA256_BLOCK_SIZE + 1];
70-
char sha256sum_image[TC_SHA256_BLOCK_SIZE + 1];
71+
char package_uid[SHA256_HEX_DIGEST_SIZE];
72+
char sha256sum_image[SHA256_HEX_DIGEST_SIZE];
7173
int image_size;
7274
} update_info;
7375

@@ -106,13 +108,13 @@ static int metadata_hash_get(char *metadata)
106108
return -1;
107109
}
108110

109-
memset(update_info.package_uid, 0, TC_SHA256_BLOCK_SIZE + 1);
111+
memset(update_info.package_uid, 0, SHA256_HEX_DIGEST_SIZE);
110112
for (int i = 0; i < TC_SHA256_DIGEST_SIZE; i++) {
111113
snprintk(buffer, sizeof(buffer), "%02x",
112114
hash[i]);
113115
buffer_len = buffer_len + strlen(buffer);
114116
strncat(&update_info.package_uid[i], buffer,
115-
MIN(TC_SHA256_BLOCK_SIZE, buffer_len));
117+
MIN(SHA256_HEX_DIGEST_SIZE - 1, buffer_len));
116118
}
117119

118120
return 0;
@@ -325,20 +327,20 @@ static int send_request(enum coap_msgtype msgtype, enum coap_method method,
325327
static bool install_update_cb_sha256(void)
326328
{
327329
u8_t image_hash[TC_SHA256_DIGEST_SIZE];
328-
char buffer[3], sha256_image_dowloaded[TC_SHA256_BLOCK_SIZE + 1];
330+
char buffer[3], sha256_image_dowloaded[SHA256_HEX_DIGEST_SIZE];
329331
int i, buffer_len = 0;
330332

331333
if (tc_sha256_final(image_hash, &ctx.sha256sum) < 1) {
332334
LOG_ERR("Could not finish sha256sum");
333335
return false;
334336
}
335337

336-
memset(&sha256_image_dowloaded, 0, TC_SHA256_BLOCK_SIZE + 1);
338+
memset(&sha256_image_dowloaded, 0, SHA256_HEX_DIGEST_SIZE);
337339
for (i = 0; i < TC_SHA256_DIGEST_SIZE; i++) {
338340
snprintk(buffer, sizeof(buffer), "%02x", image_hash[i]);
339341
buffer_len = buffer_len + strlen(buffer);
340342
strncat(&sha256_image_dowloaded[i], buffer,
341-
MIN(TC_SHA256_BLOCK_SIZE, buffer_len));
343+
MIN(SHA256_HEX_DIGEST_SIZE - 1, buffer_len));
342344
}
343345

344346
if (strncmp(sha256_image_dowloaded,
@@ -625,6 +627,8 @@ enum updatehub_response updatehub_probe(void)
625627
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
626628
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
627629

630+
size_t sha256size;
631+
628632
if (device_id == NULL || firmware_version == NULL ||
629633
metadata == NULL || metadata_copy == NULL) {
630634
LOG_ERR("Could not alloc probe memory");
@@ -703,9 +707,18 @@ enum updatehub_response updatehub_probe(void)
703707
goto cleanup;
704708
}
705709

710+
sha256size = strlen(
711+
metadata_any_boards.objects[1].objects.sha256sum) + 1;
712+
713+
if (sha256size != SHA256_HEX_DIGEST_SIZE) {
714+
LOG_ERR("SHA256 size is invalid");
715+
ctx.code_status = UPDATEHUB_METADATA_ERROR;
716+
goto cleanup;
717+
}
718+
706719
memcpy(update_info.sha256sum_image,
707720
metadata_any_boards.objects[1].objects.sha256sum,
708-
strlen(metadata_any_boards.objects[1].objects.sha256sum));
721+
SHA256_HEX_DIGEST_SIZE);
709722
update_info.image_size = metadata_any_boards.objects[1].objects.size;
710723
} else {
711724
if (!is_compatible_hardware(&metadata_some_boards)) {
@@ -714,10 +727,19 @@ enum updatehub_response updatehub_probe(void)
714727
UPDATEHUB_INCOMPATIBLE_HARDWARE;
715728
goto cleanup;
716729
}
730+
731+
sha256size = strlen(
732+
metadata_any_boards.objects[1].objects.sha256sum) + 1;
733+
734+
if (sha256size != SHA256_HEX_DIGEST_SIZE) {
735+
LOG_ERR("SHA256 size is invalid");
736+
ctx.code_status = UPDATEHUB_METADATA_ERROR;
737+
goto cleanup;
738+
}
739+
717740
memcpy(update_info.sha256sum_image,
718741
metadata_some_boards.objects[1].objects.sha256sum,
719-
strlen(metadata_some_boards.objects[1]
720-
.objects.sha256sum));
742+
SHA256_HEX_DIGEST_SIZE);
721743
update_info.image_size =
722744
metadata_some_boards.objects[1].objects.size;
723745
}

0 commit comments

Comments
 (0)