[PATCH] x86/hpet: Add safeguard check for zero channels during init

From: Habil Eren Türker

Date: Fri Sep 25 2026 - 14:26:33 EST


In the event that the BIOS or firmware incorrectly provides a
channels value of 0, the current logic does not perform a
zero-check when CONFIG_HPET_EMULATE_RTC is disabled.

Consequently, kzalloc_objs(*hc, channels) receives a count of 0
and returns ZERO_SIZE_PTR (0x10). Since the pointer is not NULL,
the allocation check if (!hc) fails to catch the error.

Later in the initialization, the for (i = 0; i < channels; i++)
loop is skipped because channels is 0. However, if the condition
(id & HPET_ID_LEGSUP) is true, the code immediately attempts to
write to hpet_base.channels.mode.

Since hpet_base.channels points to ZERO_SIZE_PTR (0x10), this
dereference triggers a page fault and causes a kernel panic.

Furthermore, propagating ZERO_SIZE_PTR through hpet_base.channels
leaves a dangling invalid pointer in the global configuration,
creating potential Use-After-Free (UAF) or undefined behavior
during runtime or cleanup.

Fix this by introducing a safeguard check ensuring that the
channel count is at least 1 when RTC emulation is disabled,
preventing allocation of zero-length arrays.

Signed-off-by: Habil Eren Türker <habilerenturker@xxxxxxxxxxx>
---
arch/x86/kernel/hpet.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 154fe23a1..565127ca9 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -1033,9 +1033,9 @@ int __init hpet_enable(void)

/*
* The legacy routing mode needs at least two channels, tick timer
- * and the rtc emulation channel.
+ * and the rtc emulation channel. Also safeguard against zero channels.
*/
- if (IS_ENABLED(CONFIG_HPET_EMULATE_RTC) && channels < 2)
+ if (channels < (IS_ENABLED(CONFIG_HPET_EMULATE_RTC) ? 2 : 1))
goto out_nohpet;

hc = kzalloc_objs(*hc, channels);
--
2.47.3