From 2aee83ae769b9a56813c20be758cd378d8f4e890 Mon Sep 17 00:00:00 2001 From: Gaurav Nebhwani Date: Tue, 15 Dec 2015 22:25:04 +0530 Subject: platform: msm_shared: add buffer overread check read_der_message_length assumes the size of input buffer itself but this function is called by multiple functions that might have different buffer size, so length of buffer is passed as a parameter and added in the check. Change-Id: I789a39fa670a3c191e6ea8e01bacc1221b472bf0 --- app/aboot/aboot.c | 2 +- platform/msm_shared/boot_verifier.c | 14 +++++++------- platform/msm_shared/include/boot_verifier.h | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c index a0b6b7f3..f5e4a01d 100644 --- a/app/aboot/aboot.c +++ b/app/aboot/aboot.c @@ -2545,7 +2545,7 @@ void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz) fastboot_fail("unlock device to flash keystore"); return; } - if(!boot_verify_validate_keystore((unsigned char *)data)) + if(!boot_verify_validate_keystore((unsigned char *)data,sz)) { fastboot_fail("image is not a keystore file"); return; diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c index 4a41992a..49c60cd0 100644 --- a/platform/msm_shared/boot_verifier.c +++ b/platform/msm_shared/boot_verifier.c @@ -96,14 +96,14 @@ IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE_INNER) } ASN1_SEQUENCE_END(KEYSTORE) IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE) -static uint32_t read_der_message_length(unsigned char* input) +static uint32_t read_der_message_length(unsigned char* input, unsigned sz) { uint32_t len = 0; - int pos = 0; + uint32_t pos = 0; uint8_t len_bytes = 1; /* Check if input starts with Sequence id (0X30) */ - if(input[pos] != 0x30) + if(sz < 3 || input[pos] != 0x30) return len; pos++; @@ -132,7 +132,7 @@ static uint32_t read_der_message_length(unsigned char* input) } /* Read next octet */ - if (pos < (int) ASN1_SIGNATURE_BUFFER_SZ) + if (pos < (uint32_t) ASN1_SIGNATURE_BUFFER_SZ && pos < sz) len = len | input[pos]; else { @@ -551,7 +551,7 @@ bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname) /* Copy the signature from scratch memory to buffer */ memcpy(signature, sig_addr, ASN1_SIGNATURE_BUFFER_SZ); - sig_len = read_der_message_length(signature); + sig_len = read_der_message_length(signature, ASN1_SIGNATURE_BUFFER_SZ); if(!sig_len) { @@ -647,12 +647,12 @@ void boot_verify_print_state() } } -bool boot_verify_validate_keystore(unsigned char * user_addr) +bool boot_verify_validate_keystore(unsigned char * user_addr, unsigned sz) { bool ret = false; unsigned char *input = user_addr; KEYSTORE *ks = NULL; - uint32_t len = read_der_message_length(input); + uint32_t len = read_der_message_length(input, sz); if(!len) { dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n"); diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h index c40a435f..485cc3cd 100644 --- a/platform/msm_shared/include/boot_verifier.h +++ b/platform/msm_shared/include/boot_verifier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -172,7 +172,7 @@ uint32_t boot_verify_get_state(); /* Print current boot state */ void boot_verify_print_state(); /* Function to validate keystore */ -bool boot_verify_validate_keystore(unsigned char * user_addr); +bool boot_verify_validate_keystore(unsigned char * user_addr, unsigned sz); /* Function to send root of trust to trust zone */ bool send_rot_command(uint32_t is_unlocked); unsigned char* get_boot_fingerprint(unsigned int* buf_size); -- cgit v1.2.3