memory: validate sparse uploads against the guest address-space owner

This commit is contained in:
nmzik
2026-09-29 20:32:56 +04:00
parent 650dc1e0af
commit f9fd400dbb
3 changed files with 40 additions and 24 deletions
-10
View File
@@ -964,16 +964,6 @@ static bool IsInPrtAperture(uint64_t address, uint64_t size = 1) {
}
bool TryReadSparseBacking(uint64_t vaddr, void* data, uint64_t size) {
std::vector<VirtualRanges::Range> ranges;
if (!g_virtual_ranges->QuerySpan(vaddr, size, &ranges)) {
return false;
}
if (std::any_of(ranges.begin(), ranges.end(), [](const auto& range) {
return !IsReservedRangeType(range.type) &&
!g_guest_address_space->BackingContains(range.start, range.size);
})) {
return false;
}
return g_guest_address_space->TryReadSparseBacking(vaddr, data, size);
}
+17 -3
View File
@@ -220,13 +220,13 @@ public:
const auto bytes = std::min(end, entry.vaddr + entry.size) - start;
const auto offset = entry.backing_offset + start - entry.vaddr;
if (cursor < start) {
std::memset(destination + cursor - vaddr, 0, start - cursor);
std::memset(destination + (cursor - vaddr), 0, start - cursor);
}
std::memcpy(destination + start - vaddr, m_backing_base + offset, bytes);
std::memcpy(destination + (start - vaddr), m_backing_base + offset, bytes);
cursor = start + bytes;
}
if (cursor < end) {
std::memset(destination + cursor - vaddr, 0, end - cursor);
std::memset(destination + (cursor - vaddr), 0, end - cursor);
}
return true;
}
@@ -738,6 +738,20 @@ public:
}
bool TryReadSparseBacking(uint64_t vaddr, void* data, uint64_t size) {
if (!Owns(vaddr, size)) {
return false;
}
std::lock_guard lock(m_mutex);
auto mapping = m_mapped.upper_bound(vaddr);
if (mapping != m_mapped.begin()) {
--mapping;
}
for (; mapping != m_mapped.end() && mapping->second.vaddr < vaddr + size; ++mapping) {
const auto& region = mapping->second;
if (region.type == MappingType::Private && region.vaddr + region.size > vaddr) {
return false;
}
}
return m_backing->TryReadSparseBacking(vaddr, data, size);
}