Bug 23230

Summary: Vixie Cron is sensitive to changes in the system clock.
Product: [Retired] Red Hat Linux Reporter: Per Erik Stendahl <pererik>
Component: vixie-cronAssignee: Crutcher Dunnavant <crutcher>
Status: CLOSED RAWHIDE QA Contact: David Lawrence <dkl>
Severity: high Docs Contact:
Priority: medium    
Version: 7.0CC: dr
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-04-10 22:02:40 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Per Erik Stendahl 2001-01-03 14:05:20 UTC
The standard crond on RH6.2 (and RH7.0 ?) is vulnerable to changes in the 
system clock. crond is basically an eternal loop and in each iteration 
crond sleeps for approximately 60 seconds. The exact time is calculated so 
that we catch clock-drifts. Vixie crond uses a variable 'TargetTime' that 
indicates when crond should wake up. The time slept is the number of 
seconds until that time.

The problem is that in each iteration TargetTime is simply increased by 60 
seconds. If the systemclock changes then the change is not reflected in 
TargetTime. This will make crond sleep for an uncorrect number of seconds.

Demonstration: Using 'date', set the systemtime back 1 year. Wait a couple 
of minutes (so that crond has time enter a new sleeping period). Set the 
time back to normal. Watch crond sleep for 1 year without doing anything 
(confirm with strace).

Solution: Calculate TargetTime correctly each iteration. Below is a patch 
that does this. The problem was found in RH6.2 on i386 (vixie-cron-3.0.1-
40). The problem seems to exist in vixie-cron-3.0.1-56 (RH7.0) as well.




--- cron.c	Wed May 31 23:37:20 1995
+++ cron.c.nosync	Wed Jan  3 15:06:29 2001
@@ -113,8 +113,8 @@
 	database.mtime = (time_t) 0;
 	load_database(&database);
 	run_reboot_jobs(&database);
-	cron_sync();
 	while (TRUE) {
+	        cron_sync();
 # if DEBUGGING
 		if (!(DebugFlags & DTEST))
 # endif /*DEBUGGING*/
@@ -125,10 +125,6 @@
 		/* do this iteration
 		 */
 		cron_tick(&database);
-
-		/* sleep 1 minute
-		 */
-		TargetTime += 60;
 	}
 }
 
@@ -205,6 +201,9 @@
  * could then get it to execute a given minute's jobs more than once.
  * instead we have the chance of missing a minute's jobs completely, but
  * that's something sysadmin's know to expect what with crashing 
computers..
+ * 2000-01-03: Change in behaviour. We always do a cron_sync() before
+ *             cron_sleep(). This way we can handle changes to the system
+ *             time.
  */
 static void
 cron_sync() {

Comment 1 Bill Nottingham 2001-01-19 17:41:08 UTC
Thanks for the patch, a variant on this will be in vixie-cron-3.0.1-57.