altos/flash-loader: Check memory addresses against flash space
authorKeith Packard <keithp@keithp.com>
Tue, 13 May 2014 06:18:41 +0000 (23:18 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 13 May 2014 06:18:41 +0000 (23:18 -0700)
This validates memory read/write requests to make sure they are within
the available flash memory space.

This also reports the flash base and bounds addresses in the 'version'
command so that the loader can validate the image before attempting to
write it.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/product/ao_flash_task.c

index 6cb308e1fa5ee580656af86757ddbcf9c4bcd97f..9a12add659a00af10bc62b48b5042b62f834f73e 100644 (file)
@@ -79,6 +79,14 @@ ao_block_erase(void)
        ao_flash_erase_page(p);
 }
 
+static int
+ao_block_valid_address(uint32_t addr)
+{
+       if ((uint32_t) AO_BOOT_APPLICATION_BASE <= addr && addr <= (uint32_t) AO_BOOT_APPLICATION_BOUND - 256)
+               return 1;
+       return 0;
+}
+
 static void
 ao_block_write(void)
 {
@@ -87,12 +95,10 @@ ao_block_write(void)
        uint8_t         data[256];
        uint16_t        i;
 
-       if (addr < (uint32_t) AO_BOOT_APPLICATION_BASE) {
-               ao_put_string("Invalid address\n");
-               return;
-       }
        for (i = 0; i < 256; i++)
                data[i] = ao_usb_getchar();
+       if (!ao_block_valid_address(addr))
+               return;
        ao_flash_page(p, (void *) data);
 }
 
@@ -104,18 +110,43 @@ ao_block_read(void)
        uint16_t        i;
        uint8_t         c;
 
+       if (!ao_block_valid_address(addr)) {
+               for (i = 0; i < 256; i++)
+                       ao_usb_putchar(0xff);
+               return;
+       }
        for (i = 0; i < 256; i++) {
                c = *p++;
                ao_usb_putchar(c);
        }
 }
 
+static inline void
+hexchar(uint8_t c)
+{
+       if (c > 10)
+               c += 'a' - ('9' + 1);
+       ao_usb_putchar(c + '0');
+}
+
+static void
+ao_put_hex(uint32_t u)
+{
+       int8_t i;
+       for (i = 28; i >= 0; i -= 4)
+               hexchar((u >> i) & 0xf);
+}
+
 static void
 ao_show_version(void)
 {
        ao_put_string("altos-loader");
        ao_put_string("\nmanufacturer     "); ao_put_string(ao_manufacturer);
        ao_put_string("\nproduct          "); ao_put_string(ao_product);
+       ao_put_string("\nflash-range      ");
+       ao_put_hex((uint32_t) AO_BOOT_APPLICATION_BASE);
+       ao_usb_putchar(' ');
+       ao_put_hex((uint32_t) AO_BOOT_APPLICATION_BOUND);
        ao_put_string("\nsoftware-version "); ao_put_string(ao_version);
        ao_put_string("\n");
 }