ARMmbed / uvisor

DEPRECATED mbed OS uVisor -- device security layer for ARMv7M microcontrollers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

v7M MPU error with box reorder

ccli8 opened this issue · comments

commented

Environment

  • uvision: 2020bea
  • mbed OS: mbed OS 5.5.0
  • target: NUMAKER_PFM_M487 (Nuvoton's new target)

Reproduce

I am adding M480 (Nuvoton's new chip) port for uvisor and writing a sample to test it. I meet an error with the log:

uVisor mode: 2
uvisor_ram : @0x20000000 (8192 bytes) [config]
             @0x20000000 (8192 bytes) [linker]
bss_boxes  : @0x20002000 (81920 bytes) [config]

box stack segment start=0x20002000 end=0x20016000 (length=81920)
MPU.REGIONS=8
MPU.ALIGNMENT=0x0000001F
MPU.ALIGNMENT_BITS=5
* MPU CONFIGURATION

  Background region enabled
  MPU bypassed @NMI, @HardFault
  MPU enabled

  Region Start      Size  XN AP  TEX S C B SRD      Valid
  0      0x00000000 128KB 0  110 000 0 0 0 00000000 1
  1      0x20000000 256KB 0  011 000 0 0 0 00001111 1
  2      0x00000000 000B  0  000 000 0 0 0 00000000 0
  3      0x00000000 000B  0  000 000 0 0 0 00000000 0
  4      0x00000000 000B  0  000 000 0 0 0 00000000 0
  5      0x00000000 000B  0  000 000 0 0 0 00000000 0
  6      0x00000000 000B  0  000 000 0 0 0 00000000 0
  7      0x00000000 000B  0  000 000 0 0 0 00000000 0

Box 0 ACLs:
  - Peripheral: 0x40000000 - 0x40000404 (permissions: 0x0AB6)
  - Peripheral: 0x40000200 - 0x400002B4 (permissions: 0x0AB6)
  - Peripheral: 0x40070000 - 0x4007004C (permissions: 0x0AB6)
  - Peripheral: 0x40004000 - 0x40004034 (permissions: 0x0AB6)
  - Peripheral: 0x40004040 - 0x40004074 (permissions: 0x0AB6)
  - Peripheral: 0x40004080 - 0x400040B4 (permissions: 0x0AB6)
  - Peripheral: 0x400040C0 - 0x400040F4 (permissions: 0x0AB6)
  - Peripheral: 0x40004100 - 0x40004134 (permissions: 0x0AB6)
  - Peripheral: 0x40004140 - 0x40004174 (permissions: 0x0AB6)
  - Peripheral: 0x40004180 - 0x400041B4 (permissions: 0x0AB6)
  - Peripheral: 0x400041C0 - 0x400041F4 (permissions: 0x0AB6)
  - Peripheral: 0x40004800 - 0x40004A00 (permissions: 0x0AB6)
  - Peripheral: 0x40050000 - 0x400500A8 (permissions: 0x0AB6)
  - Peripheral: 0x40050100 - 0x400501A8 (permissions: 0x0AB6)
  - Peripheral: 0x40051000 - 0x400510A8 (permissions: 0x0AB6)
  - Peripheral: 0x40051100 - 0x400511A8 (permissions: 0x0AB6)
Box 1 ACLs:
  - SRAM:       0x20004000 - 0x20008000 (permissions: 0x0076, subregions: 0x08)
    - BSS:      0x20004000 - 0x2000553C (original size: 5436B, rounded size: 6144B)
    - Stack:    0x20006000 - 0x20008000 (original size: 1024B, rounded size: 8192B)
Box 2 ACLs:
  - SRAM:       0x20008000 - 0x20010000 (permissions: 0x0076, subregions: 0x08)
    - BSS:      0x20008000 - 0x2000ADA8 (original size: 11688B, rounded size: 12288B)
    - Stack:    0x2000C000 - 0x20010000 (original size: 1024B, rounded size: 16384B)

  - Peripheral: 0x50080000 - 0x50080A58 (permissions: 0x0AB6)

Box 3 ACLs:
  - SRAM:       0x20010000 - 0x20014000 (permissions: 0x0076, subregions: 0x10)
    - BSS:      0x20010000 - 0x20011944 (original size: 6468B, rounded size: 8192B)
    - Stack:    0x20012800 - 0x20014000 (original size: 1024B, rounded size: 6144B)
vmpu_enumerate_boxes [DONE]
page heap: [0x20018000, 0x20020000] 32kB -> 4 8kB pages
uvisor initialized

***** NuMaker mbed uVisor example *****
Main loop count: 0
IRQ 71 registered to box 1
IRQ 71 enabled

***********************************************************
                    MEMMANAGE FAULT
***********************************************************

* Active Box ID: 1
* FAULT SYNDROME REGISTERS

  CFSR: 0x00000082

  MMFAR: 0x50080000

  --> DACCVIOL: data access violation.

* MPU FAULT

* MEMORY MAP
  Address:           0x50080000
  Region/Peripheral: [not available]
    Base address:    0x50080000
    End address:     0x50080000
    Before bitband:  [invalid]

* EXCEPTION STACK FRAME

  lr: 0xFFFFFFFD
  --> FP stack frame not saved.
  --> Exception from NP mode.
  --> Return to PSP.

  sp: 0x20005070
      sp[07]: 0x01000000 | xPSR
      sp[06]: 0x0000CE32 | pc
      sp[05]: 0x0000CE2F | lr
      sp[04]: 0x20025D6C | r12
      sp[03]: 0x50080000 | r3
      sp[02]: 0x50080000 | r2
      sp[01]: 0x0000C004 | r1
      sp[00]: 0x00000001 | r0


* MPU CONFIGURATION

  Background region enabled
  MPU bypassed @NMI, @HardFault
  MPU enabled

  Region Start      Size  XN AP  TEX S C B SRD      Valid
  0      0x00000000 128KB 0  110 000 0 0 0 00000000 1
  1      0x20000000 256KB 0  011 000 0 0 0 00001111 1
  2      0x00000000 000B  0  000 000 0 0 0 00000000 0
  3      0x20004000 016KB 1  011 000 0 0 0 00001000 1
  4      0x00000000 000B  0  000 000 0 0 0 00000000 0
  5      0x00000000 000B  0  000 000 0 0 0 00000000 0
  6      0x00000000 000B  0  000 000 0 0 0 00000000 0
  7      0x00000000 000B  0  000 000 0 0 0 00000000 0

***********************************************************

HALT_ERROR(./core/vmpu/src/mpu_armv7m/vmpu_armv7m.c#184): Access to restricted resource denied.

According to the log, there is data access violation in 0x50080000. But I have configured ACL for it.

Box 2 ACLs:
  - SRAM:       0x20008000 - 0x20010000 (permissions: 0x0076, subregions: 0x08)
    - BSS:      0x20008000 - 0x2000ADA8 (original size: 11688B, rounded size: 12288B)
    - Stack:    0x2000C000 - 0x20010000 (original size: 1024B, rounded size: 16384B)

  - Peripheral: 0x50080000 - 0x50080A58 (permissions: 0x0AB6)

I doubt it results from box reorder in uvisor core. To prove my guess, I disable box reorder:
In uvisor/core/vmpu/src/vmpu.c > vmpu_enumerate_boxes

static void vmpu_enumerate_boxes(void)
{
    /* Enumerate boxes. */
    g_vmpu_box_count = (uint32_t) (__uvisor_config.cfgtbl_ptr_end - __uvisor_config.cfgtbl_ptr_start);
    if (g_vmpu_box_count >= UVISOR_MAX_BOXES) {
        HALT_ERROR(SANITY_CHECK_FAILED, "box number overflow\n");
    }
    g_vmpu_boxes_counted = TRUE;

    /* Get the boxes order. This is MPU-specific. */

    //int box_order[UVISOR_MAX_BOXES];
    //vmpu_order_boxes(box_order, g_vmpu_box_count);


    /* Initialize the boxes. */
    for (uint8_t box_id = 0; box_id < g_vmpu_box_count; ++box_id) {
        /* Select the pointer to the (permuted) box configuration table. */

        //int index = box_order[box_id];
        int index = box_id;

        UvisorBoxConfig const * box_cfgtbl = ((UvisorBoxConfig const * *) __uvisor_config.cfgtbl_ptr_start)[index];

Re-test, and I get the correct result:

uVisor mode: 2
uvisor_ram : @0x20000000 (8192 bytes) [config]
             @0x20000000 (8192 bytes) [linker]
bss_boxes  : @0x20002000 (81920 bytes) [config]

box stack segment start=0x20002000 end=0x20016000 (length=81920)
MPU.REGIONS=8
MPU.ALIGNMENT=0x0000001F
MPU.ALIGNMENT_BITS=5
* MPU CONFIGURATION

  Background region enabled
  MPU bypassed @NMI, @HardFault
  MPU enabled

  Region Start      Size  XN AP  TEX S C B SRD      Valid
  0      0x00000000 128KB 0  110 000 0 0 0 00000000 1
  1      0x20000000 256KB 0  011 000 0 0 0 00001111 1
  2      0x00000000 000B  0  000 000 0 0 0 00000000 0
  3      0x00000000 000B  0  000 000 0 0 0 00000000 0
  4      0x00000000 000B  0  000 000 0 0 0 00000000 0
  5      0x00000000 000B  0  000 000 0 0 0 00000000 0
  6      0x00000000 000B  0  000 000 0 0 0 00000000 0
  7      0x00000000 000B  0  000 000 0 0 0 00000000 0

Box 0 ACLs:
  - Peripheral: 0x40000000 - 0x40000404 (permissions: 0x0AB6)
  - Peripheral: 0x40000200 - 0x400002B4 (permissions: 0x0AB6)
  - Peripheral: 0x40070000 - 0x4007004C (permissions: 0x0AB6)
  - Peripheral: 0x40004000 - 0x40004034 (permissions: 0x0AB6)
  - Peripheral: 0x40004040 - 0x40004074 (permissions: 0x0AB6)
  - Peripheral: 0x40004080 - 0x400040B4 (permissions: 0x0AB6)
  - Peripheral: 0x400040C0 - 0x400040F4 (permissions: 0x0AB6)
  - Peripheral: 0x40004100 - 0x40004134 (permissions: 0x0AB6)
  - Peripheral: 0x40004140 - 0x40004174 (permissions: 0x0AB6)
  - Peripheral: 0x40004180 - 0x400041B4 (permissions: 0x0AB6)
  - Peripheral: 0x400041C0 - 0x400041F4 (permissions: 0x0AB6)
  - Peripheral: 0x40004800 - 0x40004A00 (permissions: 0x0AB6)
  - Peripheral: 0x40050000 - 0x400500A8 (permissions: 0x0AB6)
  - Peripheral: 0x40050100 - 0x400501A8 (permissions: 0x0AB6)
  - Peripheral: 0x40051000 - 0x400510A8 (permissions: 0x0AB6)
  - Peripheral: 0x40051100 - 0x400511A8 (permissions: 0x0AB6)
Box 1 ACLs:
  - SRAM:       0x20008000 - 0x20010000 (permissions: 0x0076, subregions: 0x08)
    - BSS:      0x20008000 - 0x2000ADA8 (original size: 11688B, rounded size: 12288B)
    - Stack:    0x2000C000 - 0x20010000 (original size: 1024B, rounded size: 16384B)

  - Peripheral: 0x50080000 - 0x50080A58 (permissions: 0x0AB6)

Box 2 ACLs:
  - SRAM:       0x20010000 - 0x20014000 (permissions: 0x0076, subregions: 0x08)
    - BSS:      0x20010000 - 0x2001153C (original size: 5436B, rounded size: 6144B)
    - Stack:    0x20012000 - 0x20014000 (original size: 1024B, rounded size: 8192B)
Box 3 ACLs:
  - SRAM:       0x20014000 - 0x20018000 (permissions: 0x0076, subregions: 0x10)
    - BSS:      0x20014000 - 0x20015944 (original size: 6468B, rounded size: 8192B)
    - Stack:    0x20016800 - 0x20018000 (original size: 1024B, rounded size: 6144B)
vmpu_enumerate_boxes [DONE]
page heap: [0x20018000, 0x20020000] 32kB -> 4 8kB pages
uvisor initialized

***** NuMaker mbed uVisor example *****
Main loop count: 0
IRQ 71 registered to box 1
IRQ 71 enabled
uvisor_page_malloc: Requesting 1 pages with size 8192B for box 1
uvisor_page_malloc: Found an empty page 0x20018000 entry at index 0
uvisor_page_malloc: 3 free pages remaining.

aes_box_main loop count: 0
IRQ 18 registered to box 3
IRQ 18 enabled
AES compare OK: 0
Main loop count: 1
aes_box_main loop count: 1
Main loop count: 2
aes_box_main loop count: 2
AES compare OK: 1
Main loop count: 3
aes_box_main loop count: 3
Main loop count: 4
aes_box_main loop count: 4
AES compare OK: 2
Main loop count: 5
aes_box_main loop count: 5
Main loop count: 6
aes_box_main loop count: 6
AES compare OK: 3
Main loop count: 7

In my understanding, according to vmpu_enumerate_boxes, after box reorder, to map from box_id to UvisorBoxConfig, box_order array is necessary. But the array is only available in vmpu_enumerate_boxes. Other code still directly use box_id as an index to get its UvisorBoxConfig. That might be the cause.

ARM Internal Ref: IOTSEC-387

commented

@Patater I test with the latest uVisor version bb70f18 and it is OK. Thanks.