app: aboot: Verify the boot.img address are not overlapping with LK address.

CRs-Fixed: 491421
Change-Id: Iae544722dab4eea3ba5d7b7721ea72d3a4edbe18
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 48724d0..1fe24a8 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -85,6 +85,12 @@
 #define EMMC_BOOT_IMG_HEADER_ADDR 0xFF000
 #endif
 
+#ifndef MEMSIZE
+#define MEMSIZE 1024*1024
+#endif
+
+#define MAX_TAGS_SIZE   1024
+
 #define RECOVERY_MODE   0x77665502
 #define FASTBOOT_MODE   0x77665500
 
@@ -501,6 +507,26 @@
 	entry(0, machtype, (unsigned*)tags_phys);
 }
 
+/* Function to check if the memory address range falls within the aboot
+ * boundaries.
+ * start: Start of the memory region
+ * size: Size of the memory region
+ */
+int check_aboot_addr_range_overlap(uint32_t start, uint32_t size)
+{
+	/* Check for boundary conditions. */
+	if ((start + size) < start)
+		return -1;
+
+	/* Check for memory overlap. */
+	if ((start < MEMBASE) && ((start + size) <= MEMBASE))
+		return 0;
+	else if (start > (MEMBASE + MEMSIZE))
+		return 0;
+	else
+		return -1;
+}
+
 #define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
 
 BUF_DMA_ALIGN(buf, 4096); //Equal to max-supported pagesize
@@ -508,6 +534,45 @@
 BUF_DMA_ALIGN(dt_buf, 4096);
 #endif
 
+static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size)
+{
+	int ret;
+
+	/* Assume device is rooted at this time. */
+	device.is_tampered = 1;
+
+	dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
+
+	ret = image_verify((unsigned char *)bootimg_addr,
+					   (unsigned char *)(bootimg_addr + bootimg_size),
+					   bootimg_size,
+					   CRYPTO_AUTH_ALG_SHA256);
+
+	dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret);
+
+	if (ret)
+	{
+		/* Authorized kernel */
+		device.is_tampered = 0;
+	}
+
+#if USE_PCOM_SECBOOT
+	set_tamper_flag(device.is_tampered);
+#endif
+
+	if(device.is_tampered)
+	{
+		write_device_info_mmc(&device);
+	#ifdef TZ_TAMPER_FUSE
+		set_tamper_fuse_cmd();
+	#endif
+	#ifdef ASSERT_ON_TAMPER
+		dprintf(CRITICAL, "Device is tampered. Asserting..\n");
+		ASSERT(0);
+	#endif
+	}
+}
+
 int boot_linux_from_mmc(void)
 {
 	struct boot_img_hdr *hdr = (void*) buf;
@@ -589,22 +654,46 @@
 	hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
 	hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
 	hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
+
+	kernel_actual  = ROUND_TO_PAGE(hdr->kernel_size,  page_mask);
+	ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+
+	/* Check if the addresses in the header are valid. */
+	if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
+		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
+	{
+		dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
+		return -1;
+	}
+
+#ifndef DEVICE_TREE
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+	{
+		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+		return -1;
+	}
+#endif
+
 	/* Authenticate Kernel */
 	if(target_use_signed_kernel() && (!device.is_unlocked) && (!device.is_tampered))
 	{
+		offset = 0;
+
 		image_addr = (unsigned char *)target_get_scratch_address();
-		kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
-		ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+
 #if DEVICE_TREE
 		dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
 		imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
+
+		if (check_aboot_addr_range_overlap(hdr->tags_addr, hdr->dt_size))
+		{
+			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+			return -1;
+		}
 #else
 		imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
-#endif
-		offset = 0;
 
-		/* Assuming device rooted at this time */
-		device.is_tampered = 1;
+#endif
 
 		dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
 		bs_set_timestamp(BS_KERNEL_LOAD_START);
@@ -624,31 +713,14 @@
 		if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
 		{
 			dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
+			return -1;
 		}
-		else
-		{
-			dprintf(INFO, "Authenticating boot image (%d): start\n", imagesize_actual);
 
-			auth_kernel_img = image_verify((unsigned char *)image_addr,
-					(unsigned char *)(image_addr + imagesize_actual),
-					imagesize_actual,
-					CRYPTO_AUTH_ALG_SHA256);
-
-			dprintf(INFO, "Authenticating boot image (%d): done\n", imagesize_actual);
-
-			if(auth_kernel_img)
-			{
-				/* Authorized kernel */
-				device.is_tampered = 0;
-			}
-		}
+		verify_signed_bootimg(image_addr, imagesize_actual);
 
 		/* Move kernel, ramdisk and device tree to correct address */
 		memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
 		memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
-#if DEVICE_TREE
-		memmove((void*) hdr->tags_addr, (char *)(image_addr + page_size + kernel_actual + ramdisk_actual), hdr->dt_size);
-#endif
 
 		#if DEVICE_TREE
 		if(hdr->dt_size) {
@@ -672,7 +744,13 @@
 				return -1;
 			}
 
-			/* Read device device tree in the "tags_add */
+			/* Validate and Read device device tree in the "tags_add */
+			if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry_ptr->size))
+			{
+				dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+				return -1;
+			}
+
 			memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry_ptr->offset, dt_entry_ptr->size);
 		} else {
 			/*
@@ -689,22 +767,9 @@
 			}
 		}
 		#endif
-		/* Make sure everything from scratch address is read before next step!*/
-		if(device.is_tampered)
-		{
-			write_device_info_mmc(&device);
-		#ifdef TZ_TAMPER_FUSE
-			set_tamper_fuse_cmd();
-		#endif
-		}
-	#if USE_PCOM_SECBOOT
-		set_tamper_flag(device.is_tampered);
-	#endif
 	}
 	else
 	{
-		kernel_actual  = ROUND_TO_PAGE(hdr->kernel_size,  page_mask);
-		ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
 		second_actual  = ROUND_TO_PAGE(hdr->second_size,  page_mask);
 
 		dprintf(INFO, "Loading boot image (%d): start\n",
@@ -765,7 +830,13 @@
 				return -1;
 			}
 
-			/* Read device device tree in the "tags_add */
+			/* Validate and Read device device tree in the "tags_add */
+			if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry_ptr->size))
+			{
+				dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+				return -1;
+			}
+
 			if(mmc_read(ptn + offset + dt_entry_ptr->offset,
 						 (void *)hdr->tags_addr, dt_entry_ptr->size)) {
 				dprintf(CRITICAL, "ERROR: Cannot read device tree\n");
@@ -872,26 +943,47 @@
 	update_ker_tags_rdisk_addr(hdr);
 
 	/* Get virtual addresses since the hdr saves physical addresses. */
-	hdr->kernel_addr = VA(hdr->kernel_addr);
-	hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
-	hdr->tags_addr = VA(hdr->tags_addr);
+	hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
+	hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
+	hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
+
+	kernel_actual  = ROUND_TO_PAGE(hdr->kernel_size,  page_mask);
+	ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+
+	/* Check if the addresses in the header are valid. */
+	if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
+		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
+	{
+		dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
+		return -1;
+	}
+
+#ifndef DEVICE_TREE
+		if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+		{
+			dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+			return -1;
+		}
+#endif
 
 	/* Authenticate Kernel */
 	if(target_use_signed_kernel() && (!device.is_unlocked) && (!device.is_tampered))
 	{
 		image_addr = (unsigned char *)target_get_scratch_address();
-		kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
-		ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+		offset = 0;
+
 #if DEVICE_TREE
 		dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
 		imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
+
+		if (check_aboot_addr_range_overlap(hdr->tags_addr, hdr->dt_size))
+		{
+			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+			return -1;
+		}
 #else
 		imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
 #endif
-		offset = 0;
-
-		/* Assuming device rooted at this time */
-		device.is_tampered = 1;
 
 		dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
 		bs_set_timestamp(BS_KERNEL_LOAD_START);
@@ -911,30 +1003,22 @@
 		if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
 		{
 			dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
+			return -1;
 		}
-		else
-		{
-			dprintf(INFO, "Authenticating boot image (%d): start\n", imagesize_actual);
 
-			/* Verify signature */
-			auth_kernel_img = image_verify((unsigned char *)image_addr,
-						(unsigned char *)(image_addr + imagesize_actual),
-						imagesize_actual,
-						CRYPTO_AUTH_ALG_SHA256);
-
-			dprintf(INFO, "Authenticating boot image (%d): done\n", imagesize_actual);
-
-			if(auth_kernel_img)
-			{
-				/* Authorized kernel */
-				device.is_tampered = 0;
-			}
-		}
+		verify_signed_bootimg(image_addr, imagesize_actual);
 
 		/* Move kernel and ramdisk to correct address */
 		memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
 		memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
 #if DEVICE_TREE
+		/* Validate and Read device device tree in the "tags_add */
+		if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry_ptr->size))
+		{
+			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+			return -1;
+		}
+
 		memmove((void*) hdr->tags_addr, (char *)(image_addr + page_size + kernel_actual + ramdisk_actual), hdr->dt_size);
 #endif
 
