From 44a6486a4f4b4dff5b781c6e6cb22b65ac7a5373 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 7 Sep 2026 14:11:18 +0200 Subject: [PATCH] x86/vRTC: don't overrun array when storing century field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rtc_ioport_write() has two writes of the new value, yet only one was made aware of the century going outside of the array. Fold both writes by changing the RTC_SET short-circuiting. Fixes: f2ff80877f66 ("x86/vRTC: support century field") Coverity ID: 1700943 Signed-off-by: Jan Beulich Acked-by: Roger Pau Monné --- xen/arch/x86/hvm/rtc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c index 4e0d28d1ea..184e334ee6 100644 --- a/xen/arch/x86/hvm/rtc.c +++ b/xen/arch/x86/hvm/rtc.c @@ -521,20 +521,22 @@ static int rtc_ioport_write(RTCState *s, uint32_t addr, uint32_t data) case RTC_MONTH: case RTC_YEAR: case RTC_CENTURY: - /* if in set mode, just write the register */ - if ( (s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) - s->hw.cmos_data[s->hw.cmos_index] = data; - else + /* If in set mode, just write the register. */ + if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) { /* Fetch the current time and update just this field. */ s->current_tm = gmtime(get_localtime(d)); rtc_copy_date(s); - if ( s->hw.cmos_index != RTC_CENTURY ) - s->hw.cmos_data[s->hw.cmos_index] = data; - else - s->hw.century = data; - rtc_set_time(s); } + + if ( s->hw.cmos_index != RTC_CENTURY ) + s->hw.cmos_data[s->hw.cmos_index] = data; + else + s->hw.century = data; + + if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) + rtc_set_time(s); + alarm_timer_update(s); break; case RTC_REG_A: