lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sun, 17 Oct 2021 21:41:53 +0200 From: Mateusz Jończyk <mat.jonczyk@...pl> To: linux-kernel@...r.kernel.org, linux-rtc@...r.kernel.org Cc: Mateusz Jończyk <mat.jonczyk@...pl>, Alessandro Zummo <a.zummo@...ertech.it>, Alexandre Belloni <alexandre.belloni@...tlin.com> Subject: [TEST PATCH] rtc-cmos: cmos_read_alarm bug demonstration Before my commit "rtc-cmos: dont touch alarm registers during update", applying this patch and reading the CMOS time like so: while true; do cat /sys/class/rtc/rtc0/time ; sleep 0.5; done produces errors in dmesg. Signed-off-by: Mateusz Jończyk <mat.jonczyk@...pl> Cc: Alessandro Zummo <a.zummo@...ertech.it> Cc: Alexandre Belloni <alexandre.belloni@...tlin.com> --- drivers/rtc/rtc-cmos.c | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index f353a41dfe8c..c24465f7bed4 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -43,6 +43,9 @@ #include <linux/dmi.h> #endif +#include <linux/ktime.h> +#include <linux/timekeeping.h> + /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ #include <linux/mc146818rtc.h> @@ -220,6 +223,8 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr) /*----------------------------------------------------------------*/ +static void cmos_read_alarm_uip_debugging(struct device *dev); + static int cmos_read_time(struct device *dev, struct rtc_time *t) { /* @@ -234,6 +239,8 @@ static int cmos_read_time(struct device *dev, struct rtc_time *t) * That'll make Y3K compatility (year > 2070) easy! */ mc146818_get_time(t); + + cmos_read_alarm_uip_debugging(dev); return 0; } @@ -348,6 +355,60 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) return 0; } +static void cmos_read_alarm_uip_debugging(struct device *dev) +{ + unsigned long flags; + unsigned char rtc_uip_baseline, rtc_uip; + struct rtc_wkalrm t_baseline, t; + ktime_t time_start, time_end; + int i; + + spin_lock_irqsave(&rtc_lock, flags); + rtc_uip_baseline = CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP; + spin_unlock_irqrestore(&rtc_lock, flags); + + cmos_read_alarm(dev, &t_baseline); + + time_start = ktime_get(); + + for (i = 0; i < 2000; i++) { + spin_lock_irqsave(&rtc_lock, flags); + rtc_uip = CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP; + spin_unlock_irqrestore(&rtc_lock, flags); + + cmos_read_alarm(dev, &t); + + if (t_baseline.time.tm_sec != t.time.tm_sec) { + dev_err(dev, + "Inconsistent alarm tm_sec value: %d != %d (RTC_UIP = %d; %d)\n", + t_baseline.time.tm_sec, + t.time.tm_sec, + rtc_uip_baseline, rtc_uip); + } + if (t_baseline.time.tm_min != t.time.tm_min) { + dev_err(dev, + "Inconsistent alarm tm_min value: %d != %d (RTC_UIP = %d; %d)\n", + t_baseline.time.tm_min, + t.time.tm_min, + rtc_uip_baseline, rtc_uip); + } + if (t_baseline.time.tm_hour != t.time.tm_hour) { + dev_err(dev, + "Inconsistent alarm tm_hour value: %d != %d (RTC_UIP = %d; %d)\n", + t_baseline.time.tm_hour, + t.time.tm_hour, + rtc_uip_baseline, rtc_uip); + } + + } + + time_end = ktime_get(); + + pr_info_ratelimited("%s: loop executed in %lld ns\n", + __func__, ktime_to_ns(ktime_sub(time_end, time_start))); +} + + static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control) { unsigned char rtc_intr; -- 2.25.1
Powered by blists - more mailing lists