From 941c50d5ec332eab09de8ffe1344cc76ecddb521 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Mon, 28 Mar 2022 18:07:21 -0700 Subject: [PATCH] gdt: Check that MAX is in range The GDT can have a maxium length of 2^16 bytes, and must contain at least one null descriptor. As `MAX` counts the number of `u64` entries, we must have `0 < MAX <= 2^13`. Unfortunely, we cannot do this check with a `where` clause, as `feature(generic_const_expers)` is not yet stable. However, we can do this check with an `assert!` in `GlobalDescriptorTable::empty()`, which is a `const fn`. Pointed out by @Freax13 in https://github.com/rust-osdev/x86_64/pull/360#discussion_r836788703 Signed-off-by: Joe Richey --- src/structures/gdt.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/structures/gdt.rs b/src/structures/gdt.rs index c30c52adc..8c4ddf7e1 100644 --- a/src/structures/gdt.rs +++ b/src/structures/gdt.rs @@ -64,6 +64,9 @@ impl GlobalDescriptorTable { /// Creates an empty GDT which can hold `MAX` number of [`Descriptor`]s. #[inline] pub const fn empty() -> Self { + // TODO: Replace with compiler error when feature(generic_const_exprs) is stable. + assert!(MAX > 0, "A GDT cannot have 0 entries"); + assert!(MAX <= (1 << 13), "A GDT can only have at most 2^13 entries"); Self { table: [0; MAX], next_free: 1, @@ -184,6 +187,8 @@ impl GlobalDescriptorTable { use core::mem::size_of; super::DescriptorTablePointer { base: crate::VirtAddr::new(self.table.as_ptr() as u64), + // 0 < self.next_free <= MAX <= 2^13, so the limit calculation + // will not underflow or overflow. limit: (self.next_free * size_of::() - 1) as u16, } }