Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • D dynamorio
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 1,467
    • Issues 1,467
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 44
    • Merge requests 44
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • DynamoRIO
  • dynamorio
  • Issues
  • #5129
Closed
Open
Issue created Sep 27, 2021 by Assad Hashmi@AssadHashmiContributor

relink_special_ibl_xfer() may overwrite first instruction of target block on AArch64 (CRASH)

This bug was spotted by a user and posted at https://groups.google.com/g/dynamorio-users/c/Ai5fFN9Q6iE

AArch64 uses two instructions to patch an IBL: LDR followed by BR.

However, both AArch32 and x86 use one jump instruction and the IBL patching functions assume only a one instruction jump patch. This can result in AArch64 applications crashing as summarised below.

Code generated by emit_special_ibl_xfer() on AArch64 (using -loglevel 4):

client_ibl_xfer:
. . .
  0x0000000041e424b8  f9403f81   ldr    +0x78(%x28)[8byte] -> %x1
  0x0000000041e424bc  d61f0020   br     %x1
clean_call_save:
  0x0000000041e424c0  a90007e0   stp    %x0 %x1 -> (%sp)[16byte]
. . .

When relink_special_ibl_xfer() is called the BR instruction of the LDR/BR pair overwrites:

. . .
  0x0000000041e424b8  f9403f81   ldr    +0x78(%x28)[8byte] -> %x1     <-- ldr    +0x78(%x28)[8byte] -> %x1
  0x0000000041e424bc  d61f0020   br     %x1                           <-- ldr    +0x78(%x28)[8byte] -> %x1
clean_call_save:
  0x0000000041e424c0  a90007e0   stp    %x0 %x1 -> (%sp)[16byte]      <-- br     %x1     <-- STP overwritten!
. . .

We have not seen this bug cause failure before due to NOP padding used for e.g. cache alignment which depends on the machine's cache line size:

client_ibl_xfer:
. . .
  0x00000000310124ac  f9403f81   ldr    +0x78(%x28)[8byte] -> %x1  <-- ldr    +0x78(%x28)[8byte] -> %x1
  0x00000000310124b0  d61f0020   br     %x1                        <-- ldr    +0x78(%x28)[8byte] -> %x1
  0x00000000310124b4  d503201f   nop                               <-- br     %x1
  0x00000000310124b8  d503201f   nop
  0x00000000310124bc  d503201f   nop
clean_call_save:
  0x00000000310124c0  a90007e0   stp    %x0 %x1 -> (%sp)[16byte]   <-- NOT overwritten because of NOP padding above.
. . .
Assignee
Assign to
Time tracking