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:   Wed, 15 Feb 2017 17:31:09 +0300
From:   Andrey Drobyshev <immortalguardian1@...il.com>
To:     linux-kernel@...r.kernel.org
Cc:     gq@...msu.su, giometti@...eenne.com
Subject: [PATCH 8/8] LinuxPPS: pps_gen_parport: Add check for bad clocksource.

From: Nikita Edward Baruzdin <nebaruzdin@...il.com>

This commit is supposed to resolve the issue with hard lockups on systems using
jiffies as their clock source. Namely, it sets limits on number of iterations
clock source may remain unchanged (i. e. not being updated for one reason or
another, as it is with jiffies clock source), and on unsuccessful
getnstimeofday() polls as well. In case limit is reached, we consider clock
source incompatible with this driver or unstable.

Considering this issue to be fixed, un-BROKEN pps_gen_parport.

For explanation of the problem see this thread on lkml:
https://lkml.org/lkml/2011/2/18/310

Signed-off-by: Nikita Edward Baruzdin <nebaruzdin@....cs.msu.su>
Signed-off-by: Alexander GQ Gerasiov <gq@...msu.su>
---
 drivers/pps/generators/Kconfig           |  2 +-
 drivers/pps/generators/pps_gen_parport.c | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig
index e4c4f3d..f3a73dd 100644
--- a/drivers/pps/generators/Kconfig
+++ b/drivers/pps/generators/Kconfig
@@ -6,7 +6,7 @@ comment "PPS generators support"
 
 config PPS_GENERATOR_PARPORT
 	tristate "Parallel port PPS signal generator"
-	depends on PARPORT && BROKEN
+	depends on PARPORT
 	help
 	  If you say yes here you get support for a PPS signal generator which
 	  utilizes STROBE pin of a parallel port to send PPS signals. It uses
diff --git a/drivers/pps/generators/pps_gen_parport.c b/drivers/pps/generators/pps_gen_parport.c
index 7739301..bcb53cd 100644
--- a/drivers/pps/generators/pps_gen_parport.c
+++ b/drivers/pps/generators/pps_gen_parport.c
@@ -53,6 +53,13 @@ MODULE_PARM_DESC(polarity,
 	"Signal is on the low level (0 - default) or on the high level (1).");
 module_param(polarity, uint, 0);
 
+static unsigned int failure_iterations = 5;
+MODULE_PARM_DESC(failure_iterations,
+	"Number of iterations the clock source may remain unchanged.");
+module_param(failure_iterations, uint, 0);
+
+#define MAX_GETTIME_ATTEMPTS 100000
+
 #define SAFETY_INTERVAL	3000	/* set the hrtimer earlier for safety (ns) */
 
 /* internal per port structure */
@@ -79,6 +86,7 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
 	struct parport *port;
 	long lim, delta;
 	unsigned long flags;
+	unsigned int i;
 
 	/* We have to disable interrupts here. The idea is to prevent
 	 * other interrupts on the same processor to introduce random
@@ -106,8 +114,18 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
 	}
 
 	/* busy loop until the time is right for an assert edge */
+	i = 0;
 	do {
 		getnstimeofday(&ts2);
+		i++;
+
+		/* Check if there are problems with clock source
+		 * and prevent hard lockups.
+		 */
+		if ((i >= failure_iterations &&
+			ts1.tv_sec  == ts2.tv_sec &&
+			ts1.tv_nsec == ts2.tv_nsec) || i > MAX_GETTIME_ATTEMPTS)
+			goto error;
 	} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
 
 	/* set the signal */
@@ -116,8 +134,17 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
 
 	/* busy loop until the time is right for a clear edge */
 	lim = NSEC_PER_SEC - dev->port_write_time;
+	i = 0;
 	do {
 		getnstimeofday(&ts2);
+		i++;
+
+		/* Check if there are problems with clock source
+		 * and prevent hard lockups.
+		 */
+		if (i > MAX_GETTIME_ATTEMPTS)
+			goto error;
+
 	} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
 
 	/* unset the signal */
@@ -154,6 +181,11 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
 				2 * hrtimer_error)));
 
 	return HRTIMER_RESTART;
+
+error:
+	local_irq_restore(flags);
+	pr_err("Clocksource unstable or not compatible with pps_gen_parport.");
+	return HRTIMER_NORESTART;
 }
 
 /* calibrate port write time */
-- 
2.1.4

Powered by blists - more mailing lists