diff options
| author | Jim Ingham <jingham@apple.com> | 2019-12-20 11:00:11 -0800 |
|---|---|---|
| committer | Jim Ingham <jingham@apple.com> | 2019-12-20 11:02:24 -0800 |
| commit | 2a42a5a2f4144cd99812ad0d230480f94a1d1c92 (patch) | |
| tree | d4b33c08279563782d568724e1b8f77152c61cd5 /lldb/source/Target | |
| parent | 42f9d0c0bee32a1a48a45c039988d27115f30da9 (diff) | |
| download | bcm5719-llvm-2a42a5a2f4144cd99812ad0d230480f94a1d1c92.tar.gz bcm5719-llvm-2a42a5a2f4144cd99812ad0d230480f94a1d1c92.zip | |
In 'thread step-out' command, only insert a breakpoint in executable memory.
Previously, if the current function had a nonstandard stack layout/ABI, and had a valid
data pointer in the location where the return address is usually located, data corruption
would occur when the breakpoint was written. This could lead to an incorrectly reported
crash or silent corruption of the program's state. Now, if the above check fails, the command safely aborts.
Differential Revision: https://reviews.llvm.org/D71372
Diffstat (limited to 'lldb/source/Target')
| -rw-r--r-- | lldb/source/Target/ThreadPlanStepOut.cpp | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp index d7dae446b22..f15a343aaa3 100644 --- a/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/lldb/source/Target/ThreadPlanStepOut.cpp @@ -126,6 +126,25 @@ ThreadPlanStepOut::ThreadPlanStepOut( if (m_return_addr == LLDB_INVALID_ADDRESS) return; + // Perform some additional validation on the return address. + uint32_t permissions = 0; + if (!m_thread.GetProcess()->GetLoadAddressPermissions(m_return_addr, + permissions)) { + m_constructor_errors.Printf("Return address (0x%" PRIx64 + ") permissions not found.", + m_return_addr); + LLDB_LOGF(log, "ThreadPlanStepOut(%p): %s", static_cast<void *>(this), + m_constructor_errors.GetData()); + return; + } else if (!(permissions & ePermissionsExecutable)) { + m_constructor_errors.Printf("Return address (0x%" PRIx64 + ") did not point to executable memory.", + m_return_addr); + LLDB_LOGF(log, "ThreadPlanStepOut(%p): %s", static_cast<void *>(this), + m_constructor_errors.GetData()); + return; + } + Breakpoint *return_bp = m_thread.CalculateTarget() ->CreateBreakpoint(m_return_addr, true, false) .get(); @@ -238,8 +257,13 @@ bool ThreadPlanStepOut::ValidatePlan(Stream *error) { } if (m_return_bp_id == LLDB_INVALID_BREAK_ID) { - if (error) + if (error) { error->PutCString("Could not create return address breakpoint."); + if (m_constructor_errors.GetSize() > 0) { + error->PutCString(" "); + error->PutCString(m_constructor_errors.GetString()); + } + } return false; } |

