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) {