Skip to content

Commit 8ac2487

Browse files
authored
Merge pull request #351 from drzewiec/pagerangeinclusive_fix
Fixed overflow bug in PageRangeInclusive
2 parents 33b4c2d + d75d170 commit 8ac2487

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

src/structures/paging/page.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,16 @@ impl<S: PageSize> Iterator for PageRangeInclusive<S> {
380380
fn next(&mut self) -> Option<Self::Item> {
381381
if self.start <= self.end {
382382
let page = self.start;
383-
self.start += 1;
383+
384+
// If the end of the inclusive range is the maximum page possible for size S,
385+
// incrementing start until it is greater than the end will cause an integer overflow.
386+
// So instead, in that case we decrement end rather than incrementing start.
387+
let max_page_addr = VirtAddr::new(u64::MAX) - (S::SIZE - 1);
388+
if self.start.start_address() < max_page_addr {
389+
self.start += 1;
390+
} else {
391+
self.end -= 1;
392+
}
384393
Some(page)
385394
} else {
386395
None
@@ -438,4 +447,23 @@ mod tests {
438447
}
439448
assert_eq!(range_inclusive.next(), None);
440449
}
450+
451+
#[test]
452+
pub fn test_page_range_inclusive_overflow() {
453+
let page_size = Size4KiB::SIZE;
454+
let number = 1000;
455+
456+
let start_addr = VirtAddr::new(u64::MAX).align_down(page_size) - number * page_size;
457+
let start: Page = Page::containing_address(start_addr);
458+
let end = start + number;
459+
460+
let mut range_inclusive = Page::range_inclusive(start, end);
461+
for i in 0..=number {
462+
assert_eq!(
463+
range_inclusive.next(),
464+
Some(Page::containing_address(start_addr + page_size * i))
465+
);
466+
}
467+
assert_eq!(range_inclusive.next(), None);
468+
}
441469
}

0 commit comments

Comments
 (0)