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
  • #4464
Closed
Open
Issue created Sep 30, 2020 by Administrator@rootContributor

CRASH, x86-64 cleancall save_fpstate causes incorrect passing of register operands

Created by: nextsilicon-itay-bookstein

Passing save_fpstate = true to dr_insert_clean_call (or, alternatively, DR_CLEANCALL_SAVE_FLOAT to dr_insert_clean_call_ex) causes incorrect passing of register operands to the clean-call.

With save_fpstate = false:

 +121  m4 @0x00007fbc087e71b8  48 8d a4 24 f8 f6 ff lea    0xfffff6f8(%rsp) -> %rsp
                               ff
 +129  m4 @0x00007fbc087e3908  e8 5b 14 06 80       call   $0x00007fbc8872dd00 %rsp -> %rsp 0xfffffff8(%rsp)[8byte]
 +134  m4 @0x00007fbc087e5e18                       <label>
 +134  m4 @0x00007fbc087e2de0  48 8b 74 24 30       mov    0x30(%rsp)[8byte] -> %rsi
 +139  m4 @0x00007fbc087e3c70  48 bf 37 64 68 cc bc mov    $0x00007fbccc686437 -> %rdi
                               7f 00 00
 +149  m4 @0x00007fbc087e5a18  e8 bb 62 fb 7f       call   $0x00007fbc88682b60 %rsp -> %rsp 0xfffffff8(%rsp)[8byte]
 +154  m4 @0x00007fbc086d5aa8  e8 5b 15 06 80       call   $0x00007fbc8872de00 %rsp -> %rsp 0xfffffff8(%rsp)[8byte]

With save_fpstate = true:

 +121  m4 @0x00007fdaeb5571b8  48 8d a4 24 f8 f6 ff lea    0xfffff6f8(%rsp) -> %rsp
                               ff
 +129  m4 @0x00007fdaeb553908  e8 5b 14 06 80       call   $0x00007fdb6b49dd00 %rsp -> %rsp 0xfffffff8(%rsp)[8byte]
 +134  m4 @0x00007fdaeb555e18  48 8d a4 24 00 fe ff lea    0xfffffe00(%rsp) -> %rsp
                               ff
 +142  m4 @0x00007fdaeb553c70  48 0f ae 04 24       fxsave64  -> (%rsp)[512byte]
 +147  m4 @0x00007fdaeb552de0  db e2                fnclex
 +149  m4 @0x00007fdaeb555a18  9b                   fwait
 +150  m4 @0x00007fdaeb445aa8  db e3                fninit
 +152  m4 @0x00007fdaeb5554d8                       <label>
 +152  m4 @0x00007fdaeb557308  48 8b 74 24 30       mov    0x30(%rsp)[8byte] -> %rsi
 +157  m4 @0x00007fdaeb4408b8  48 bf 37 64 3f af db mov    $0x00007fdbaf3f6437 -> %rdi
                               7f 00 00
 +167  m4 @0x00007fdaeb5584c0  e8 bb 62 fb 7f       call   $0x00007fdb6b3f2b60 %rsp -> %rsp 0xfffffff8(%rsp)[8byte]
 +172  m4 @0x00007fdaeb443b28  48 0f ae 0c 24       fxrstor64 (%rsp)[512byte]
 +177  m4 @0x00007fdaeb555b98  48 8d a4 24 00 02 00 lea    0x00000200(%rsp) -> %rsp
                               00
 +185  m4 @0x00007fdaeb556738  e8 5b 15 06 80       call   $0x00007fdb6b49de00 %rsp -> %rsp 0xfffffff8(%rsp)[8byte]

This is a two-parameter clean-call where the first parameter is an immediate and the second parameter is a register operand. You'll see that in both cases the second parameter is loaded from 0x30(%rsp)[8byte], but in the save_fpstate = true case this offset becomes incorrect due to the adjustment of the stack for the fxsave64 spill.

To Reproduce Steps to reproduce the behavior:

  1. Use dr_insert_clean_call with save_fpstate = true and an opnd_t which specifies a register operand.

Please also answer these questions:

  • What happens when you run without any client? AFAICT, this is a bug in the implementation of a client API
  • What happens when you run with debug build ("-debug" flag to drrun/drconfig/drinject)? Reproduces

Versions

  • What version of DynamoRIO are you using? Fairly recent master
  • What operating system version are you running on? Ubuntu 20.04.1 LTS
  • Is your application 32-bit or 64-bit? 64-bit
Assignee
Assign to
Time tracking