Skip to content

Linker section alignment isn't suitable for MPU #524

@BigPeteB

Description

@BigPeteB

Correct me if I've gotten anything wrong—I'm not a general Cortex-M expert—but as I understand it, MPU regions must be 32-byte aligned. The linker script in cortex-m-rt uses 32-byte alignment only for .gnu.sgstubs to satisfy the SAU, but uses smaller alignment for all other sections.

The potential results could be very harmful, depending on how the MPU regions are configured. Consider the case of .text followed immediately by .rodata or .data:

  1. If we round towards lower addresses when configuring MPU regions, a few instructions of code would end up in the data region and be marked non-executable. This would be disastrous as it would crash.
  2. If we round towards higher addresses, a few bytes of data would end up in the code region and be marked executable. This could potentially be exploited if an attacker could find a way to manipulate that data so that it contains the instructions they desire (or they get lucky and the data already happens to correspond to instructions they can exploit) and then find a way to cause those instructions to be executed.

(I should mention, I'm considering cases that may be a bit beyond what cortex-m-rt supports out of the box, such as the FLASH memory region actually being in RAM, in which case it's not inherently read-only. But even if FLASH corresponds to read-only storage as cortex-m-rt expects, there are still potential crashes or security exploits waiting to happen.)

I think the linker script should be modified to use 32-byte alignment for regions that users would expect to configure separate MPU regions for. Given the current order of sections that are output, this affects almost all of them: 😭

  • .vector_table (read-only, NX)
  • .text (read-only, executable)
  • .rodata (read-only, NX)
  • .data (the destination would be writeable, NX, but the source data in FLASH would be read-only, NX... or more likely would be unmapped since it's not needed after runtime initialization)
  • .gnu.sgstubs (read-only, NX)
  • .bss, .uninit, heap, and stack are probably unaffected since they would likely be in a contiguous MPU region with .data, although maybe some users want to put the heap and stack in their own MPU regions so their sizes can be dynamically adjusted.

Rearranging the linker sections could allow some regions to be consolidated and use fewer MPU regions, which would reduce the need to align/pad some of the sections. (Also, I just noticed that .gnu.sgstubs is placed after the comment /* ## Sections in RAM */, which is incorrect: it's placed in FLASH.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions