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
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index 9c80839..12488a9 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -96,14 +96,14 @@
} 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 @@
}
/* 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
{
@@ -550,7 +550,7 @@
/* 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)
{
@@ -646,12 +646,12 @@
}
}
-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");