UserVM: Validate the entire range when freeing multiple VM pages
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
631cdd0204
commit
a3d0fa7d0a
@ -100,8 +100,7 @@ Result<void> UserVM::free_several_pages(u64 address, usize count)
|
|||||||
const u64 index = (address - VM_BASE) / ARCH_PAGE_SIZE;
|
const u64 index = (address - VM_BASE) / ARCH_PAGE_SIZE;
|
||||||
if ((index + count) > (MAX_VM_SIZE * 8)) return err(EINVAL);
|
if ((index + count) > (MAX_VM_SIZE * 8)) return err(EINVAL);
|
||||||
|
|
||||||
// FIXME: Is it necessary to check all pages?
|
if (!m_bitmap.match_region(index, count, true)) return err(EFAULT);
|
||||||
if (!m_bitmap.get(index)) return err(EFAULT);
|
|
||||||
|
|
||||||
m_bitmap.clear_region(index, count, false);
|
m_bitmap.clear_region(index, count, false);
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ class Bitmap
|
|||||||
|
|
||||||
Option<usize> find_and_toggle_region(bool value, usize count, usize begin = 0);
|
Option<usize> find_and_toggle_region(bool value, usize count, usize begin = 0);
|
||||||
|
|
||||||
|
bool match_region(usize start, usize bits, bool value);
|
||||||
|
|
||||||
void clear(bool value);
|
void clear(bool value);
|
||||||
void clear_region(usize start, usize bits, bool value);
|
void clear_region(usize start, usize bits, bool value);
|
||||||
|
|
||||||
|
@ -167,3 +167,40 @@ Option<usize> Bitmap::find_and_toggle_region(bool value, usize count, usize begi
|
|||||||
clear_region(index, count, !value);
|
clear_region(index, count, !value);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Bitmap::match_region(usize start, usize bits, bool value)
|
||||||
|
{
|
||||||
|
expect(initialized(), "Bitmap was never initialized");
|
||||||
|
expect((start + bits) <= size(), "Bitmap match out of range");
|
||||||
|
|
||||||
|
if (!bits) return true;
|
||||||
|
|
||||||
|
// Match individual bits while not on a byte boundary.
|
||||||
|
while ((start % 8) && bits)
|
||||||
|
{
|
||||||
|
if (get(start) != value) return false;
|
||||||
|
start++;
|
||||||
|
bits--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match the rest in bytes.
|
||||||
|
usize bytes = bits / 8;
|
||||||
|
const u8 byte_that_contains_only_value = value_byte(value);
|
||||||
|
|
||||||
|
for (usize i = start; i < start + bytes; i += 8)
|
||||||
|
{
|
||||||
|
if (m_location[i / 8] != byte_that_contains_only_value) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
start += bytes * 8;
|
||||||
|
bits -= bytes * 8;
|
||||||
|
|
||||||
|
// Match the remaining individual bits.
|
||||||
|
while (bits--)
|
||||||
|
{
|
||||||
|
if (get(start) != value) return false;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user