@@ -1007,6 +1091,13 @@
 				return -1;
 			}
 
+			/* Validate and Read device device tree in the "tags_add */
+			if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry_ptr->size))
+			{
+				dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+				return -1;
+			}
+
 			/* Read device device tree in the "tags_add */
 			if(flash_read(ptn, offset + dt_entry_ptr->offset,
 						 (void *)hdr->tags_addr, dt_entry_ptr->size)) {
@@ -1235,6 +1326,13 @@
 			return -1;
 		}
 
+		/* Validate and Read device device tree in the "tags_add */
+		if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry_ptr->size))
+		{
+			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+			return -1;
+		}
+
 		/* Read device device tree in the "tags_add */
 		memmove((void*) hdr->tags_addr,
 				boot_image_start + dt_image_offset +  dt_entry_ptr->offset,
@@ -1286,6 +1384,14 @@
 	hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
 	hdr->tags_addr = VA(hdr->tags_addr);
 
+	/* Check if the addresses in the header are valid. */
+	if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
+		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
+	{
+		dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
+		return -1;
+	}
+
 	/* sz should have atleast raw boot image */
 	if (page_size + kernel_actual + ramdisk_actual > sz) {
 		fastboot_fail("incomplete bootimage");
@@ -1297,6 +1403,12 @@
 	ret = copy_dtb(data);
 
 	dtb_copied = !ret ? 1 : 0;
+#else
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+	{
+		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+		return -1;
+	}
 #endif
 
 	/* Load ramdisk & kernel */
@@ -1320,6 +1432,14 @@
 	}
 #endif
 
+#ifndef DEVICE_TREE
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+	{
+		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+		return -1;
+	}
+#endif
+
 	fastboot_okay("");
 	udc_stop();
 
@@ -1831,6 +1951,8 @@
 		page_mask = page_size - 1;
 	}
 
+	ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
+
 	if(target_use_signed_kernel())
 	{
 		read_device_info(&device);