Skip to content

Commit

Permalink
Merge pull request #351 from drzewiec/pagerangeinclusive_fix
Browse files Browse the repository at this point in the history
Fixed overflow bug in PageRangeInclusive
  • Loading branch information
Freax13 authored Mar 18, 2022
2 parents 33b4c2d + d75d170 commit 8ac2487
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion src/structures/paging/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,16 @@ impl<S: PageSize> Iterator for PageRangeInclusive<S> {
fn next(&mut self) -> Option<Self::Item> {
if self.start <= self.end {
let page = self.start;
self.start += 1;

// If the end of the inclusive range is the maximum page possible for size S,
// incrementing start until it is greater than the end will cause an integer overflow.
// So instead, in that case we decrement end rather than incrementing start.
let max_page_addr = VirtAddr::new(u64::MAX) - (S::SIZE - 1);
if self.start.start_address() < max_page_addr {
self.start += 1;
} else {
self.end -= 1;
}
Some(page)
} else {
None
Expand Down Expand Up @@ -438,4 +447,23 @@ mod tests {
}
assert_eq!(range_inclusive.next(), None);
}

#[test]
pub fn test_page_range_inclusive_overflow() {
let page_size = Size4KiB::SIZE;
let number = 1000;

let start_addr = VirtAddr::new(u64::MAX).align_down(page_size) - number * page_size;
let start: Page = Page::containing_address(start_addr);
let end = start + number;

let mut range_inclusive = Page::range_inclusive(start, end);
for i in 0..=number {
assert_eq!(
range_inclusive.next(),
Some(Page::containing_address(start_addr + page_size * i))
);
}
assert_eq!(range_inclusive.next(), None);
}
}

0 comments on commit 8ac2487

Please sign in to comment.