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  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 9 Sep 2016 16:33:59 +0200 (CEST)
From:   Thomas Gleixner <tglx@...utronix.de>
To:     Chen Yu <yu.c.chen@...el.com>
cc:     "Rafael J. Wysocki" <rjw@...ysocki.net>, x86@...nel.org,
        John Stultz <john.stultz@...aro.org>,
        Ingo Molnar <mingo@...hat.com>,
        "H. Peter Anvin" <hpa@...or.com>, linux-kernel@...r.kernel.org,
        Xunlei Pang <xlpang@...hat.com>,
        "Zhang, Rui" <rui.zhang@...el.com>, linux-pm@...r.kernel.org
Subject: Re: [PATCH][RFC v5] timekeeping: Ignore the bogus sleep time if
 pm_trace is enabled

On Fri, 9 Sep 2016, Chen Yu wrote:
> > I really have no idea why this is burried in x86 land. The pm_trace hackery
> > issues mc146818_set_time() to fiddle with the RTC. So any implementation of
> > this is affected.
> OK, I've changed this patch according to this suggestion.

No you did not! You still have that silly x86 hackery in place.
 
> OK. I've moved most of the logic into the pm_trace component,
> Once the mc146818_set_time has modified the RTC by pm_trace,
> related flags will be set which indicates the unusable of RTC.
> And timekeeping system is able to query these flags to decide whether
> it should inject the sleep time. (We tried to make this patch as
> simple as possible, but it looks like we have to deal with persistent
> clock for x86, which makes this patch a little more complicated).
> Here's the trial version of it, any suggestion would be appreciated:

It's overengineered and horrible.
 
> +unsigned int timekeeping_tainted;

It does not taint timekeeping. It just wreckages the RTC.

> +void pm_trace_taint_timekeeping(void)
> +{
> +	if (pm_trace_is_enabled()) {
> +		timekeeping_tainted |= TIMEKEEPING_RTC_TAINTED;
> +		if (arch_pm_trace_taint_pclock())
> +			timekeeping_tainted |= TIMEKEEPING_PERSISTENT_CLOCK_TAINTED;
> +	}

Why would you need all these flags?

> +static inline int pm_trace_rtc_is_tainted(void)
> +{
> +	return (timekeeping_tainted & TIMEKEEPING_RTC_TAINTED) ?
> +		1 : 0;

ever heard about bool?

> +}
> +

> +extern void pm_trace_untaint_timekeeping(void);

And how exactly do you untaint it? Just by clearing the flags. That makes
the RTC time magically correct again?

> +int arch_pm_trace_taint_pclock(void)
> +{
> +	return (x86_platform.get_wallclock == mach_get_cmos_time);
> +}

Groan. I told you to do it in the mc14xxx related places. There are not
that many in the kernel

Here is a completely uncompiled/untested patch which should address the
issue in a halfways clean way.

Thanks,

	tglx

--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -64,6 +64,15 @@ void mach_get_cmos_time(struct timespec
 	unsigned int status, year, mon, day, hour, min, sec, century = 0;
 	unsigned long flags;
 
+	/*
+	 * If pm trace abused the RTC as storage set the timespec to 0
+	 * which tells the caller that this RTC value is bogus.
+	 */
+	if (!pm_trace_rtc_valid()) {
+		now->tv_sec = now->tv_nsec = 0;
+		return;
+	}
+
 	spin_lock_irqsave(&rtc_lock, flags);
 
 	/*
--- a/drivers/base/power/trace.c
+++ b/drivers/base/power/trace.c
@@ -74,6 +74,7 @@
 
 #define DEVSEED (7919)
 
+bool pm_trace_rtc_abused __read_mostly;
 static unsigned int dev_hash_value;
 
 static int set_magic_time(unsigned int user, unsigned int file, unsigned int device)
@@ -104,6 +105,7 @@ static int set_magic_time(unsigned int u
 	time.tm_min = (n % 20) * 3;
 	n /= 20;
 	mc146818_set_time(&time);
+	pm_trace_rtc_abused = true;
 	return n ? -1 : 0;
 }
 
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -189,6 +189,13 @@ static inline void cmos_write_bank2(unsi
 
 static int cmos_read_time(struct device *dev, struct rtc_time *t)
 {
+	/*
+	 * If pmtrace abused the RTC for storage tell the caller that it is
+	 * unusable.
+	 */
+	if (!pm_trace_rtc_valid())
+		return -EIO;
+
 	/* REVISIT:  if the clock has a "century" register, use
 	 * that instead of the heuristic in mc146818_get_time().
 	 * That'll make Y3K compatility (year > 2070) easy!
--- a/include/linux/mc146818rtc.h
+++ b/include/linux/mc146818rtc.h
@@ -16,6 +16,7 @@
 #include <asm/mc146818rtc.h>		/* register access macros */
 #include <linux/bcd.h>
 #include <linux/delay.h>
+#include <linux/pm-trace.h>
 
 #ifdef __KERNEL__
 #include <linux/spinlock.h>		/* spinlock_t */
--- a/include/linux/pm-trace.h
+++ b/include/linux/pm-trace.h
@@ -6,6 +6,12 @@
 #include <linux/types.h>
 
 extern int pm_trace_enabled;
+extern bool pm_trace_rtc_abused;
+
+static inline bool pm_trace_rtc_valid(void)
+{
+	return !pm_trace_rtc_abused;
+}
 
 static inline int pm_trace_is_enabled(void)
 {
@@ -24,6 +30,7 @@ extern int show_trace_dev_match(char *bu
 
 #else
 
+static inline bool pm_trace_rtc_valid(void) { return true; }
 static inline int pm_trace_is_enabled(void) { return 0; }
 
 #define TRACE_DEVICE(dev) do { } while (0)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