service: metadata: Add checks for heap overflow
Avoid heap overflow during calloc, when writing data to the allocated
heap, which was happening due to integer has no boundary check.
Change-Id: I2522308a6600a81b501747c5c8fa5042485c6941
diff --git a/service/src/metadata.c b/service/src/metadata.c
index 87c0677..c94f856 100644
--- a/service/src/metadata.c
+++ b/service/src/metadata.c
@@ -71,6 +71,8 @@
#define NUM_PROPS(x) *((uint32_t *) PTR_TO_NUM_PROPS(x))
#define PTR_TO_PROPS(x) (PTR_TO_NUM_PROPS(x) + sizeof(uint32_t))
+#define MAX_KVPAIR 48
+
void metadata_print(struct agm_meta_data_gsl* metadata)
{
int i, count = metadata->gkv.num_kvs;
@@ -201,6 +203,13 @@
}
va_end(valist);
+ if ((merged->gkv.num_kvs > MAX_KVPAIR) || (merged->ckv.num_kvs > MAX_KVPAIR)) {
+ AGM_LOGE("Num GKVs %d Num CKVs %d more than expected: %d", merged->gkv.num_kvs,
+ merged->ckv.num_kvs, MAX_KVPAIR);
+ free(merged);
+ return NULL;
+ }
+
merged->gkv.kv = calloc(merged->gkv.num_kvs, sizeof(struct agm_key_value));
if (!merged->gkv.kv) {
AGM_LOGE("No memory to merge gkv\n");
@@ -271,6 +280,14 @@
AGM_LOGI("NULL metadata passed, ignoring\n");
return ret;
}
+
+ if ((NUM_GKV(metadata) > MAX_KVPAIR) || (NUM_CKV(metadata) > MAX_KVPAIR)) {
+ AGM_LOGE("Num GKVs %d Num CKVs %d more than expected: %d", NUM_GKV(metadata),
+ NUM_CKV(metadata), MAX_KVPAIR);
+ ret = -EINVAL;
+ return ret;
+ }
+
dest->gkv.num_kvs = NUM_GKV(metadata);
dest->gkv.kv = calloc(dest->gkv.num_kvs, sizeof(struct agm_key_value));
if (!dest->gkv.kv) {