llvm / llvm/llvm-project

Logic bug in debugserver's MachVMMemory::WriteRegion

Open
#217,007 1 comment 0 reactions 1 assignee Claimed by @jasonmolenda View on GitHub
lldb platform:macos
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

https://github.com/llvm/llvm-project/blob/b025f5b75941fcf2e719535473c51b5e0617c4f9/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp#L360

In `lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp`, `m_err` is first set to the result of `mach_vm_write`:

```c++
m_err =
::mach_vm_write(task, curr_addr, (pointer_t)curr_data, curr_data_count);
```

If it failed, there is a log message but the function/loop does not exit:

```c++
if (DNBLogCheckLogBit(LOG_MEMORY) || m_err.Fail())
m_err.LogThreaded("::mach_vm_write ( task = 0x%4.4x, addr = 0x%8.8llx, "
"data = %8.8p, dataCnt = %u )",
task, (uint64_t)curr_addr, curr_data, curr_data_count);
```

Then there is a cache flush that overwrites `m_err`:

```c++
#if !defined(__i386__) && !defined(__x86_64__)
vm_machine_attribute_val_t mattr_value = MATTR_VAL_CACHE_FLUSH;

m_err = ::vm_machine_attribute(task, curr_addr, curr_data_count,
MATTR_CACHE, &mattr_value);
if (DNBLogCheckLogBit(LOG_MEMORY) || m_err.Fail())
m_err.LogThreaded("::vm_machine_attribute ( task = 0x%4.4x, addr = "
"0x%8.8llx, size = %u, attr = MATTR_CACHE, mattr_value "
"=> MATTR_VAL_CACHE_FLUSH )",
task, (uint64_t)curr_addr, curr_data_count);
#endif
```

And finally `m_err` is checked:

```c++
if (m_err.Success()) {
total_bytes_written += curr_data_count;
curr_addr += curr_data_count;
curr_data += curr_data_count;
} else {
break;
}
```

If we are on Arm64 and the write failed but the cache flush did not, this function will act as if the write succeeded.

Found this investigating https://github.com/llvm/llvm-project/pull/216723, but I do not think it's the cause of that problem.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.