mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 10:18:40 +12:00
rsx: Fix memory tagging and add some security checks
This commit is contained in:
parent
987166f4da
commit
247759b75b
1 changed files with 39 additions and 21 deletions
|
@ -660,48 +660,61 @@ namespace rsx
|
||||||
|
|
||||||
void remove_duplicates_fallback_impl(std::vector<surface_overlap_info>& sections, const rsx::address_range& range)
|
void remove_duplicates_fallback_impl(std::vector<surface_overlap_info>& sections, const rsx::address_range& range)
|
||||||
{
|
{
|
||||||
|
// Originally used to debug crashes but this function breaks often enough that I'll leave the checks in for now.
|
||||||
|
// Safe to remove after some time if no asserts are reported.
|
||||||
|
constexpr u32 overrun_cookie_value = 0xCAFEBABEu;
|
||||||
|
|
||||||
// Generic painter's algorithm to detect obsolete sections
|
// Generic painter's algorithm to detect obsolete sections
|
||||||
ensure(range.length() < 64 * 0x100000);
|
ensure(range.length() < 64 * 0x100000);
|
||||||
std::vector<u8> marker(range.length(), 0);
|
std::vector<u8> marker(range.length() + sizeof(overrun_cookie_value), 0);
|
||||||
|
|
||||||
auto compare_and_tag_row = [&](u32 offset, u32 length) -> bool
|
// Tag end
|
||||||
|
u32* overrun_test_ptr = utils::bless<u32>(marker.data() + range.length());
|
||||||
|
*overrun_test_ptr = overrun_cookie_value;
|
||||||
|
|
||||||
|
auto compare_and_tag_row = [&](const u32 offset, u32 length) -> bool
|
||||||
{
|
{
|
||||||
bool valid = false;
|
u64 mask = 0;
|
||||||
for (u32 i = 0; i < (length / 8); ++i, offset += 8, length -= 8)
|
u8* dst_ptr = marker.data() + offset;
|
||||||
|
|
||||||
|
while (length >= 8)
|
||||||
{
|
{
|
||||||
auto dest = reinterpret_cast<u64*>(marker.data() + offset);
|
auto& value = *utils::bless<u64>(dst_ptr);
|
||||||
valid |= (*dest != umax);
|
mask |= (~value); // If the value is not all 1s, set valid to true
|
||||||
*dest = umax;
|
value = umax;
|
||||||
|
|
||||||
|
dst_ptr += 8;
|
||||||
|
length -= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length >= 4)
|
if (length >= 4)
|
||||||
{
|
{
|
||||||
auto dest = reinterpret_cast<u32*>(marker.data() + offset);
|
auto& value = *utils::bless<u32>(dst_ptr);
|
||||||
valid |= (*dest != umax);
|
mask |= (~value);
|
||||||
*dest = umax;
|
value = umax;
|
||||||
|
|
||||||
offset += 4;
|
dst_ptr += 4;
|
||||||
length -= 4;
|
length -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length >= 2)
|
if (length >= 2)
|
||||||
{
|
{
|
||||||
auto dest = reinterpret_cast<u16*>(marker.data() + offset);
|
auto& value = *utils::bless<u16>(dst_ptr);
|
||||||
valid |= (*dest != umax);
|
mask |= (~value);
|
||||||
*dest = umax;
|
value = umax;
|
||||||
|
|
||||||
offset += 2;
|
dst_ptr += 2;
|
||||||
length -= 2;
|
length -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
auto dest = (marker.data() + offset);
|
auto& value = *dst_ptr;
|
||||||
valid |= (*dest != umax);
|
mask |= (~value);
|
||||||
*dest = umax;
|
value = umax;
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid;
|
return !!mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto it = sections.crbegin(); it != sections.crend(); ++it)
|
for (auto it = sections.crbegin(); it != sections.crend(); ++it)
|
||||||
|
@ -750,9 +763,11 @@ namespace rsx
|
||||||
num_rows = utils::aligned_div(this_range.length(), rsx_pitch);
|
num_rows = utils::aligned_div(this_range.length(), rsx_pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 row = 0, offset = (this_range.start - range.start); row < num_rows; ++row, offset += rsx_pitch)
|
for (u32 row = 0, offset = (this_range.start - range.start), section_len = (this_range.end - range.start + 1);
|
||||||
|
row < num_rows;
|
||||||
|
++row, offset += rsx_pitch)
|
||||||
{
|
{
|
||||||
valid |= compare_and_tag_row(offset, std::min<u32>(native_pitch, (this_range.end - offset + 1)));
|
valid |= compare_and_tag_row(offset, std::min<u32>(native_pitch, (section_len - offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid)
|
if (!valid)
|
||||||
|
@ -761,6 +776,9 @@ namespace rsx
|
||||||
invalidate_surface_address(it->base_address, it->is_depth);
|
invalidate_surface_address(it->base_address, it->is_depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify no OOB
|
||||||
|
ensure(*overrun_test_ptr == overrun_cookie_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue