[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#925250: marked as done (unblock: cron/3.0pl1-133)



Your message dated Sat, 6 Apr 2019 13:08:33 +0200
with message-id <20190406110830.uexlhfxlgxu4atjg@debian.org>
and subject line Re: unblock: cron/3.0pl1-133
has caused the Debian Bug report #925250,
regarding unblock: cron/3.0pl1-133
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
925250: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=925250
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Dear Release Team,

I'd like to request an unblock for cron/3.0pl1-133. The notable changes
are smallish, and mainly concern security fixes that have been assigned
CVE-2019-9704, -9705, and -9706 in the meantime. One of these fixes
(limiting crontabs to 1000 lines) required a debian/NEWS entry.

However, there are a number of insignificant changes that make the
debdiff quite large. I pushed these without pre-approval because I
erroneously assumed that anything uploaded before the hard freeze may
still transition in 10 days without explicit unblock, and because, well,
they are insignificant.

A great deal of these changes are trivial (eg man page fixes) or
completely irrelevant (eg whitespace fixes). It may sound odd to push
irrelevant changes, but I needed for the upcoming conversion to source
format 3.0 (quilt), which I'd like to see in stretch. This conversion is
greatly facilitated by reducing the diff to the original upstream, and
reducing the accumulated noise so far. (with close to 70 patches, any
reduction in noise counts greatly...)

I've attached a debdiff -w, and a debdiff -w --exclude {MANPAGES}, but
offer the following comments on all commits affecting this release as a
guide:

Notable changes (all documented in d/changelog):
  Security:
    https://salsa.debian.org/debian/cron/commit/13d44ca
    https://salsa.debian.org/debian/cron/commit/40791b9
    https://salsa.debian.org/debian/cron/commit/f252556
    https://salsa.debian.org/debian/cron/commit/26814a2
  Add NEWS entry crontab line limit:
    https://salsa.debian.org/debian/cron/commit/70c6730
  Move crond.reboot from /var/run to /run
    https://salsa.debian.org/debian/cron/commit/0222c88
    https://salsa.debian.org/debian/cron/commit/8beb02d
  Man page fixes:
    https://salsa.debian.org/debian/cron/commit/9853021
    https://salsa.debian.org/debian/cron/commit/286dde8
    https://salsa.debian.org/debian/cron/commit/90a23a4
  Fix the daemon 'x' option:
    https://salsa.debian.org/debian/cron/commit/39591a2

Whitespace cleanups
    https://salsa.debian.org/debian/cron/commit/6b28e6a
    https://salsa.debian.org/debian/cron/commit/56d0c88
Trivial changes (commit messages elaborate)
    https://salsa.debian.org/debian/cron/commit/391cc96
    https://salsa.debian.org/debian/cron/commit/2eeba30
    https://salsa.debian.org/debian/cron/commit/d7d3153
    https://salsa.debian.org/debian/cron/commit/867936d
    https://salsa.debian.org/debian/cron/commit/d7d3153
    https://salsa.debian.org/debian/cron/commit/55fa0e6
    https://salsa.debian.org/debian/cron/commit/f521ca9
    https://salsa.debian.org/debian/cron/commit/45fa23e

With regards to the security fixes, uploads for jessie and stretch are
being or have been prepared.

Regards,
Christian

unblock cron/3.0pl1-133
diff -wu cron-3.0pl1/Makefile cron-3.0pl1/Makefile
--- cron-3.0pl1/Makefile
+++ cron-3.0pl1/Makefile
@@ -57,8 +57,8 @@
 #<<need getopt()>>
 LIBS		= $(PAM_LIBS) $(SELINUX_LIBS) $(AUDIT_LIBS)
 #<<optimize or debug?>>
-OPTIM		=	-O2
-#OPTIM		=	-g
+#OPTIM		=	-O
+OPTIM		=	-g
 #<<ATT or BSD or POSIX?>>
 # (ATT untested)
 #COMPAT		=	-DATT
@@ -73,17 +73,14 @@
 #<<manifest defines>>
 # Allow override from command line
 DEBUG_DEFS  ?= -DDEBUGGING=0   
-# The -DUSE_SIGCHLD is needed for the Alpha port
-DEFS = -DDEBIAN -DUSE_SIGCHLD $(DEBUG_DEFS) $(PAM_DEFS) $(SELINUX_DEFS) $(AUDIT_DEFS)
+DEFS		= $(DEBUG_DEFS) $(PAM_DEFS) $(SELINUX_DEFS) $(AUDIT_DEFS)
 #(SGI IRIX systems need this)
 #DEFS		=	-D_BSD_SIGNALS -Dconst=
 #<<the name of the BSD-like install program>>
 #INSTALL = installbsd
-INSTALL = install -s
+INSTALL = install
 #<<any special load flags>>
-# LDFLAGS		=	-s
-# Let install do the strip
-
+#LDFLAGS		=
 #################################### end configurable stuff
 
 SHELL		=	/bin/sh
diff -wu cron-3.0pl1/compat.h cron-3.0pl1/compat.h
--- cron-3.0pl1/compat.h
+++ cron-3.0pl1/compat.h
@@ -62,8 +62,8 @@
 #endif
 
 #ifndef POSIX
-# if (BSD >= 199103) || defined(__linux__) || defined(__GNU__) || defined(ultrix) ||\
-        defined(AIX) ||\ defined(HPUX) || defined(CONVEX) || defined(IRIX) || defined(__GLIBC__)
+# if (BSD >= 199103) || defined(__linux__) || defined(ultrix) || defined(AIX) ||\
+	defined(HPUX) || defined(CONVEX) || defined(IRIX)
 #  define POSIX
 # endif
 #endif
@@ -76,17 +76,17 @@
 
 /*****************************************************************/
 
-#if !defined(BSD) && !defined(HPUX) && !defined(CONVEX) && !defined(__linux__) && !defined(__GNU__)
+#if !defined(BSD) && !defined(HPUX) && !defined(CONVEX) && !defined(__linux__) && !defined(__GLIBC__)
 # define NEED_VFORK
 #endif
 
 #if (!defined(BSD) || (BSD < 198902)) && !defined(__linux__) && \
-	!defined(IRIX) && !defined(NeXT) && !defined(HPUX) && !defined(__GNU__) && !defined(__GLIBC__)
+	!defined(IRIX) && !defined(NeXT) && !defined(HPUX) && !defined(__GLIBC__)
 # define NEED_STRCASECMP
 #endif
 
 #if (!defined(BSD) || (BSD < 198911)) && !defined(__linux__) &&\
-	!defined(IRIX) && !defined(UNICOS) && !defined(HPUX) && !defined(__GNU__) && !defined(__GLIBC__)
+	!defined(IRIX) && !defined(UNICOS) && !defined(HPUX) && !defined(__GLIBC__)
 # define NEED_STRDUP
 #endif
 
@@ -102,7 +102,7 @@
 # define NEED_SETSID
 #endif
 
-#if (defined(POSIX) && !defined(BSD)) && !defined(__linux__) && !defined(__GNU__) && !defined(__GLIBC__)
+#if (defined(POSIX) && !defined(BSD)) && !defined(__linux__) && !defined(__GLIBC__)
 # define NEED_GETDTABLESIZE
 #endif
 
@@ -110,11 +110,11 @@
 # define HAVE_SAVED_UIDS
 #endif
 
-#if !defined(ATT) && !defined(__linux__) && !defined(__GNU__) && !defined(IRIX) && !defined(UNICOS) && !defined(__GLIBC__)
+#if (!defined(ATT) && !defined(IRIX) && !defined(UNICOS)) || defined(POSIX)
 # define USE_SIGCHLD
 #endif
 
-#if !defined(AIX) && !defined(UNICOS) && !defined(DEBIAN)
+#if !defined(AIX) && !defined(UNICOS) && !defined(POSIX)
 # define SYS_TIME_H 1
 #else
 # define SYS_TIME_H 0
diff -wu cron-3.0pl1/config.h cron-3.0pl1/config.h
--- cron-3.0pl1/config.h
+++ cron-3.0pl1/config.h
@@ -43,10 +43,10 @@
 			 */
 
 #define MAILCMD _PATH_SENDMAIL					/*-*/
-/* #define MAILARGS "%s -i -FCronDaemon -odi -oem  %s"		/*-*/
-#define MAILARGS "%s -i -FCronDaemon -B8BITMIME -oem  %s"		/*-*/
-			/* -i    = don't terminate on "." by itself
-                         * -Fx	 = set full-name of sender
+#define MAILARGS "%s -FCronDaemon -i -B8BITMIME -oem  %s"	/*-*/
+			/* -Fx	 = set full-name of sender
+			 * -i    = don't terminate on "." by itself
+			 * -B8BITMIME = 8-bit processing
 			 * -odi	 = Option Deliverymode Interactive
 			 * -oem	 = Option Errors Mailedtosender
  			 * -t    = read recipient from header of message
@@ -55,15 +55,15 @@
 			 * by joe user.  --okir
 			 */
 
-/* #define MAILCMD "/bin/mail"			-*/
-/* #define MAILARGS "%s -d  %s"			-*/
+/* #define MAILCMD "/bin/mail"			/*-*/
+/* #define MAILARGS "%s -d  %s"			/*-*/
 			/* -d = undocumented but common flag: deliver locally?
 			 */
 
-/* #define MAILCMD "/usr/mmdf/bin/submit"	-*/
-/* #define MAILARGS "%s -mlrxto %s"		-*/
+/* #define MAILCMD "/usr/mmdf/bin/submit"	/*-*/
+/* #define MAILARGS "%s -mlrxto %s"		/*-*/
 
-/* #define MAIL_DATE				-*/
+/* #define MAIL_DATE				/*-*/
 			/* should we include an ersatz Date: header in
 			 * generated mail?  if you are using sendmail
 			 * for MAILCMD, it is better to let sendmail
@@ -74,7 +74,7 @@
 			 * defined but neither exists, should crontab(1) be
 			 * usable only by root?
 			 */
-/*#define ALLOW_ONLY_ROOT			-*/
+/*#define ALLOW_ONLY_ROOT			/*-*/
 
 			/* if you want to use syslog(3) instead of appending
 			 * to CRONDIR/LOG_FILE (/var/cron/log, e.g.), define
diff -wu cron-3.0pl1/cron.8 cron-3.0pl1/cron.8
--- cron-3.0pl1/cron.8
+++ cron-3.0pl1/cron.8
@@ -23,9 +23,9 @@
 cron \- daemon to execute scheduled commands (Vixie Cron)
 .SH SYNOPSIS
 cron
-.RB [ -f ]
-.RB [ -l ]
-.RB [ -L
+.RB [ \-f ]
+.RB [ \-l ]
+.RB [ \-L
 .IR loglevel ]
 .SH DESCRIPTION
 .I cron
@@ -33,19 +33,19 @@
 runlevels.
 .SH OPTIONS
 .TP 8
-.B -f
+.B \-f
 Stay in foreground mode, don't daemonize.
 .TP
-.B -l
+.B \-l
 Enable LSB compliant names for /etc/cron.d files. This setting, however, does
 not affect the parsing of files under /etc/cron.hourly, /etc/cron.daily,
 /etc/cron.weekly or /etc/cron.monthly.
 .TP
-.B -n
+.B \-n
 Include the FQDN in the subject when sending mails. By default, cron will
 abbreviate the hostname.
 .TP
-.B -L loglevel 
+.B \-L loglevel
 Tell cron what to log about \fBjobs\fR (errors are logged regardless of this
 value) as the sum of the following values:
 .br
@@ -60,9 +60,11 @@
 will log the process number of all cron jobs
 .RE
 .IP
-The default is to log the start of all jobs (1). Logging will be disabled
-if \fIlevels\fR is set to zero (0). A value of fifteen (15) will select all
-options.
+The default is to log the start of all jobs (1).
+Logging will be disabled if
+.I levels
+is set to zero (0).
+A value of fifteen (15) will select all options.
 .SH NOTES
 .PP
 .I cron
@@ -88,8 +90,9 @@
 .I cron
 reads the files in the /etc/cron.d directory.
 .I cron
-treats the files in /etc/cron.d as in the same way as the /etc/crontab file (they
-follow the special format of that file, i.e. they include the 
+treats the files in /etc/cron.d as in the same way as the /etc/crontab
+file (they follow the special format of that file,
+i.e.\& they include the
 .I user
 field). However, they are independent of /etc/crontab: they do not, for 
 example, inherit environment variable settings from it. This change is
@@ -98,7 +101,8 @@
 below.
 
 Like /etc/crontab, the files in the /etc/cron.d directory are
-monitored for changes. In general, the system administrator should not use /etc/cron.d/,
+monitored for changes.
+In general, the system administrator should not use /etc/cron.d/,
 but use the standard system crontab /etc/crontab.
 
 /etc/crontab and the files in /etc/cron.d must be owned by root, and must not
@@ -127,11 +131,11 @@
 .I cron
 checks each minute to see if its spool directory's modtime (or the modtime
 on the 
-.IR /etc/crontab
+.I /etc/crontab
 file)
 has changed, and if it has,
 .I cron
-will then examine the modtime on all crontabs files and reload those which have
+will then examine the modtime on all crontabs and reload those which have
 changed.  Thus
 .I cron
 need not be restarted whenever a crontab file is modified.  Note that the
@@ -177,8 +181,7 @@
 .B NOT
 affect the environment of tasks running under cron. For more information
 on how to modify the environment of tasks, consult 
-.IR crontab(5)
-\.
+.IR crontab (5).
 .PP
 The daemon will use, if present, the definition from
 .I /etc/timezone
@@ -224,7 +227,8 @@
 The default system-wide crontab contains four tasks: run every hour, every
 day, every week and every month. Each of these tasks will execute 
 .B run-parts
-providing each one of the directories as an argument. These tasks are disabled if
+providing each one of the directories as an argument.
+These tasks are disabled if
 .B anacron 
 is installed (except for the hourly task) to prevent conflicts between
 both daemons.
@@ -242,8 +246,8 @@
 For example, any file containing dots will be ignored.
 This is done to prevent cron from running any of the files
 that are left by the Debian package management system when handling files in
-/etc/cron.d/ as configuration files (i.e. files ending in .dpkg-dist, .dpkg-orig, 
-and .dpkg-new).
+/etc/cron.d/ as configuration files (i.e.\& files ending in
+\&.dpkg-dist, \&.dpkg-orig, and \&.dpkg-new).
 
 This feature can be used by system administrators and packages to include
 tasks that will be run at defined intervals. Files created by packages in these
@@ -254,31 +258,31 @@
 .I cron 
 daemon itself, which handles this location as the system-wide crontab spool.
 This directory can contain any file defining tasks following the format
-used in /etc/crontab, i.e. unlike the user cron spool, these files must
+used in /etc/crontab, i.e.\& unlike the user cron spool, these files must
 provide the username to run the task as in the task definition.
 
 Files in this directory have to be owned by root, do not need to be executable
 (they are configuration files, just like /etc/crontab) and 
 must conform to the same naming convention as used by 
-.IR run-parts(8) :
+.IR run-parts "(8) :"
 they
 must consist solely of upper- and lower-case letters, digits, underscores,
 and hyphens. This means that they 
 .B cannot
 contain any dots. 
 If the 
-.B -l
+.B \-l
 option is specified to 
 .I cron
 (this option can be setup through /etc/default/cron, see below), then they must
 conform to the LSB namespace specification, exactly as in the
-.B --lsbsysinit
+.B \-\-lsbsysinit
 option in 
 .IR run-parts .
 
-The intended purpose
-of this feature is to allow packages that require
-finer control of their scheduling than the /etc/cron.{hourly,daily,weekly,monthly} 
+The intended purpose of this feature is to allow packages that require
+finer control of their scheduling than the
+/etc/cron.{hourly,daily,weekly,monthly}
 directories to add a crontab file to /etc/cron.d. Such files
 should be named after the package that supplies them.
 
diff -wu cron-3.0pl1/cron.c cron-3.0pl1/cron.c
--- cron-3.0pl1/cron.c
+++ cron-3.0pl1/cron.c
@@ -26,6 +26,7 @@
 #include "cron.h"
 #include <signal.h>
 
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <libgen.h>
@@ -49,8 +50,9 @@
 	char **dflags;
 
 	fprintf(stderr, "usage:  %s [-x [", ProgramName);
-	for(dflags = DebugFlagNames; *dflags; dflags++)
+	for (dflags = DebugFlagNames; *dflags; dflags++) {
 		fprintf(stderr, "%s%s", *dflags, dflags[1] ? "," : "]");
+	}
 	fprintf(stderr, "]\n");
 #else
 	fprintf(stderr, "usage: %s\n", ProgramName);
@@ -83,9 +85,6 @@
 #endif
 	(void) signal(SIGHUP, sighup_handler);
 
-        /* Reopen stdin in case some idiot closed it before starting
-           us - it will only be closed, but not having it open here
-           screws up other things that will be opened */
         if (fdopen(0,"r") == NULL) {
             (void) open("dev/null", 0);
         }
@@ -145,11 +144,8 @@
 	database.tail = NULL;
 	database.sys_mtime = (time_t) 0;
 	database.user_mtime = (time_t) 0;
-#ifdef DEBIAN
 	database.sysd_mtime = (time_t) 0;
-#endif
 	load_database(&database);
-
 	set_time(TRUE);
 	run_reboot_jobs(&database);
 	timeRunning = virtualTime = clockTime;
@@ -273,10 +269,6 @@
 	}
 }
 
-#ifdef DEBIAN
-#include <sys/stat.h>
-#include <fcntl.h>
-#endif
 
 static void
 run_reboot_jobs(db)
@@ -285,8 +277,7 @@
 	register user		*u;
 	register entry		*e;
     int rbfd;
-#ifdef DEBIAN
-#define REBOOT_FILE "/var/run/crond.reboot"
+
 	/* Run on actual reboot, rather than cron restart */
 	if (access(REBOOT_FILE, F_OK) == 0) {
 	        /* File exists, return */
@@ -303,12 +294,7 @@
 		close(rbfd);
 		log_it("CRON", getpid(),"INFO", "Running @reboot jobs");
 	}
-      
-
-        Debug(DMISC, ("[%d], Debian running reboot jobs\n",getpid()));
-    
-#endif
-        Debug(DMISC, ("[%d], vixie running reboot jobs\n", getpid()));
+	Debug(DMISC, ("[%d], running reboot jobs\n", getpid()));
 	for (u = db->head;  u != NULL;  u = u->next) {
 		for (e = u->crontab;  e != NULL;  e = e->next) {
 			if (e->flags & WHEN_REBOOT) {
@@ -418,7 +404,7 @@
 
 #ifdef USE_SIGCHLD
 static void
-sigchld_handler(x) {
+sigchld_handler(int x) {
 	int save_errno = errno;
 	WAIT_T		waiter;
 	PID_T		pid;
@@ -452,7 +438,7 @@
 
 
 static void
-sighup_handler(x) {
+sighup_handler(int x) {
 	log_close();
 
 	/* we should use sigaction for proper signal blocking as this 
@@ -461,6 +447,12 @@
 }
 
 
+#if DEBUGGING
+const char *getoptarg = "flL:nx:";
+#else
+const char *getoptarg = "flL:n";
+#endif
+
 static void
 parse_args(argc, argv)
 	int	argc;
@@ -468,31 +460,33 @@
 {
 	int	argch;
 
-	log_level = 1;
 	stay_foreground = 0;
         lsbsysinit_mode = 0;
+	log_level = 1;
         fqdn_in_subject = 0;
 
-	while (EOF != (argch = getopt(argc, argv, "lfnx:L:"))) {
+	while (EOF != (argch = getopt(argc, argv, getoptarg))) {
 		switch (argch) {
 		default:
 			usage();
 		case 'f':
 			stay_foreground = 1;
 			break;
-		case 'x':
-			if (!set_debug_flags(optarg))
-				usage();
-			break;
 		case 'l':
 			lsbsysinit_mode = 1;
 			break;
+		case 'L':
+			log_level = atoi(optarg);
+			break;
 		case 'n':
 			fqdn_in_subject = 1;
 			break;
-		case 'L':
-			log_level = atoi(optarg);
+#if DEBUGGING
+		case 'x':
+			if (!set_debug_flags(optarg))
+				usage();
 			break;
+#endif
 		}
 	}
 }
diff -wu cron-3.0pl1/cron.h cron-3.0pl1/cron.h
--- cron-3.0pl1/cron.h
+++ cron-3.0pl1/cron.h
@@ -82,6 +82,7 @@
 #define	MAX_COMMAND	1000	/* max length of internally generated cmd */
 #define	MAX_TEMPSTR	1000	/* max length of envvar=value\0 strings */
 #define	MAX_ENVSTR	MAX_TEMPSTR	/* DO NOT change - buffer overruns otherwise */
+#define MAX_TAB_LINES	1000	/* max length of crontabs */
 #define	MAX_UNAME	20	/* max length of username, should be overkill */
 #define	ROOT_UID	0	/* don't change this, it really must be root */
 #define	ROOT_USER	"root"	/* ditto */
@@ -101,6 +102,7 @@
 #define	CRON_TAB(u)	"%s/%s", SPOOL_DIR, u
 #define	REG		register
 #define	PPC_NULL	((char **)NULL)
+#define NHEADER_LINES   3
 
 #ifndef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN 64
@@ -126,6 +128,8 @@
 			;
 #endif /* DEBUGGING */
 
+#define Stringify_(x)	#x
+#define Stringify(x)	Stringify_(x)
 #define	MkLower(ch)	(isupper(ch) ? tolower(ch) : ch)
 #define	MkUpper(ch)	(islower(ch) ? toupper(ch) : ch)
 #define	Set_LineNum(ln)	{Debug(DPARS|DEXT,("linenum=%d\n",ln)); \
@@ -209,9 +213,7 @@
 	user		*head, *tail;	/* links */
 	time_t		user_mtime;     /* last modtime on spooldir */
 	time_t		sys_mtime;      /* last modtime on system crontab */
-#ifdef DEBIAN
 	time_t		sysd_mtime;     /* last modtime on system crondir */
-#endif
 } cron_db;
 
 typedef struct _orphan {
@@ -263,7 +265,7 @@
 		**env_set __P((char **, char *));
 
 user		*load_user __P((int, struct passwd *, char *, char *, char *)),
-		*find_user __P((cron_db *, char *));
+		*find_user __P((cron_db *, const char *));
 
 entry		*load_entry __P((FILE *, void (*)(),
 				 struct passwd *, char **));
@@ -305,8 +307,9 @@
 
 int	stay_foreground;
 int     lsbsysinit_mode;
+int	log_level;
 int     fqdn_in_subject;
-int     log_level = 1;
+
 char    cron_default_mail_charset[MAX_ENVSTR] = "";
 
 # if DEBUGGING
@@ -322,8 +325,8 @@
 		*DowNames[],
 		*ProgramName;
 extern  int     lsbsysinit_mode;
-extern  int     fqdn_in_subject;
 extern  int     log_level;
+extern	int	fqdn_in_subject;
 extern	int	LineNumber;
 extern	time_t	StartTime;
 extern  time_min timeRunning;
diff -wu cron-3.0pl1/crontab.1 cron-3.0pl1/crontab.1
--- cron-3.0pl1/crontab.1
+++ cron-3.0pl1/crontab.1
@@ -133,6 +133,14 @@
 /var/spool/cron/crontabs
 .fi
 .PP
+The files
+.I /etc/cron.allow
+and
+.I /etc/cron.deny
+if, they exist, must be either world-readable, or readable by group
+``crontab''. If they are not, then cron will deny access to all users until the
+permissions are fixed.
+.PP
 There is one file for each user's crontab under the /var/spool/cron/crontabs
 directory.  Users are not allowed to edit the files under that directory
 directly to ensure that only users allowed by the system to run periodic tasks
@@ -157,7 +165,6 @@
 last entry in a crontab is missing the newline, cron will consider the crontab
 (at least partially) broken and refuse to install it.
 
-.SH DIAGNOSTICS
 The files under
 .I
 /var/spool/cron/crontabs
diff -wu cron-3.0pl1/crontab.5 cron-3.0pl1/crontab.5
--- cron-3.0pl1/crontab.5
+++ cron-3.0pl1/crontab.5
@@ -44,7 +44,9 @@
 settings will affect only the cron commands below them in the file.
 An environment setting is of the form,
 .PP
+.in +4n
     name = value
+.in
 .PP
 where the spaces around the equal-sign (=) are optional, and any subsequent
 non-leading spaces in
@@ -56,32 +58,35 @@
 string may be placed in quotes (single or double, but matching) to preserve
 leading or trailing blanks. To define an empty variable, quotes
 .B must
-be used. The  
+be used.
+.PP
+The
 .I value
 string is 
 .B not
-parsed for environmental substitutions or replacement of variables, thus lines
-like
+parsed for environmental substitutions or replacement of variables or
+tilde(~) expansion, thus lines like
 .PP
+.in +4n
+.nf
     PATH = $HOME/bin:$PATH
+PATH = ~/bin:/usr/bin:/bin
+.fi
+.in
 .PP
 will not work as you might expect. And neither will this work
 .PP
+.in +4n
+.nf
     A=1
     B=2
     C=$A $B
+.fi
+.in
 .PP
 There will not be any substitution for the defined variables in the
 last value.
 .PP
-An alternative for setting up the commands path is using the fact that
-many shells will treat the tilde(~) as substitution of $HOME, so if you use 
-.I bash
-for your tasks you can use this:
-.PP
-     SHELL=/bin/bash
-     PATH=~/bin:/usr/bin/:/bin
-.PP
 Several environment variables are set up automatically by the
 .IR cron (8)
 daemon.
@@ -105,7 +110,7 @@
 On the Debian GNU/Linux system, cron supports the
 .B pam_env
 module, and loads the environment specified by 
-.IR /etc/environment
+.I /etc/environment
 and
 .IR /etc/security/pam_env.conf .
 It also reads locale information from
@@ -121,8 +126,9 @@
 "text/plain" with the "charset=" parameter set to the charmap / codeset of the
 locale in which
 .IR crond (8)
-is started up - i.e. either the default system locale, if no LC_* environment
-variables are set, or the locale specified by the LC_* environment variables 
+is started up \(en i.e.\& either the default system locale,
+if no LC_* environment variables are set, or the locale specified by
+the LC_* environment variables
 ( see
 .IR locale (7) ).
 You can use different character encodings for mailed cron job output by
@@ -131,7 +137,7 @@
 .PP
 The format of a cron command is very much the V7 standard, with a number of
 upward-compatible extensions.  Each line has five time and date fields,
-followed by a command, followed by a newline character ('\\n').  
+followed by a command, followed by a newline character ('\en').
 The system crontab (/etc/crontab) uses the same format, except that
 the username for the command is specified after the time and
 date fields and before the command. The fields may be separated
@@ -153,30 +159,30 @@
 .br
 -----	--------------
 .br
-minute	0-59
+minute	0\(en59
 .br
-hour	0-23
+hour	0\(en23
 .br
-day of month	1-31
+day of month	1\(en31
 .br
-month	1-12 (or names, see below)
+month	1\(en12 (or names, see below)
 .br
-day of week	0-7 (0 or 7 is Sun, or use names)
+day of week	0\(en7 (0 or 7 is Sun, or use names)
 .br
 .PP
 A field may be an asterisk (*), which always stands for ``first\-last''.
 .PP
 Ranges of numbers are allowed.  Ranges are two numbers separated
 with a hyphen.  The specified range is inclusive.  For example,
-8-11 for an ``hours'' entry specifies execution at hours 8, 9, 10
+8\(en11 for an ``hours'' entry specifies execution at hours 8, 9, 10
 and 11.
 .PP
 Lists are allowed.  A list is a set of numbers (or ranges)
-separated by commas.  Examples: ``1,2,5,9'', ``0-4,8-12''.
+separated by commas.  Examples: ``1,2,5,9'', ``0\(en4,8\(en12''.
 .PP
 Step values can be used in conjunction with ranges.  Following
 a range with ``/<number>'' specifies skips of the number's value
-through the range.  For example, ``0-23/2'' can be used in the hours
+through the range.  For example, ``0\(en23/2'' can be used in the hours
 field to specify command execution every other hour (the alternative
 in the V7 standard is ``0,2,4,6,8,10,12,14,16,18,20,22'').  Steps are
 also permitted after an asterisk, so if you want to say ``every two
@@ -193,10 +199,10 @@
 character, will be executed by /bin/sh or by the shell
 specified in the SHELL variable of the crontab file.
 Percent-signs (%) in the command, unless escaped with backslash
-(\\), will be changed into newline characters, and all data
+(\e), will be changed into newline characters, and all data
 after the first % will be sent to the command as standard
 input. There is no way to split a single command line onto multiple
-lines, like the shell's trailing "\\".
+lines, like the shell's trailing "\e".
 .PP
 Note: The day of a command's execution can be specified by two
 fields \(em day of month, and day of week.  If both fields are
@@ -254,16 +260,16 @@
 #
 # run five minutes after midnight, every day
 5 0 * * *       $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
-# run at 2:15pm on the first of every month -- output mailed to paul
+# run at 2:15pm on the first of every month \(em output mailed to paul
 15 14 1 * *     $HOME/bin/monthly
 # run at 10 pm on weekdays, annoy Joe
-0 22 * * 1-5    mail \-s "It's 10pm" joe%Joe,%%Where are your kids?%
-23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
+0 22 * * 1\(en5    mail \-s "It's 10pm" joe%Joe,%%Where are your kids?%
+23 0\(en23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
 5 4 * * sun     echo "run at 5 after 4 every Sunday"
 0 */4 1 * mon   echo "run every 4th hour on the 1st and on every Monday"
 0 0 */2 * sun   echo "run at midn on every Sunday that's an uneven date"
 # Run on every second Saturday of the month
-0 4 8-14 * *    test $(date +\\%u) \-eq 6 && echo "2nd Saturday"
+0 4 8\(en14 * *    test $(date +\e%u) \-eq 6 && echo "2nd Saturday"
 .fi
 
 .PP
@@ -323,10 +329,11 @@
 When specifying day of week, both day 0 and day 7 will be considered Sunday.
 BSD and AT&T seem to disagree about this.
 .PP
-Lists and ranges are allowed to co-exist in the same field.  "1-3,7-9" would
-be rejected by AT&T or BSD cron -- they want to see "1-3" or "7,8,9" ONLY.
+Lists and ranges are allowed to co-exist in the same field.
+"1\(en3,7\(en9" would be rejected by AT&T or BSD cron \(em they want
+to see "1\(en3" or "7,8,9" ONLY.
 .PP
-Ranges can include "steps", so "1-9/2" is the same as "1,3,5,7,9".
+Ranges can include "steps", so "1\(en9/2" is the same as "1,3,5,7,9".
 .PP
 Months or days of the week can be specified by name.
 .PP
@@ -381,15 +388,15 @@
 the following wrapper code:
 
 .nf
-0 4 * * Sat   [ "$(date +\\%e)" = "$(LANG=C ncal | sed -n 's/^Sa .* \\([0-9]\\+\\) *$/\\1/p')" ] && echo "Last Saturday" && program_to_run
+0 4 * * Sat   [ "$(date +\e%e)" = "$(LANG=C ncal | sed \-n 's/^Sa .* \e([0\(en9]\e+\e) *$/\ex1/p')" ] && echo "Last Saturday" && program_to_run
 .fi
 
 
 .SH DIAGNOSTICS
 cron requires that each entry in a crontab end in a newline character. If the
-last entry in a crontab is missing a newline (i.e. terminated by EOF), cron will
-consider the crontab (at least partially) broken. A warning will be written to
-syslog.
+last entry in a crontab is missing a newline (i.e.\& terminated by EOF),
+cron will consider the crontab (at least partially) broken.
+A warning will be written to syslog.
 
 .SH AUTHOR
 Paul Vixie <paul@vix.com> is the author of 
diff -wu cron-3.0pl1/crontab.c cron-3.0pl1/crontab.c
--- cron-3.0pl1/crontab.c
+++ cron-3.0pl1/crontab.c
@@ -46,8 +46,6 @@
 #endif
 
 
-#define NHEADER_LINES 3
-
 enum opt_t	{ opt_unknown, opt_list, opt_delete, opt_edit, opt_replace };
 
 #if DEBUGGING
@@ -155,10 +153,9 @@
 	
 #if DEBUGGING
-char *getoptarg = "u:lerix:";
+const char *getoptarg = "u:lerix:";
 #else
-char *getoptarg = "u:leri";
+const char *getoptarg = "u:leri";
 #endif
 
-
 static void
 parse_args(argc, argv)
@@ -189,7 +186,6 @@
 		case 'x':
 			if (!set_debug_flags(optarg))
 				usage("bad debug option");
-			usage("unrecognized option");
 			break;
 #endif
 		case 'u':
@@ -302,10 +298,8 @@
 	char	n[MAX_FNAME];
 	FILE	*f;
 	int	ch;
-#ifdef DEBIAN
 	int     x;
 	char    *ctnh;
-#endif
 
 	log_it(RealUser, Pid, "LIST", User);
 	(void) snprintf(n, MAX_FNAME, CRON_TAB(User));
@@ -321,30 +315,33 @@
 	/* file is open. copy to stdout, close.
 	 */
 	Set_LineNum(1)
-#ifdef DEBIAN
-	  /* DEBIAN: Don't list header lines unless CRONTAB_NOHEADER is
-	     'N'. */
-	  /* ignore the top few comments since we probably put them there.
+
+	/* Don't list header lines unless CRONTAB_NOHEADER is 'N'.
+	 *
+	 * ignore the top few comments since we probably put them there.
 	   */
-	  if (!(ctnh = getenv("CRONTAB_NOHEADER")) ||
-	      toupper(*ctnh) != 'N') 
-	    {
+	if (!(ctnh = getenv("CRONTAB_NOHEADER")) || toupper(*ctnh) != 'N') {
 	    for (x = 0;  x < NHEADER_LINES;  x++) {
 	      ch = get_char(f);
-	      if (EOF == ch)
+			if (EOF == ch) {
 		break;
+			}
+
 	      if ('#' != ch) {
 		putchar(ch);
 		break;
 	      }
-	      while (EOF != (ch = get_char(f)))
-		if (ch == '\n')
+			while (EOF != (ch = get_char(f))) {
+				if (ch == '\n') {
 		  break;
-	      if (EOF == ch)
+				}
+			}
+			if (EOF == ch) {
 		break;
 	    }
 	  }
-#endif
+	}
+
 	while (EOF != (ch = get_char(f)))
 		putchar(ch);
 	fclose(f);
@@ -365,8 +362,7 @@
             exit(ERROR_EXIT);
 	}
 
-        if( PromptOnDelete == 1 )
-        {
+	if (PromptOnDelete == 1) {
             printf("crontab: really delete %s's crontab? (y/n) ", User);
             fflush(stdout);
             ans = 0;
@@ -382,9 +378,10 @@
                         fprintf(stderr, "Please enter Y or N: ");
                 }
             }
-            if ( (q[0] == 'N') || (q[0] == 'n') )
+		if ((q[0] == 'N') || (q[0] == 'n')) {
                 exit(OK_EXIT);
         }
+	}
 
 	log_it(RealUser, Pid, "DELETE", User);
 	if (unlink(n)) {
@@ -441,8 +438,7 @@
         }
 
         /* Now create the actual temporary crontab file */
-        if (snprintf(Filename, MAX_FNAME, "%s/crontab", Directory)
-            >= MAX_FNAME) {
+	if (snprintf(Filename, MAX_FNAME, "%s/crontab", Directory) >= MAX_FNAME) {
                 fprintf(stderr, "Temporary filename too long - aborting\n");
                 Filename[0] = '\0';
                 return -1;
@@ -637,21 +633,15 @@
 		while (EOF != (ch = get_char(f)))
 			putc(ch, NewCrontab);
 	fclose(f);
-
 	if (ferror(NewCrontab)) {
 		fprintf(stderr, "%s: error while writing new crontab to %s\n",
 			ProgramName, Filename);
 	}
-
 	if (fstat(t, &fsbuf) < 0) {
 		perror("unable to stat temp file");
 		goto fatal;
 	}
 
-
-
-        /* Okay, edit the file */
-
 	if ((!((editor = getenv("VISUAL")) && strlen(editor)))
 	 && (!((editor = getenv("EDITOR")) && strlen(editor)))
 	    ) {
@@ -674,7 +664,4 @@
 	(void)signal(SIGQUIT, SIG_IGN);
 
-        /* Give up privileges while editing */
-        swap_uids();
-
 	switch (pid = fork()) {
 	case -1:
@@ -739,9 +726,6 @@
 	(void)signal(SIGQUIT, SIG_DFL);
 	(void)signal(SIGTSTP, SIG_DFL);
 
-        /* Need privs again */
-        swap_uids_back();
-
         switch (open_tmp_crontab(&fsbuf)) {
         case -1:
                 fprintf(stderr, "Error while editing crontab\n");
@@ -886,7 +870,7 @@
 	 */
 	Set_LineNum(1 - NHEADER_LINES)
 	CheckErrorCount = 0;  eof = FALSE;
-	while (!CheckErrorCount && !eof) {
+	while (!CheckErrorCount && !eof && LineNumber < MAX_TAB_LINES + 2) {
 		switch (load_env(envstr, tmp)) {
 		case ERR:
 			eof = TRUE;
@@ -903,6 +887,13 @@
 		}
 	}
 
+	if (LineNumber >= MAX_TAB_LINES + 2) {
+		fprintf(stderr, "crontab is too long; maximum number of lines "
+				"is %d.\n", MAX_TAB_LINES);
+		fclose(tmp);  unlink(tn);
+		return (-1);
+	}
+
 	if (CheckErrorCount != 0) {
 		fprintf(stderr, "errors in crontab file, can't install.\n");
 		fclose(tmp);  unlink(tn);
@@ -928,7 +919,6 @@
 		return (-2);
 	}
 
-
 	if (fclose(tmp) == EOF) {
 		perror("fclose");
 		unlink(tn);
@@ -951,8 +941,6 @@
 		unlink(tn);
 		return (-2);
 	}
-
-
 	log_it(RealUser, Pid, "REPLACE", User);
 
 	poke_daemon();
diff -wu cron-3.0pl1/database.c cron-3.0pl1/database.c
--- cron-3.0pl1/database.c
+++ cron-3.0pl1/database.c
@@ -24,13 +24,12 @@
 
 
 #include "cron.h"
-#define __USE_GNU /* For O_NOFOLLOW */
 #include <fcntl.h>
-#undef __USE_GNU
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <time.h>
 
+
 #define TMAX(a,b) ((a)>(b)?(a):(b))
 
 /* Try to get maximum path name -- this isn't really correct, but we're
@@ -49,10 +48,8 @@
 static	void		process_crontab __P((char *, char *, char *,
 					     struct stat *,
 					     cron_db *, cron_db *));
-#ifdef DEBIAN
 static int valid_name (char *filename);
 static user *get_next_system_crontab __P((user *));
-#endif
 
 void force_rescan_user(cron_db *old_db, cron_db *new_db, const char *fname, time_t old_mtime);
 
@@ -69,13 +66,10 @@
 	DIR_T   	*dp;
 	cron_db		new_db;
 	user		*u, *nu;
-#ifdef DEBIAN
 	struct stat     syscrond_stat;
 	struct stat     syscrond_file_stat;
-	
         char            syscrond_fname[PATH_MAX+1];
 	int             syscrond_change = 0;
-#endif
 
 	Debug(DLOAD, ("[%d] load_database()\n", getpid()))
 
@@ -95,7 +89,6 @@
 		syscron_stat.st_mtime = 0;
 	}
 
-#ifdef DEBIAN
 	/* Check mod time of SYSCRONDIR. This won't tell us if a file
          * in it changed, but will capture deletions, which the individual
          * file check won't
@@ -141,7 +134,6 @@
 			Debug(DLOAD, (" [checked]\n"))
 		}
 	}
-#endif /* DEBIAN */
 
 	/* if spooldir's mtime has not changed, we don't need to fiddle with
 	 * the database.
@@ -150,14 +142,9 @@
 	 * so is guaranteed to be different than the stat() mtime the first
 	 * time this function is called.
 	 */
-#ifdef DEBIAN
 	if ((old_db->user_mtime == statbuf.st_mtime) &&
 	    (old_db->sys_mtime == syscron_stat.st_mtime) &&
 	    (!syscrond_change)) {
-#else
-	if ((old_db->user_mtime == statbuf.st_mtime) &&
-	    (old_db->sys_mtime == syscron_stat.st_mtime)) {
-#endif
 		Debug(DLOAD, ("[%d] spool dir mtime unch, no load needed.\n",
 			      getpid()))
 		return;
@@ -170,9 +157,7 @@
 	 */
 	new_db.user_mtime = statbuf.st_mtime;
 	new_db.sys_mtime = syscron_stat.st_mtime;
-#ifdef DEBIAN
 	new_db.sysd_mtime = syscrond_stat.st_mtime;
-#endif
 	new_db.head = new_db.tail = NULL;
 
 	if (syscron_stat.st_mtime) {
@@ -181,7 +166,6 @@
 				&new_db, old_db);
 	}
 
-#ifdef DEBIAN
 	/* Read all the package crontabs. */
 	if (!(dir = opendir(SYSCRONDIR))) {
 		log_it("CRON", getpid(), "OPENDIR FAILED", SYSCRONDIR);
@@ -219,7 +203,6 @@
 	}
 	if (dir)
 		closedir(dir);
-#endif
 
 	/* we used to keep this dir open all the time, for the sake of
 	 * efficiency.  however, we need to close it in every fork, and
@@ -308,7 +291,7 @@
 user *
 find_user(db, name)
 	cron_db	*db;
-	char	*name;
+	const char	*name;
 {
 	char	*env_get();
 	user	*u;
@@ -333,13 +316,9 @@
 	int		crontab_fd = OK - 1;
 	user		*u = NULL;
 
-#ifdef DEBIAN
 	/* If the name begins with *system*, don't worry about password -
 	 it's part of the system crontab */
 	if (strncmp(fname, "*system*", 8) && !(pw = getpwnam(uname))) {
-#else
-	if (strcmp(fname, "*system*") && !(pw = getpwnam(uname))) {
-#endif
 		/* file doesn't have a user in passwd file.
 		 */
 		if (strncmp(fname, "tmp.", 4)) {
@@ -365,6 +344,7 @@
             }
             /* Check to make sure that the crontab is owned by the correct user
                (or root) */
+
             if (statbuf->st_uid != pw->pw_uid && statbuf->st_uid != ROOT_UID) {
                 log_it(fname, getpid(), "WRONG FILE OWNER", tabname);
                 force_rescan_user(old_db, new_db, fname, 0);
@@ -404,20 +384,20 @@
             }
             if ((crontab_fd = open(tabname, O_RDONLY, 0)) < OK) {
 		/* crontab not accessible?
-
-		   If tabname is a symlink, it's most probably just broken, so
-		   we force a rescan. Once the link is fixed, it will get picked
-		   up and processed again. If tabname is a regular file, this
-		   error is bad so we skip it instead.
+			 *
+			 * If tabname is a symlink, it's most probably just
+			 * broken, so we force a rescan. Once the link is
+			 * fixed, it will get picked up and processed again. If
+			 * tabname is a regular file, this error is bad, so we
+			 * skip it instead.
 		 */
 		if (S_ISLNK(statbuf->st_mode)) {
                     log_it(fname, getpid(), "CAN'T OPEN SYMLINK", tabname);
                     force_rescan_user(old_db, new_db, fname, 0);
-                    goto next_crontab;
                 } else {
 		    log_it(fname, getpid(), "CAN'T OPEN", tabname);
-		    goto next_crontab;
 		}
+			goto next_crontab;
             }
 
             if (fstat(crontab_fd, statbuf) < OK) {
@@ -461,6 +441,7 @@
 		goto next_crontab;
 	    }
         }
+
         /*
          * The link count check is not sufficient (the owner may
          * delete their original link, reducing the link count back to
@@ -510,5 +491,4 @@
         }   
 
-
 next_crontab:
 	if (crontab_fd >= OK) {
@@ -517,7 +497,6 @@
 	}
 }
 
-#ifdef DEBIAN
 
 #include <regex.h>
 
@@ -568,8 +547,6 @@
 	return curtab;
 }
 
-#endif
-
 /* Force rescan of a crontab the next time cron wakes up
  *
  * cron currently only detects changes caused by an mtime update; it does not
@@ -595,10 +572,12 @@
 	/* Allocate an empty crontab with the specified mtime, add it to new DB */
         if ((u = (user *) malloc(sizeof(user))) == NULL) {
                 errno = ENOMEM;
+		return;
         }   
         if ((u->name = strdup(fname)) == NULL) {
                 free(u);
                 errno = ENOMEM;
+		return;
         }   
         u->mtime = old_mtime;
         u->crontab = NULL;
diff -wu cron-3.0pl1/debian/changelog cron-3.0pl1/debian/changelog
--- cron-3.0pl1/debian/changelog
+++ cron-3.0pl1/debian/changelog
@@ -1,3 +1,32 @@
+cron (3.0pl1-133) unstable; urgency=medium
+
+  * SECURITY: Fix bypass of /etc/cron.{allow,deny} on failure to open
+    If these files exist, then they must be readable by the user executing
+    crontab(1). Users will now be denied by default if they aren't.
+    (LP: #1813833)
+  * SECURITY: Fix for possible DoS by use-after-free
+    A user reported a use-after-free condition in the cron daemon, leading to a
+    possible Denial-of-Service scenario by crashing the daemon.
+    (Closes: #809167)
+  * SECURITY: DoS: Fix unchecked return of calloc()
+    Florian Weimer discovered that a missing check for the return value of
+    calloc() could crash the daemon, which could be triggered by a very
+    large crontab created by a user.
+  * Enforce maximum crontab line count of 1000 to prevent a malicious user
+    from creating an excessivly large crontab. The daemon will log a warning
+    for existing files, and crontab(1) will refuse to create new ones.
+  * Add d/NEWS altering to the new 1000 lines limit.
+  * Move /var/run/crond.reboot to /run/crond.reboot.
+  * crontab.5: Reverse the info on tilde expansion. When setting PATH, most
+    shells will not expand a tilde. Thanks, Tim Landscheidt, for the analysis.
+    (Closes: #801328)
+  * Fixes for numerous man page issues. Remove trailing whitespace, use proper
+    escapes, etc. Thanks, Bjarni Ingi Gislason! (Closes: #893575, #893579)
+  * crontab.1: Drop duplicate DIAGNOSTICS header.
+  * daemon: Only support the 'x' debug option in debug builds.
+
+ -- Christian Kastner <ckk@debian.org>  Sun, 10 Mar 2019 17:49:18 +0100
+
 cron (3.0pl1-132) unstable; urgency=medium
 
   [ Christian Kastner ]
diff -wu cron-3.0pl1/do_command.c cron-3.0pl1/do_command.c
--- cron-3.0pl1/do_command.c
+++ cron-3.0pl1/do_command.c
@@ -132,7 +132,6 @@
 	char		*usernm, *mailto;
 	int		children = 0;
 	pid_t		job_pid;
-
 #if defined(USE_PAM)
 	int		retcode = 0;
 #endif
@@ -173,13 +172,9 @@
 	/* our parent is watching for our death by catching SIGCHLD.  we
 	 * do not care to watch for our children's deaths this way -- we
-	 * use wait() explictly.  so we have to disable the signal (which
+	 * use wait() explictly.  so we have to reset the signal (which
 	 * was inherited from the parent).
 	 */
-#ifdef DEBIAN
 	(void) signal(SIGCHLD, SIG_DFL);
 #else
-	(void) signal(SIGCHLD, SIG_IGN);
-#endif
-#else
 	/* on system-V systems, we are ignoring SIGCLD.  we have to stop
 	 * ignoring it now or the wait() in cron_pclose() won't work.
@@ -245,7 +240,6 @@
 	PAM_FAIL_CHECK;
 	retcode = pam_open_session(pamh, PAM_SILENT);
 	PAM_FAIL_CHECK;
-
 #endif
 
 	/* fork again, this time so we can exec the user's command.
@@ -288,11 +282,9 @@
 		/* grandchild process.  make std{in,out} be the ends of
 		 * pipes opened by our daddy; make stderr go to stdout.
 		 */
-		/* Closes are unnecessary -- let dup2() do it */
-
-		  /* close(STDIN) */; dup2(stdin_pipe[READ_PIPE], STDIN);
+		dup2(stdin_pipe[READ_PIPE], STDIN);
 		  dup2(fileno(tmpout), STDOUT);
-		  /* close(STDERR)*/; dup2(STDOUT, STDERR);
+		dup2(STDOUT, STDERR);
 
 
 		/* close the pipe we just dup'ed.  The resources will remain.
@@ -348,26 +340,20 @@
 				_exit(OK_EXIT);
 			}
 # endif /*DEBUGGING*/
-#if 0
-			{
-			  struct sigaction oact;
-			  sigaction(SIGCHLD, NULL, &oact);
-			}
-			fprintf(stdout,"error");
-#endif
 #ifdef WITH_SELINUX
 			if (is_selinux_enabled() > 0) {
 			    if (u->scontext != 0L) {
-                                if (setexeccon(u->scontext) < 0) {
-                                    if (security_getenforce() > 0) {
-                                        fprintf(stderr, "Could not set exec context to %s for user  %s\n", u->scontext,u->name);
+					if (setexeccon(u->scontext) < 0 &&
+							security_getenforce() > 0) {
+						fprintf(stderr, "Could not set exec context "
+								"to %s for user  %s\n",
+								u->scontext,u->name);
                                         _exit(ERROR_EXIT);
                                     }
-			        }
-                            }
-			    else if(security_getenforce() > 0)
-			    {
-                                fprintf(stderr, "Error, must have a security context for the cron job when in enforcing mode.\nUser %s.\n", u->name);
+				} else if (security_getenforce() > 0) {
+					fprintf(stderr, "Error, must have a security context "
+							"for the cron job when in enforcing "
+							"mode.\nUser %s.\n", u->name);
                                 _exit(ERROR_EXIT);
 			    }
 			}
@@ -513,7 +499,6 @@
 	
 	long pos;
 	struct stat	mcsb;
-	int		statret;	
 
 	fseek(tmpout, 0, SEEK_END);
 	pos = ftell(tmpout);
@@ -531,7 +516,7 @@
                 goto mail_finished;
 
 	/* Don't send mail if MAILCMD is not available */
-	if ((statret = stat(MAILCMD, &mcsb)) != 0) {
+	if (stat(MAILCMD, &mcsb) != 0) {
 		Debug(DPROC|DEXT, ("%s not found, not sending mail\n", MAILCMD))
 		if (pos > 0) {
 			log_it("CRON", getpid(), "info", "No MTA installed, discarding output");
@@ -569,10 +554,10 @@
 			arpadate(&StartTime));
 # endif /* MAIL_DATE */
 	fprintf(mail, "MIME-Version: 1.0\n");
+
 	if ( content_type == 0L ) {
 		fprintf(mail, "Content-Type: text/plain; charset=%s\n",
-				cron_default_mail_charset
-		       );
+			cron_default_mail_charset);
 	} else {   
 		/* user specified Content-Type header.
 		 * disallow new-lines for security reasons
@@ -581,24 +566,28 @@
 		char *nl=content_type;
 		size_t ctlen = strlen(content_type);
 
-		while(  (*nl != '\0')
-				&& ((nl=strchr(nl,'\n')) != 0L)
-				&& (nl < (content_type+ctlen))
-		     ) *nl = ' ';
+		while ((*nl != '\0') &&
+				((nl=strchr(nl,'\n')) != 0L) &&
+				(nl < (content_type+ctlen))) {
+			*nl = ' ';
+		}
 		fprintf(mail,"Content-Type: %s\n", content_type);
 	}
+
 	if ( content_transfer_encoding != 0L ) {
 		char *nl=content_transfer_encoding;
 		size_t ctlen = strlen(content_transfer_encoding);
-		while(  (*nl != '\0')
-				&& ((nl=strchr(nl,'\n')) != 0L)
-				&& (nl < (content_transfer_encoding+ctlen))
-		     ) *nl = ' ';
-
-		fprintf(mail,"Content-Transfer-Encoding: %s\n", content_transfer_encoding);
+		while ((*nl != '\0') &&
+				((nl = strchr(nl,'\n')) != 0L) &&
+				(nl < (content_transfer_encoding+ctlen))) {
+			*nl = ' ';
 	}
-	else
+
+		fprintf(mail,"Content-Transfer-Encoding: %s\n",
+				content_transfer_encoding);
+	} else {
 		fprintf(mail, "Content-Transfer-Encoding: 8bit\n");
+	}
 
 	for (env = e->envp;  *env;  env++)
 		fprintf(mail, "X-Cron-Env: <%s>\n",
diff -wu cron-3.0pl1/entry.c cron-3.0pl1/entry.c
--- cron-3.0pl1/entry.c
+++ cron-3.0pl1/entry.c
@@ -108,6 +108,10 @@
 	 */
 
 	e = (entry *) calloc(sizeof(entry), sizeof(char));
+	if (e == NULL) {
+		log_it("CRON", getpid(), "OOM", "Out of memory parsing crontab");
+		return NULL;
+	}
 
 	if (ch == '@') {
 		/* all of these should be flagged and load-limited; i.e.,
diff -wu cron-3.0pl1/env.c cron-3.0pl1/env.c
--- cron-3.0pl1/env.c
+++ cron-3.0pl1/env.c
@@ -278,7 +278,7 @@
 	register int	len = strlen(name);
 	register char	*p, *q;
 
-	while ((p = *envp++)) {
+	while ((p = *envp++) != NULL) {
 		if (!(q = strchr(p, '=')))
 			continue;
 		if ((q - p) == len && !strncmp(p, name, len))
diff -wu cron-3.0pl1/externs.h cron-3.0pl1/externs.h
--- cron-3.0pl1/externs.h
+++ cron-3.0pl1/externs.h
@@ -61,7 +61,6 @@
 extern	void		perror(), exit(), free();
 extern	char		*getenv(), *strcpy(), *strchr(), *strtok();
 extern	void		*malloc(), *realloc();
-
 # define SIG_T	void
 # define TIME_T	long
 # define PID_T int
diff -wu cron-3.0pl1/misc.c cron-3.0pl1/misc.c
--- cron-3.0pl1/misc.c
+++ cron-3.0pl1/misc.c
@@ -213,8 +213,7 @@
 			fprintf(stderr, "%s: created\n", CRONDIR);
 			stat(CRONDIR, &sb);
 		} else {
-			fprintf(stderr, "%s: mkdir: %s\n", CRONDIR,
-				strerror(errno));
+			fprintf(stderr, "%s: mkdir: %s\n", CRONDIR, strerror(errno));
 			exit(ERROR_EXIT);
 		}
 		(void) umask(um);
@@ -331,7 +330,6 @@
 	/* abandon fd and fp even though the file is open. we need to
 	 * keep it open and locked, but we don't need the handles elsewhere.
 	 */
-	
 }
 
 /* get_char(file) : like getc() but increment LineNumber on newlines
@@ -344,7 +342,7 @@
 
 	ch = getc(file);
 	if (ch == '\n')
-		Set_LineNum(LineNumber + 1);
+		Set_LineNum(LineNumber + 1)
 	return ch;
 }
 
@@ -358,7 +356,7 @@
 {
 	ungetc(ch, file);
 	if (ch == '\n')
-	       Set_LineNum(LineNumber - 1);
+		Set_LineNum(LineNumber - 1)
 }
 
 
@@ -479,7 +477,23 @@
 		init = TRUE;
 #if defined(ALLOW_FILE) && defined(DENY_FILE)
 		allow = fopen(ALLOW_FILE, "r");
+		if (allow == NULL) {
+			/* Only if the file does not exist do we ignore the
+			 * error. Otherwise, we deny by default.
+			 */
+			if (errno != ENOENT) {
+				perror(ALLOW_FILE);
+				return FALSE;
+			}
+		}
 		deny = fopen(DENY_FILE, "r");
+		if (allow == NULL) {
+			/* See above */
+			if (errno != ENOENT) {
+				perror(DENY_FILE);
+				return FALSE;
+			}
+		}
 		Debug(DMISC, ("allow/deny enabled, %d/%d\n", !!allow, !!deny))
 #else
 		allow = NULL;
@@ -515,15 +529,14 @@
 	char	*event;
 	char	*detail;
 {
-#if defined(LOG_FILE)
 	PID_T			pid = xpid;
+#if defined(LOG_FILE)
 	char			*msg;
 	TIME_T			now = time((TIME_T) 0);
 	register struct tm	*t = localtime(&now);
 	int 			msg_size;
 #endif /*LOG_FILE*/
 
-
 #if defined(LOG_FILE)
 	/* we assume that MAX_TEMPSTR will hold the date, time, &punctuation.
 	 */
@@ -567,15 +580,6 @@
 #endif /*LOG_FILE*/
 
 #if defined(SYSLOG)
-
-
-	    /* we don't use LOG_PID since the pid passed to us by
-	     * our client may not be our own.  therefore we want to
-	     * print the pid ourselves.
-	     */
-	    /* SteveG says: That comment is not consistent with the
-	       code, and makes no sense -- I suspect it's a remnant
-	       of a cut-n-paster... */
 # ifdef LOG_CRON
 	openlog(ProgramName, LOG_PID, LOG_CRON);
 # else
@@ -584,7 +588,6 @@
 	  
 	syslog(LOG_INFO, "(%s) %s (%s)", username, event, detail);
 
-	closelog();
 #endif /*SYSLOG*/
 
 #if DEBUGGING
diff -wu cron-3.0pl1/pathnames.h cron-3.0pl1/pathnames.h
--- cron-3.0pl1/pathnames.h
+++ cron-3.0pl1/pathnames.h
@@ -19,7 +19,7 @@
  * $Id: pathnames.h,v 1.3 1994/01/15 20:43:43 vixie Exp $
  */
 
-#if (defined(BSD)) && (BSD >= 199103) || defined(__linux__) || defined(AIX) || defined(__GNU__) || defined(__GLIBC__)
+#if (defined(BSD)) && (BSD >= 199103) || defined(__linux__) || defined(AIX) || defined(__GLIBC__)
 # include <paths.h>
 #endif /*BSD*/
 
@@ -47,14 +47,9 @@
 			 * LOG_FILE or SYSLOG is defined, we don't log.  If
 			 * both are defined, we log both ways.
 			 */
-#ifdef DEBIAN
 #define	ALLOW_FILE	"/etc/cron.allow"		/*-*/
 #define DENY_FILE	"/etc/cron.deny"		/*-*/
-#else
-#define	ALLOW_FILE	"allow"		/*-*/
-#define DENY_FILE	"deny"		/*-*/
-#endif
-/* #define LOG_FILE	"log"		  -*/
+/* #define LOG_FILE	"log"		/*-*/
 
 			/* where should the daemon stick its PID?
 			 */
@@ -67,20 +62,13 @@
 
 			/* 4.3BSD-style crontab */
 #define SYSCRONTAB	"/etc/crontab"
-#ifdef DEBIAN
                         /* where package specific crontabs live */ 
 #define SYSCRONDIR      "/etc/cron.d"
-#endif
+
 			/* what editor to use if no EDITOR or VISUAL
 			 * environment variable specified.
 			 */
-#if defined(DEBIAN)
 # define EDITOR "/usr/bin/sensible-editor"
-#elif defined(_PATH_VI)
-# define EDITOR _PATH_VI
-#else
-# define EDITOR "/usr/ucb/vi"
-#endif
 
 #ifndef _PATH_BSHELL
 # define _PATH_BSHELL "/bin/sh"
@@ -90,12 +78,11 @@
 # define _PATH_DEFPATH "/usr/bin:/bin"
 #endif
 
-#ifndef _PATH_DEFPATH_ROOT
-# define _PATH_DEFPATH_ROOT "/usr/sbin:/usr/bin:/sbin:/bin"
+#ifndef REBOOT_FILE
+# define REBOOT_FILE "/run/crond.reboot"
 #endif
 
 
-#ifdef DEBIAN
 #ifndef CRONDIR_MODE
 			/* Create mode for CRONDIR; must be in sync with
 			 * packaging
@@ -117 +103,0 @@
-#endif
diff -wu cron-3.0pl1/popen.c cron-3.0pl1/popen.c
--- cron-3.0pl1/popen.c
+++ cron-3.0pl1/popen.c
@@ -148,7 +148,6 @@
 		  exit(ERROR_EXIT);
 		}	
 		chdir(env_get("HOME", e->envp));
-
 #if WANT_GLOBBING
 		execvp(gargv[0], gargv);
 #else
diff -wu cron-3.0pl1/user.c cron-3.0pl1/user.c
--- cron-3.0pl1/user.c
+++ cron-3.0pl1/user.c
@@ -58,9 +58,7 @@
             freecon(current_con);
             return (security_getenforce() > 0);
         }
-    }
-    else
-    {
+	} else {
         context_t temp_con = context_new(current_con);
         if (temp_con == NULL) {
             log_it(name, getpid(), "context_new FAILED", tabname);
@@ -110,8 +108,7 @@
      * permission check for this purpose.
      */
 
-    for(i = 0; i < list_count; i++)
-    {
+	for (i = 0; i < list_count; i++) {
         retval = security_compute_av(context_list[i],
                                  file_context,
                                  SECCLASS_FILE,
@@ -139,7 +136,6 @@
 #endif
 
 
-#ifdef DEBIAN
 /* Function used to log errors in crontabs from cron daemon. (User
    crontabs are checked before they're accepted, but system crontabs
    are not. */
@@ -163,8 +159,6 @@
   }
 }
 
-#endif
-
 void
 free_user(u)
 	user	*u;
@@ -236,7 +230,6 @@
         }
 #endif
 
-
 	/* 
 	 * init environment.  this will be copied/augmented for each entry.
 	 */
@@ -249,6 +242,7 @@
 	/*
 	 * load the crontab
 	 */
+	Set_LineNum(1)
 	do {
 		status = load_env(envstr, file);
 		switch (status) {
@@ -268,13 +262,9 @@
 			}
 			goto done;
 		case FALSE:
-#ifdef DEBIAN
 			err_user = fname;
 			e = load_entry(file, crontab_error, pw, envp);
 			err_user = NULL;
-#else
-			e = load_entry(file, NULL, pw, envp);
-#endif
 			if (e) {
 				e->next = u->crontab;
 				u->crontab = e;
@@ -298,7 +288,19 @@
 			}
 			break;
 		}
-	} while (status >= OK);
+	/* When counting lines, ignore the user-hidden header part, and account
+	 * for idiosyncrasies of LineNumber manipulation
+	 */
+	} while (status >= OK && LineNumber < MAX_TAB_LINES + NHEADER_LINES + 2);
+
+	if (LineNumber >= MAX_TAB_LINES + NHEADER_LINES + 2) {
+		log_it(fname, getpid(), "ERROR", "crontab must not be longer "
+				"than " Stringify(MAX_TAB_LINES) " lines, "
+				"this crontab file will be ignored");
+		free_user(u);
+		u = NULL;
+		goto done;
+	}
 
  done:
 	env_free(envp);
only in patch2:
--- cron-3.0pl1.orig/debian/NEWS
+++ cron-3.0pl1/debian/NEWS
@@ -0,0 +1,9 @@
+cron (3.0pl1-133) unstable; urgency=medium
+
+  * As a reasonable protective measure, crontabs are now limited to 1000 lines
+    in length per crontab.
+    The maintainers find it very unlikely that longer crontabs exist; however,
+    if you do have a use case, please file a bug report with a brief rationale,
+    and we will consider raising this limit.
+
+ -- Christian Kastner <ckk@debian.org>  Sun, 10 Mar 2019 17:44:13 +0100
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/debian/changelog cron-3.0pl1/debian/changelog
--- cron-3.0pl1/debian/changelog	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/debian/changelog	2019-03-21 20:14:33.000000000 +0100
@@ -1,3 +1,32 @@
+cron (3.0pl1-133) unstable; urgency=medium
+
+  * SECURITY: Fix bypass of /etc/cron.{allow,deny} on failure to open
+    If these files exist, then they must be readable by the user executing
+    crontab(1). Users will now be denied by default if they aren't.
+    (LP: #1813833)
+  * SECURITY: Fix for possible DoS by use-after-free
+    A user reported a use-after-free condition in the cron daemon, leading to a
+    possible Denial-of-Service scenario by crashing the daemon.
+    (Closes: #809167)
+  * SECURITY: DoS: Fix unchecked return of calloc()
+    Florian Weimer discovered that a missing check for the return value of
+    calloc() could crash the daemon, which could be triggered by a very
+    large crontab created by a user.
+  * Enforce maximum crontab line count of 1000 to prevent a malicious user
+    from creating an excessivly large crontab. The daemon will log a warning
+    for existing files, and crontab(1) will refuse to create new ones.
+  * Add d/NEWS altering to the new 1000 lines limit.
+  * Move /var/run/crond.reboot to /run/crond.reboot.
+  * crontab.5: Reverse the info on tilde expansion. When setting PATH, most
+    shells will not expand a tilde. Thanks, Tim Landscheidt, for the analysis.
+    (Closes: #801328)
+  * Fixes for numerous man page issues. Remove trailing whitespace, use proper
+    escapes, etc. Thanks, Bjarni Ingi Gislason! (Closes: #893575, #893579)
+  * crontab.1: Drop duplicate DIAGNOSTICS header.
+  * daemon: Only support the 'x' debug option in debug builds.
+
+ -- Christian Kastner <ckk@debian.org>  Sun, 10 Mar 2019 17:49:18 +0100
+
 cron (3.0pl1-132) unstable; urgency=medium
 
   [ Christian Kastner ]
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/compat.h cron-3.0pl1/compat.h
--- cron-3.0pl1/compat.h	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/compat.h	2019-03-21 20:14:33.000000000 +0100
@@ -62,8 +62,8 @@
 #endif
 
 #ifndef POSIX
-# if (BSD >= 199103) || defined(__linux__) || defined(__GNU__) || defined(ultrix) ||\
-        defined(AIX) ||\ defined(HPUX) || defined(CONVEX) || defined(IRIX) || defined(__GLIBC__)
+# if (BSD >= 199103) || defined(__linux__) || defined(ultrix) || defined(AIX) ||\
+	defined(HPUX) || defined(CONVEX) || defined(IRIX)
 #  define POSIX
 # endif
 #endif
@@ -76,17 +76,17 @@
 
 /*****************************************************************/
 
-#if !defined(BSD) && !defined(HPUX) && !defined(CONVEX) && !defined(__linux__) && !defined(__GNU__)
+#if !defined(BSD) && !defined(HPUX) && !defined(CONVEX) && !defined(__linux__) && !defined(__GLIBC__)
 # define NEED_VFORK
 #endif
 
 #if (!defined(BSD) || (BSD < 198902)) && !defined(__linux__) && \
-	!defined(IRIX) && !defined(NeXT) && !defined(HPUX) && !defined(__GNU__) && !defined(__GLIBC__)
+	!defined(IRIX) && !defined(NeXT) && !defined(HPUX) && !defined(__GLIBC__)
 # define NEED_STRCASECMP
 #endif
 
 #if (!defined(BSD) || (BSD < 198911)) && !defined(__linux__) &&\
-	!defined(IRIX) && !defined(UNICOS) && !defined(HPUX) && !defined(__GNU__) && !defined(__GLIBC__)
+	!defined(IRIX) && !defined(UNICOS) && !defined(HPUX) && !defined(__GLIBC__)
 # define NEED_STRDUP
 #endif
 
@@ -102,7 +102,7 @@
 # define NEED_SETSID
 #endif
 
-#if (defined(POSIX) && !defined(BSD)) && !defined(__linux__) && !defined(__GNU__) && !defined(__GLIBC__)
+#if (defined(POSIX) && !defined(BSD)) && !defined(__linux__) && !defined(__GLIBC__)
 # define NEED_GETDTABLESIZE
 #endif
 
@@ -110,11 +110,11 @@
 # define HAVE_SAVED_UIDS
 #endif
 
-#if !defined(ATT) && !defined(__linux__) && !defined(__GNU__) && !defined(IRIX) && !defined(UNICOS) && !defined(__GLIBC__)
+#if (!defined(ATT) && !defined(IRIX) && !defined(UNICOS)) || defined(POSIX)
 # define USE_SIGCHLD
 #endif
 
-#if !defined(AIX) && !defined(UNICOS) && !defined(DEBIAN)
+#if !defined(AIX) && !defined(UNICOS) && !defined(POSIX)
 # define SYS_TIME_H 1
 #else
 # define SYS_TIME_H 0
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/config.h cron-3.0pl1/config.h
--- cron-3.0pl1/config.h	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/config.h	2019-03-21 20:14:33.000000000 +0100
@@ -43,10 +43,10 @@
 			 */
 
 #define MAILCMD _PATH_SENDMAIL					/*-*/
-/* #define MAILARGS "%s -i -FCronDaemon -odi -oem  %s"		/*-*/
-#define MAILARGS "%s -i -FCronDaemon -B8BITMIME -oem  %s"		/*-*/
-			/* -i    = don't terminate on "." by itself
-                         * -Fx	 = set full-name of sender
+#define MAILARGS "%s -FCronDaemon -i -B8BITMIME -oem  %s"	/*-*/
+			/* -Fx	 = set full-name of sender
+			 * -i    = don't terminate on "." by itself
+			 * -B8BITMIME = 8-bit processing
 			 * -odi	 = Option Deliverymode Interactive
 			 * -oem	 = Option Errors Mailedtosender
  			 * -t    = read recipient from header of message
@@ -55,15 +55,15 @@
 			 * by joe user.  --okir
 			 */
 
-/* #define MAILCMD "/bin/mail"			-*/
-/* #define MAILARGS "%s -d  %s"			-*/
+/* #define MAILCMD "/bin/mail"			/*-*/
+/* #define MAILARGS "%s -d  %s"			/*-*/
 			/* -d = undocumented but common flag: deliver locally?
 			 */
 
-/* #define MAILCMD "/usr/mmdf/bin/submit"	-*/
-/* #define MAILARGS "%s -mlrxto %s"		-*/
+/* #define MAILCMD "/usr/mmdf/bin/submit"	/*-*/
+/* #define MAILARGS "%s -mlrxto %s"		/*-*/
 
-/* #define MAIL_DATE				-*/
+/* #define MAIL_DATE				/*-*/
 			/* should we include an ersatz Date: header in
 			 * generated mail?  if you are using sendmail
 			 * for MAILCMD, it is better to let sendmail
@@ -74,7 +74,7 @@
 			 * defined but neither exists, should crontab(1) be
 			 * usable only by root?
 			 */
-/*#define ALLOW_ONLY_ROOT			-*/
+/*#define ALLOW_ONLY_ROOT			/*-*/
 
 			/* if you want to use syslog(3) instead of appending
 			 * to CRONDIR/LOG_FILE (/var/cron/log, e.g.), define
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/cron.c cron-3.0pl1/cron.c
--- cron-3.0pl1/cron.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/cron.c	2019-03-21 20:14:33.000000000 +0100
@@ -26,6 +26,7 @@
 #include "cron.h"
 #include <signal.h>
 
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <libgen.h>
@@ -49,8 +50,9 @@
 	char **dflags;
 
 	fprintf(stderr, "usage:  %s [-x [", ProgramName);
-	for(dflags = DebugFlagNames; *dflags; dflags++)
+	for (dflags = DebugFlagNames; *dflags; dflags++) {
 		fprintf(stderr, "%s%s", *dflags, dflags[1] ? "," : "]");
+	}
 	fprintf(stderr, "]\n");
 #else
 	fprintf(stderr, "usage: %s\n", ProgramName);
@@ -83,9 +85,6 @@
 #endif
 	(void) signal(SIGHUP, sighup_handler);
 
-        /* Reopen stdin in case some idiot closed it before starting
-           us - it will only be closed, but not having it open here
-           screws up other things that will be opened */
         if (fdopen(0,"r") == NULL) {
             (void) open("dev/null", 0);
         }
@@ -145,11 +144,8 @@
 	database.tail = NULL;
 	database.sys_mtime = (time_t) 0;
 	database.user_mtime = (time_t) 0;
-#ifdef DEBIAN
 	database.sysd_mtime = (time_t) 0;
-#endif
 	load_database(&database);
-
 	set_time(TRUE);
 	run_reboot_jobs(&database);
 	timeRunning = virtualTime = clockTime;
@@ -273,10 +269,6 @@
 	}
 }
 
-#ifdef DEBIAN
-#include <sys/stat.h>
-#include <fcntl.h>
-#endif
 
 static void
 run_reboot_jobs(db)
@@ -285,8 +277,7 @@
 	register user		*u;
 	register entry		*e;
     int rbfd;
-#ifdef DEBIAN
-#define REBOOT_FILE "/var/run/crond.reboot"
+
 	/* Run on actual reboot, rather than cron restart */
 	if (access(REBOOT_FILE, F_OK) == 0) {
 	        /* File exists, return */
@@ -303,12 +294,7 @@
 		close(rbfd);
 		log_it("CRON", getpid(),"INFO", "Running @reboot jobs");
 	}
-      
-
-        Debug(DMISC, ("[%d], Debian running reboot jobs\n",getpid()));
-    
-#endif
-        Debug(DMISC, ("[%d], vixie running reboot jobs\n", getpid()));
+	Debug(DMISC, ("[%d], running reboot jobs\n", getpid()));
 	for (u = db->head;  u != NULL;  u = u->next) {
 		for (e = u->crontab;  e != NULL;  e = e->next) {
 			if (e->flags & WHEN_REBOOT) {
@@ -418,7 +404,7 @@
 
 #ifdef USE_SIGCHLD
 static void
-sigchld_handler(x) {
+sigchld_handler(int x) {
 	int save_errno = errno;
 	WAIT_T		waiter;
 	PID_T		pid;
@@ -452,7 +438,7 @@
 
 
 static void
-sighup_handler(x) {
+sighup_handler(int x) {
 	log_close();
 
 	/* we should use sigaction for proper signal blocking as this 
@@ -461,6 +447,12 @@
 }
 
 
+#if DEBUGGING
+const char *getoptarg = "flL:nx:";
+#else
+const char *getoptarg = "flL:n";
+#endif
+
 static void
 parse_args(argc, argv)
 	int	argc;
@@ -468,31 +460,33 @@
 {
 	int	argch;
 
-	log_level = 1;
 	stay_foreground = 0;
         lsbsysinit_mode = 0;
+	log_level = 1;
         fqdn_in_subject = 0;
 
-	while (EOF != (argch = getopt(argc, argv, "lfnx:L:"))) {
+	while (EOF != (argch = getopt(argc, argv, getoptarg))) {
 		switch (argch) {
 		default:
 			usage();
 		case 'f':
 			stay_foreground = 1;
 			break;
-		case 'x':
-			if (!set_debug_flags(optarg))
-				usage();
-			break;
 		case 'l':
 			lsbsysinit_mode = 1;
 			break;
+		case 'L':
+			log_level = atoi(optarg);
+			break;
 		case 'n':
 			fqdn_in_subject = 1;
 			break;
-		case 'L':
-			log_level = atoi(optarg);
+#if DEBUGGING
+		case 'x':
+			if (!set_debug_flags(optarg))
+				usage();
 			break;
+#endif
 		}
 	}
 }
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/cron.h cron-3.0pl1/cron.h
--- cron-3.0pl1/cron.h	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/cron.h	2019-03-21 20:14:33.000000000 +0100
@@ -82,6 +82,7 @@
 #define	MAX_COMMAND	1000	/* max length of internally generated cmd */
 #define	MAX_TEMPSTR	1000	/* max length of envvar=value\0 strings */
 #define	MAX_ENVSTR	MAX_TEMPSTR	/* DO NOT change - buffer overruns otherwise */
+#define MAX_TAB_LINES	1000	/* max length of crontabs */
 #define	MAX_UNAME	20	/* max length of username, should be overkill */
 #define	ROOT_UID	0	/* don't change this, it really must be root */
 #define	ROOT_USER	"root"	/* ditto */
@@ -101,6 +102,7 @@
 #define	CRON_TAB(u)	"%s/%s", SPOOL_DIR, u
 #define	REG		register
 #define	PPC_NULL	((char **)NULL)
+#define NHEADER_LINES   3
 
 #ifndef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN 64
@@ -126,6 +128,8 @@
 			;
 #endif /* DEBUGGING */
 
+#define Stringify_(x)	#x
+#define Stringify(x)	Stringify_(x)
 #define	MkLower(ch)	(isupper(ch) ? tolower(ch) : ch)
 #define	MkUpper(ch)	(islower(ch) ? toupper(ch) : ch)
 #define	Set_LineNum(ln)	{Debug(DPARS|DEXT,("linenum=%d\n",ln)); \
@@ -209,9 +213,7 @@
 	user		*head, *tail;	/* links */
 	time_t		user_mtime;     /* last modtime on spooldir */
 	time_t		sys_mtime;      /* last modtime on system crontab */
-#ifdef DEBIAN
 	time_t		sysd_mtime;     /* last modtime on system crondir */
-#endif
 } cron_db;
 
 typedef struct _orphan {
@@ -263,7 +265,7 @@
 		**env_set __P((char **, char *));
 
 user		*load_user __P((int, struct passwd *, char *, char *, char *)),
-		*find_user __P((cron_db *, char *));
+		*find_user __P((cron_db *, const char *));
 
 entry		*load_entry __P((FILE *, void (*)(),
 				 struct passwd *, char **));
@@ -305,8 +307,9 @@
 
 int	stay_foreground;
 int     lsbsysinit_mode;
+int	log_level;
 int     fqdn_in_subject;
-int     log_level = 1;
+
 char    cron_default_mail_charset[MAX_ENVSTR] = "";
 
 # if DEBUGGING
@@ -322,8 +325,8 @@
 		*DowNames[],
 		*ProgramName;
 extern  int     lsbsysinit_mode;
-extern  int     fqdn_in_subject;
 extern  int     log_level;
+extern	int	fqdn_in_subject;
 extern	int	LineNumber;
 extern	time_t	StartTime;
 extern  time_min timeRunning;
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/crontab.c cron-3.0pl1/crontab.c
--- cron-3.0pl1/crontab.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/crontab.c	2019-03-21 20:14:33.000000000 +0100
@@ -46,8 +46,6 @@
 #endif
 
 
-#define NHEADER_LINES 3
-
 enum opt_t	{ opt_unknown, opt_list, opt_delete, opt_edit, opt_replace };
 
 #if DEBUGGING
@@ -154,12 +152,11 @@
 }
 	
 #if DEBUGGING
-char *getoptarg = "u:lerix:";
+const char *getoptarg = "u:lerix:";
 #else
-char *getoptarg = "u:leri";
+const char *getoptarg = "u:leri";
 #endif
 
-
 static void
 parse_args(argc, argv)
 	int	argc;
@@ -189,7 +186,6 @@
 		case 'x':
 			if (!set_debug_flags(optarg))
 				usage("bad debug option");
-			usage("unrecognized option");
 			break;
 #endif
 		case 'u':
@@ -302,10 +298,8 @@
 	char	n[MAX_FNAME];
 	FILE	*f;
 	int	ch;
-#ifdef DEBIAN
 	int     x;
 	char    *ctnh;
-#endif
 
 	log_it(RealUser, Pid, "LIST", User);
 	(void) snprintf(n, MAX_FNAME, CRON_TAB(User));
@@ -321,30 +315,33 @@
 	/* file is open. copy to stdout, close.
 	 */
 	Set_LineNum(1)
-#ifdef DEBIAN
-	  /* DEBIAN: Don't list header lines unless CRONTAB_NOHEADER is
-	     'N'. */
-	  /* ignore the top few comments since we probably put them there.
+
+	/* Don't list header lines unless CRONTAB_NOHEADER is 'N'.
+	 *
+	 * ignore the top few comments since we probably put them there.
 	   */
-	  if (!(ctnh = getenv("CRONTAB_NOHEADER")) ||
-	      toupper(*ctnh) != 'N') 
-	    {
+	if (!(ctnh = getenv("CRONTAB_NOHEADER")) || toupper(*ctnh) != 'N') {
 	    for (x = 0;  x < NHEADER_LINES;  x++) {
 	      ch = get_char(f);
-	      if (EOF == ch)
+			if (EOF == ch) {
 		break;
+			}
+
 	      if ('#' != ch) {
 		putchar(ch);
 		break;
 	      }
-	      while (EOF != (ch = get_char(f)))
-		if (ch == '\n')
+			while (EOF != (ch = get_char(f))) {
+				if (ch == '\n') {
 		  break;
-	      if (EOF == ch)
+				}
+			}
+			if (EOF == ch) {
 		break;
 	    }
 	  }
-#endif
+	}
+
 	while (EOF != (ch = get_char(f)))
 		putchar(ch);
 	fclose(f);
@@ -365,8 +362,7 @@
             exit(ERROR_EXIT);
 	}
 
-        if( PromptOnDelete == 1 )
-        {
+	if (PromptOnDelete == 1) {
             printf("crontab: really delete %s's crontab? (y/n) ", User);
             fflush(stdout);
             ans = 0;
@@ -382,9 +378,10 @@
                         fprintf(stderr, "Please enter Y or N: ");
                 }
             }
-            if ( (q[0] == 'N') || (q[0] == 'n') )
+		if ((q[0] == 'N') || (q[0] == 'n')) {
                 exit(OK_EXIT);
         }
+	}
 
 	log_it(RealUser, Pid, "DELETE", User);
 	if (unlink(n)) {
@@ -441,8 +438,7 @@
         }
 
         /* Now create the actual temporary crontab file */
-        if (snprintf(Filename, MAX_FNAME, "%s/crontab", Directory)
-            >= MAX_FNAME) {
+	if (snprintf(Filename, MAX_FNAME, "%s/crontab", Directory) >= MAX_FNAME) {
                 fprintf(stderr, "Temporary filename too long - aborting\n");
                 Filename[0] = '\0';
                 return -1;
@@ -637,21 +633,15 @@
 		while (EOF != (ch = get_char(f)))
 			putc(ch, NewCrontab);
 	fclose(f);
-
 	if (ferror(NewCrontab)) {
 		fprintf(stderr, "%s: error while writing new crontab to %s\n",
 			ProgramName, Filename);
 	}
-
 	if (fstat(t, &fsbuf) < 0) {
 		perror("unable to stat temp file");
 		goto fatal;
 	}
 
-
-
-        /* Okay, edit the file */
-
 	if ((!((editor = getenv("VISUAL")) && strlen(editor)))
 	 && (!((editor = getenv("EDITOR")) && strlen(editor)))
 	    ) {
@@ -673,9 +663,6 @@
 	(void)signal(SIGINT, SIG_IGN);
 	(void)signal(SIGQUIT, SIG_IGN);
 
-        /* Give up privileges while editing */
-        swap_uids();
-
 	switch (pid = fork()) {
 	case -1:
 		perror("fork");
@@ -739,9 +726,6 @@
 	(void)signal(SIGQUIT, SIG_DFL);
 	(void)signal(SIGTSTP, SIG_DFL);
 
-        /* Need privs again */
-        swap_uids_back();
-
         switch (open_tmp_crontab(&fsbuf)) {
         case -1:
                 fprintf(stderr, "Error while editing crontab\n");
@@ -886,7 +870,7 @@
 	 */
 	Set_LineNum(1 - NHEADER_LINES)
 	CheckErrorCount = 0;  eof = FALSE;
-	while (!CheckErrorCount && !eof) {
+	while (!CheckErrorCount && !eof && LineNumber < MAX_TAB_LINES + 2) {
 		switch (load_env(envstr, tmp)) {
 		case ERR:
 			eof = TRUE;
@@ -903,6 +887,13 @@
 		}
 	}
 
+	if (LineNumber >= MAX_TAB_LINES + 2) {
+		fprintf(stderr, "crontab is too long; maximum number of lines "
+				"is %d.\n", MAX_TAB_LINES);
+		fclose(tmp);  unlink(tn);
+		return (-1);
+	}
+
 	if (CheckErrorCount != 0) {
 		fprintf(stderr, "errors in crontab file, can't install.\n");
 		fclose(tmp);  unlink(tn);
@@ -928,7 +919,6 @@
 		return (-2);
 	}
 
-
 	if (fclose(tmp) == EOF) {
 		perror("fclose");
 		unlink(tn);
@@ -951,8 +941,6 @@
 		unlink(tn);
 		return (-2);
 	}
-
-
 	log_it(RealUser, Pid, "REPLACE", User);
 
 	poke_daemon();
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/database.c cron-3.0pl1/database.c
--- cron-3.0pl1/database.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/database.c	2019-03-21 20:14:33.000000000 +0100
@@ -24,13 +24,12 @@
 
 
 #include "cron.h"
-#define __USE_GNU /* For O_NOFOLLOW */
 #include <fcntl.h>
-#undef __USE_GNU
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <time.h>
 
+
 #define TMAX(a,b) ((a)>(b)?(a):(b))
 
 /* Try to get maximum path name -- this isn't really correct, but we're
@@ -49,10 +48,8 @@
 static	void		process_crontab __P((char *, char *, char *,
 					     struct stat *,
 					     cron_db *, cron_db *));
-#ifdef DEBIAN
 static int valid_name (char *filename);
 static user *get_next_system_crontab __P((user *));
-#endif
 
 void force_rescan_user(cron_db *old_db, cron_db *new_db, const char *fname, time_t old_mtime);
 
@@ -69,13 +66,10 @@
 	DIR_T   	*dp;
 	cron_db		new_db;
 	user		*u, *nu;
-#ifdef DEBIAN
 	struct stat     syscrond_stat;
 	struct stat     syscrond_file_stat;
-	
         char            syscrond_fname[PATH_MAX+1];
 	int             syscrond_change = 0;
-#endif
 
 	Debug(DLOAD, ("[%d] load_database()\n", getpid()))
 
@@ -95,7 +89,6 @@
 		syscron_stat.st_mtime = 0;
 	}
 
-#ifdef DEBIAN
 	/* Check mod time of SYSCRONDIR. This won't tell us if a file
          * in it changed, but will capture deletions, which the individual
          * file check won't
@@ -141,7 +134,6 @@
 			Debug(DLOAD, (" [checked]\n"))
 		}
 	}
-#endif /* DEBIAN */
 
 	/* if spooldir's mtime has not changed, we don't need to fiddle with
 	 * the database.
@@ -150,14 +142,9 @@
 	 * so is guaranteed to be different than the stat() mtime the first
 	 * time this function is called.
 	 */
-#ifdef DEBIAN
 	if ((old_db->user_mtime == statbuf.st_mtime) &&
 	    (old_db->sys_mtime == syscron_stat.st_mtime) &&
 	    (!syscrond_change)) {
-#else
-	if ((old_db->user_mtime == statbuf.st_mtime) &&
-	    (old_db->sys_mtime == syscron_stat.st_mtime)) {
-#endif
 		Debug(DLOAD, ("[%d] spool dir mtime unch, no load needed.\n",
 			      getpid()))
 		return;
@@ -170,9 +157,7 @@
 	 */
 	new_db.user_mtime = statbuf.st_mtime;
 	new_db.sys_mtime = syscron_stat.st_mtime;
-#ifdef DEBIAN
 	new_db.sysd_mtime = syscrond_stat.st_mtime;
-#endif
 	new_db.head = new_db.tail = NULL;
 
 	if (syscron_stat.st_mtime) {
@@ -181,7 +166,6 @@
 				&new_db, old_db);
 	}
 
-#ifdef DEBIAN
 	/* Read all the package crontabs. */
 	if (!(dir = opendir(SYSCRONDIR))) {
 		log_it("CRON", getpid(), "OPENDIR FAILED", SYSCRONDIR);
@@ -219,7 +203,6 @@
 	}
 	if (dir)
 		closedir(dir);
-#endif
 
 	/* we used to keep this dir open all the time, for the sake of
 	 * efficiency.  however, we need to close it in every fork, and
@@ -308,7 +291,7 @@
 user *
 find_user(db, name)
 	cron_db	*db;
-	char	*name;
+	const char	*name;
 {
 	char	*env_get();
 	user	*u;
@@ -333,13 +316,9 @@
 	int		crontab_fd = OK - 1;
 	user		*u = NULL;
 
-#ifdef DEBIAN
 	/* If the name begins with *system*, don't worry about password -
 	 it's part of the system crontab */
 	if (strncmp(fname, "*system*", 8) && !(pw = getpwnam(uname))) {
-#else
-	if (strcmp(fname, "*system*") && !(pw = getpwnam(uname))) {
-#endif
 		/* file doesn't have a user in passwd file.
 		 */
 		if (strncmp(fname, "tmp.", 4)) {
@@ -365,6 +344,7 @@
             }
             /* Check to make sure that the crontab is owned by the correct user
                (or root) */
+
             if (statbuf->st_uid != pw->pw_uid && statbuf->st_uid != ROOT_UID) {
                 log_it(fname, getpid(), "WRONG FILE OWNER", tabname);
                 force_rescan_user(old_db, new_db, fname, 0);
@@ -404,20 +384,20 @@
             }
             if ((crontab_fd = open(tabname, O_RDONLY, 0)) < OK) {
 		/* crontab not accessible?
-
-		   If tabname is a symlink, it's most probably just broken, so
-		   we force a rescan. Once the link is fixed, it will get picked
-		   up and processed again. If tabname is a regular file, this
-		   error is bad so we skip it instead.
+			 *
+			 * If tabname is a symlink, it's most probably just
+			 * broken, so we force a rescan. Once the link is
+			 * fixed, it will get picked up and processed again. If
+			 * tabname is a regular file, this error is bad, so we
+			 * skip it instead.
 		 */
 		if (S_ISLNK(statbuf->st_mode)) {
                     log_it(fname, getpid(), "CAN'T OPEN SYMLINK", tabname);
                     force_rescan_user(old_db, new_db, fname, 0);
-                    goto next_crontab;
                 } else {
 		    log_it(fname, getpid(), "CAN'T OPEN", tabname);
-		    goto next_crontab;
 		}
+			goto next_crontab;
             }
 
             if (fstat(crontab_fd, statbuf) < OK) {
@@ -461,6 +441,7 @@
 		goto next_crontab;
 	    }
         }
+
         /*
          * The link count check is not sufficient (the owner may
          * delete their original link, reducing the link count back to
@@ -509,7 +490,6 @@
                 force_rescan_user(old_db, new_db, fname, statbuf->st_mtime);
         }   
 
-
 next_crontab:
 	if (crontab_fd >= OK) {
 		Debug(DLOAD, (" [done]\n"))
@@ -517,7 +497,6 @@
 	}
 }
 
-#ifdef DEBIAN
 
 #include <regex.h>
 
@@ -568,8 +547,6 @@
 	return curtab;
 }
 
-#endif
-
 /* Force rescan of a crontab the next time cron wakes up
  *
  * cron currently only detects changes caused by an mtime update; it does not
@@ -595,10 +572,12 @@
 	/* Allocate an empty crontab with the specified mtime, add it to new DB */
         if ((u = (user *) malloc(sizeof(user))) == NULL) {
                 errno = ENOMEM;
+		return;
         }   
         if ((u->name = strdup(fname)) == NULL) {
                 free(u);
                 errno = ENOMEM;
+		return;
         }   
         u->mtime = old_mtime;
         u->crontab = NULL;
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/debian/NEWS cron-3.0pl1/debian/NEWS
--- cron-3.0pl1/debian/NEWS	1970-01-01 01:00:00.000000000 +0100
+++ cron-3.0pl1/debian/NEWS	2019-03-21 20:14:33.000000000 +0100
@@ -0,0 +1,9 @@
+cron (3.0pl1-133) unstable; urgency=medium
+
+  * As a reasonable protective measure, crontabs are now limited to 1000 lines
+    in length per crontab.
+    The maintainers find it very unlikely that longer crontabs exist; however,
+    if you do have a use case, please file a bug report with a brief rationale,
+    and we will consider raising this limit.
+
+ -- Christian Kastner <ckk@debian.org>  Sun, 10 Mar 2019 17:44:13 +0100
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/do_command.c cron-3.0pl1/do_command.c
--- cron-3.0pl1/do_command.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/do_command.c	2019-03-21 20:14:33.000000000 +0100
@@ -132,7 +132,6 @@
 	char		*usernm, *mailto;
 	int		children = 0;
 	pid_t		job_pid;
-
 #if defined(USE_PAM)
 	int		retcode = 0;
 #endif
@@ -172,15 +171,11 @@
 #ifdef USE_SIGCHLD
 	/* our parent is watching for our death by catching SIGCHLD.  we
 	 * do not care to watch for our children's deaths this way -- we
-	 * use wait() explictly.  so we have to disable the signal (which
+	 * use wait() explictly.  so we have to reset the signal (which
 	 * was inherited from the parent).
 	 */
-#ifdef DEBIAN
 	(void) signal(SIGCHLD, SIG_DFL);
 #else
-	(void) signal(SIGCHLD, SIG_IGN);
-#endif
-#else
 	/* on system-V systems, we are ignoring SIGCLD.  we have to stop
 	 * ignoring it now or the wait() in cron_pclose() won't work.
 	 * because of this, we have to wait() for our children here, as well.
@@ -245,7 +240,6 @@
 	PAM_FAIL_CHECK;
 	retcode = pam_open_session(pamh, PAM_SILENT);
 	PAM_FAIL_CHECK;
-
 #endif
 
 	/* fork again, this time so we can exec the user's command.
@@ -288,11 +282,9 @@
 		/* grandchild process.  make std{in,out} be the ends of
 		 * pipes opened by our daddy; make stderr go to stdout.
 		 */
-		/* Closes are unnecessary -- let dup2() do it */
-
-		  /* close(STDIN) */; dup2(stdin_pipe[READ_PIPE], STDIN);
+		dup2(stdin_pipe[READ_PIPE], STDIN);
 		  dup2(fileno(tmpout), STDOUT);
-		  /* close(STDERR)*/; dup2(STDOUT, STDERR);
+		dup2(STDOUT, STDERR);
 
 
 		/* close the pipe we just dup'ed.  The resources will remain.
@@ -348,26 +340,20 @@
 				_exit(OK_EXIT);
 			}
 # endif /*DEBUGGING*/
-#if 0
-			{
-			  struct sigaction oact;
-			  sigaction(SIGCHLD, NULL, &oact);
-			}
-			fprintf(stdout,"error");
-#endif
 #ifdef WITH_SELINUX
 			if (is_selinux_enabled() > 0) {
 			    if (u->scontext != 0L) {
-                                if (setexeccon(u->scontext) < 0) {
-                                    if (security_getenforce() > 0) {
-                                        fprintf(stderr, "Could not set exec context to %s for user  %s\n", u->scontext,u->name);
+					if (setexeccon(u->scontext) < 0 &&
+							security_getenforce() > 0) {
+						fprintf(stderr, "Could not set exec context "
+								"to %s for user  %s\n",
+								u->scontext,u->name);
                                         _exit(ERROR_EXIT);
                                     }
-			        }
-                            }
-			    else if(security_getenforce() > 0)
-			    {
-                                fprintf(stderr, "Error, must have a security context for the cron job when in enforcing mode.\nUser %s.\n", u->name);
+				} else if (security_getenforce() > 0) {
+					fprintf(stderr, "Error, must have a security context "
+							"for the cron job when in enforcing "
+							"mode.\nUser %s.\n", u->name);
                                 _exit(ERROR_EXIT);
 			    }
 			}
@@ -513,7 +499,6 @@
 	
 	long pos;
 	struct stat	mcsb;
-	int		statret;	
 
 	fseek(tmpout, 0, SEEK_END);
 	pos = ftell(tmpout);
@@ -531,7 +516,7 @@
                 goto mail_finished;
 
 	/* Don't send mail if MAILCMD is not available */
-	if ((statret = stat(MAILCMD, &mcsb)) != 0) {
+	if (stat(MAILCMD, &mcsb) != 0) {
 		Debug(DPROC|DEXT, ("%s not found, not sending mail\n", MAILCMD))
 		if (pos > 0) {
 			log_it("CRON", getpid(), "info", "No MTA installed, discarding output");
@@ -569,10 +554,10 @@
 			arpadate(&StartTime));
 # endif /* MAIL_DATE */
 	fprintf(mail, "MIME-Version: 1.0\n");
+
 	if ( content_type == 0L ) {
 		fprintf(mail, "Content-Type: text/plain; charset=%s\n",
-				cron_default_mail_charset
-		       );
+			cron_default_mail_charset);
 	} else {   
 		/* user specified Content-Type header.
 		 * disallow new-lines for security reasons
@@ -581,24 +566,28 @@
 		char *nl=content_type;
 		size_t ctlen = strlen(content_type);
 
-		while(  (*nl != '\0')
-				&& ((nl=strchr(nl,'\n')) != 0L)
-				&& (nl < (content_type+ctlen))
-		     ) *nl = ' ';
+		while ((*nl != '\0') &&
+				((nl=strchr(nl,'\n')) != 0L) &&
+				(nl < (content_type+ctlen))) {
+			*nl = ' ';
+		}
 		fprintf(mail,"Content-Type: %s\n", content_type);
 	}
+
 	if ( content_transfer_encoding != 0L ) {
 		char *nl=content_transfer_encoding;
 		size_t ctlen = strlen(content_transfer_encoding);
-		while(  (*nl != '\0')
-				&& ((nl=strchr(nl,'\n')) != 0L)
-				&& (nl < (content_transfer_encoding+ctlen))
-		     ) *nl = ' ';
-
-		fprintf(mail,"Content-Transfer-Encoding: %s\n", content_transfer_encoding);
+		while ((*nl != '\0') &&
+				((nl = strchr(nl,'\n')) != 0L) &&
+				(nl < (content_transfer_encoding+ctlen))) {
+			*nl = ' ';
 	}
-	else
+
+		fprintf(mail,"Content-Transfer-Encoding: %s\n",
+				content_transfer_encoding);
+	} else {
 		fprintf(mail, "Content-Transfer-Encoding: 8bit\n");
+	}
 
 	for (env = e->envp;  *env;  env++)
 		fprintf(mail, "X-Cron-Env: <%s>\n",
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/entry.c cron-3.0pl1/entry.c
--- cron-3.0pl1/entry.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/entry.c	2019-03-21 20:14:33.000000000 +0100
@@ -108,6 +108,10 @@
 	 */
 
 	e = (entry *) calloc(sizeof(entry), sizeof(char));
+	if (e == NULL) {
+		log_it("CRON", getpid(), "OOM", "Out of memory parsing crontab");
+		return NULL;
+	}
 
 	if (ch == '@') {
 		/* all of these should be flagged and load-limited; i.e.,
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/env.c cron-3.0pl1/env.c
--- cron-3.0pl1/env.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/env.c	2019-03-21 20:14:33.000000000 +0100
@@ -278,7 +278,7 @@
 	register int	len = strlen(name);
 	register char	*p, *q;
 
-	while ((p = *envp++)) {
+	while ((p = *envp++) != NULL) {
 		if (!(q = strchr(p, '=')))
 			continue;
 		if ((q - p) == len && !strncmp(p, name, len))
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/externs.h cron-3.0pl1/externs.h
--- cron-3.0pl1/externs.h	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/externs.h	2019-03-21 20:14:33.000000000 +0100
@@ -61,7 +61,6 @@
 extern	void		perror(), exit(), free();
 extern	char		*getenv(), *strcpy(), *strchr(), *strtok();
 extern	void		*malloc(), *realloc();
-
 # define SIG_T	void
 # define TIME_T	long
 # define PID_T int
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/Makefile cron-3.0pl1/Makefile
--- cron-3.0pl1/Makefile	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/Makefile	2019-03-21 20:14:33.000000000 +0100
@@ -57,8 +57,8 @@
 #<<need getopt()>>
 LIBS		= $(PAM_LIBS) $(SELINUX_LIBS) $(AUDIT_LIBS)
 #<<optimize or debug?>>
-OPTIM		=	-O2
-#OPTIM		=	-g
+#OPTIM		=	-O
+OPTIM		=	-g
 #<<ATT or BSD or POSIX?>>
 # (ATT untested)
 #COMPAT		=	-DATT
@@ -73,17 +73,14 @@
 #<<manifest defines>>
 # Allow override from command line
 DEBUG_DEFS  ?= -DDEBUGGING=0   
-# The -DUSE_SIGCHLD is needed for the Alpha port
-DEFS = -DDEBIAN -DUSE_SIGCHLD $(DEBUG_DEFS) $(PAM_DEFS) $(SELINUX_DEFS) $(AUDIT_DEFS)
+DEFS		= $(DEBUG_DEFS) $(PAM_DEFS) $(SELINUX_DEFS) $(AUDIT_DEFS)
 #(SGI IRIX systems need this)
 #DEFS		=	-D_BSD_SIGNALS -Dconst=
 #<<the name of the BSD-like install program>>
 #INSTALL = installbsd
-INSTALL = install -s
+INSTALL = install
 #<<any special load flags>>
-# LDFLAGS		=	-s
-# Let install do the strip
-
+#LDFLAGS		=
 #################################### end configurable stuff
 
 SHELL		=	/bin/sh
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/misc.c cron-3.0pl1/misc.c
--- cron-3.0pl1/misc.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/misc.c	2019-03-21 20:14:33.000000000 +0100
@@ -213,8 +213,7 @@
 			fprintf(stderr, "%s: created\n", CRONDIR);
 			stat(CRONDIR, &sb);
 		} else {
-			fprintf(stderr, "%s: mkdir: %s\n", CRONDIR,
-				strerror(errno));
+			fprintf(stderr, "%s: mkdir: %s\n", CRONDIR, strerror(errno));
 			exit(ERROR_EXIT);
 		}
 		(void) umask(um);
@@ -331,7 +330,6 @@
 	/* abandon fd and fp even though the file is open. we need to
 	 * keep it open and locked, but we don't need the handles elsewhere.
 	 */
-	
 }
 
 /* get_char(file) : like getc() but increment LineNumber on newlines
@@ -344,7 +342,7 @@
 
 	ch = getc(file);
 	if (ch == '\n')
-		Set_LineNum(LineNumber + 1);
+		Set_LineNum(LineNumber + 1)
 	return ch;
 }
 
@@ -358,7 +356,7 @@
 {
 	ungetc(ch, file);
 	if (ch == '\n')
-	       Set_LineNum(LineNumber - 1);
+		Set_LineNum(LineNumber - 1)
 }
 
 
@@ -479,7 +477,23 @@
 		init = TRUE;
 #if defined(ALLOW_FILE) && defined(DENY_FILE)
 		allow = fopen(ALLOW_FILE, "r");
+		if (allow == NULL) {
+			/* Only if the file does not exist do we ignore the
+			 * error. Otherwise, we deny by default.
+			 */
+			if (errno != ENOENT) {
+				perror(ALLOW_FILE);
+				return FALSE;
+			}
+		}
 		deny = fopen(DENY_FILE, "r");
+		if (allow == NULL) {
+			/* See above */
+			if (errno != ENOENT) {
+				perror(DENY_FILE);
+				return FALSE;
+			}
+		}
 		Debug(DMISC, ("allow/deny enabled, %d/%d\n", !!allow, !!deny))
 #else
 		allow = NULL;
@@ -515,15 +529,14 @@
 	char	*event;
 	char	*detail;
 {
-#if defined(LOG_FILE)
 	PID_T			pid = xpid;
+#if defined(LOG_FILE)
 	char			*msg;
 	TIME_T			now = time((TIME_T) 0);
 	register struct tm	*t = localtime(&now);
 	int 			msg_size;
 #endif /*LOG_FILE*/
 
-
 #if defined(LOG_FILE)
 	/* we assume that MAX_TEMPSTR will hold the date, time, &punctuation.
 	 */
@@ -567,15 +580,6 @@
 #endif /*LOG_FILE*/
 
 #if defined(SYSLOG)
-
-
-	    /* we don't use LOG_PID since the pid passed to us by
-	     * our client may not be our own.  therefore we want to
-	     * print the pid ourselves.
-	     */
-	    /* SteveG says: That comment is not consistent with the
-	       code, and makes no sense -- I suspect it's a remnant
-	       of a cut-n-paster... */
 # ifdef LOG_CRON
 	openlog(ProgramName, LOG_PID, LOG_CRON);
 # else
@@ -584,7 +588,6 @@
 	  
 	syslog(LOG_INFO, "(%s) %s (%s)", username, event, detail);
 
-	closelog();
 #endif /*SYSLOG*/
 
 #if DEBUGGING
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/pathnames.h cron-3.0pl1/pathnames.h
--- cron-3.0pl1/pathnames.h	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/pathnames.h	2019-03-21 20:14:33.000000000 +0100
@@ -19,7 +19,7 @@
  * $Id: pathnames.h,v 1.3 1994/01/15 20:43:43 vixie Exp $
  */
 
-#if (defined(BSD)) && (BSD >= 199103) || defined(__linux__) || defined(AIX) || defined(__GNU__) || defined(__GLIBC__)
+#if (defined(BSD)) && (BSD >= 199103) || defined(__linux__) || defined(AIX) || defined(__GLIBC__)
 # include <paths.h>
 #endif /*BSD*/
 
@@ -47,14 +47,9 @@
 			 * LOG_FILE or SYSLOG is defined, we don't log.  If
 			 * both are defined, we log both ways.
 			 */
-#ifdef DEBIAN
 #define	ALLOW_FILE	"/etc/cron.allow"		/*-*/
 #define DENY_FILE	"/etc/cron.deny"		/*-*/
-#else
-#define	ALLOW_FILE	"allow"		/*-*/
-#define DENY_FILE	"deny"		/*-*/
-#endif
-/* #define LOG_FILE	"log"		  -*/
+/* #define LOG_FILE	"log"		/*-*/
 
 			/* where should the daemon stick its PID?
 			 */
@@ -67,20 +62,13 @@
 
 			/* 4.3BSD-style crontab */
 #define SYSCRONTAB	"/etc/crontab"
-#ifdef DEBIAN
                         /* where package specific crontabs live */ 
 #define SYSCRONDIR      "/etc/cron.d"
-#endif
+
 			/* what editor to use if no EDITOR or VISUAL
 			 * environment variable specified.
 			 */
-#if defined(DEBIAN)
 # define EDITOR "/usr/bin/sensible-editor"
-#elif defined(_PATH_VI)
-# define EDITOR _PATH_VI
-#else
-# define EDITOR "/usr/ucb/vi"
-#endif
 
 #ifndef _PATH_BSHELL
 # define _PATH_BSHELL "/bin/sh"
@@ -90,12 +78,11 @@
 # define _PATH_DEFPATH "/usr/bin:/bin"
 #endif
 
-#ifndef _PATH_DEFPATH_ROOT
-# define _PATH_DEFPATH_ROOT "/usr/sbin:/usr/bin:/sbin:/bin"
+#ifndef REBOOT_FILE
+# define REBOOT_FILE "/run/crond.reboot"
 #endif
 
 
-#ifdef DEBIAN
 #ifndef CRONDIR_MODE
 			/* Create mode for CRONDIR; must be in sync with
 			 * packaging
@@ -114,4 +101,3 @@
 			 */ 
 #define SPOOL_DIR_GROUP "crontab"
 #endif
-#endif
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/popen.c cron-3.0pl1/popen.c
--- cron-3.0pl1/popen.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/popen.c	2019-03-21 20:14:33.000000000 +0100
@@ -148,7 +148,6 @@
 		  exit(ERROR_EXIT);
 		}	
 		chdir(env_get("HOME", e->envp));
-
 #if WANT_GLOBBING
 		execvp(gargv[0], gargv);
 #else
diff -Nru -w --exclude crontab.1 --exclude crontab.5 --exclude cron.8 cron-3.0pl1/user.c cron-3.0pl1/user.c
--- cron-3.0pl1/user.c	2019-03-21 20:14:32.000000000 +0100
+++ cron-3.0pl1/user.c	2019-03-21 20:14:33.000000000 +0100
@@ -58,9 +58,7 @@
             freecon(current_con);
             return (security_getenforce() > 0);
         }
-    }
-    else
-    {
+	} else {
         context_t temp_con = context_new(current_con);
         if (temp_con == NULL) {
             log_it(name, getpid(), "context_new FAILED", tabname);
@@ -110,8 +108,7 @@
      * permission check for this purpose.
      */
 
-    for(i = 0; i < list_count; i++)
-    {
+	for (i = 0; i < list_count; i++) {
         retval = security_compute_av(context_list[i],
                                  file_context,
                                  SECCLASS_FILE,
@@ -139,7 +136,6 @@
 #endif
 
 
-#ifdef DEBIAN
 /* Function used to log errors in crontabs from cron daemon. (User
    crontabs are checked before they're accepted, but system crontabs
    are not. */
@@ -163,8 +159,6 @@
   }
 }
 
-#endif
-
 void
 free_user(u)
 	user	*u;
@@ -236,7 +230,6 @@
         }
 #endif
 
-
 	/* 
 	 * init environment.  this will be copied/augmented for each entry.
 	 */
@@ -249,6 +242,7 @@
 	/*
 	 * load the crontab
 	 */
+	Set_LineNum(1)
 	do {
 		status = load_env(envstr, file);
 		switch (status) {
@@ -268,13 +262,9 @@
 			}
 			goto done;
 		case FALSE:
-#ifdef DEBIAN
 			err_user = fname;
 			e = load_entry(file, crontab_error, pw, envp);
 			err_user = NULL;
-#else
-			e = load_entry(file, NULL, pw, envp);
-#endif
 			if (e) {
 				e->next = u->crontab;
 				u->crontab = e;
@@ -298,7 +288,19 @@
 			}
 			break;
 		}
-	} while (status >= OK);
+	/* When counting lines, ignore the user-hidden header part, and account
+	 * for idiosyncrasies of LineNumber manipulation
+	 */
+	} while (status >= OK && LineNumber < MAX_TAB_LINES + NHEADER_LINES + 2);
+
+	if (LineNumber >= MAX_TAB_LINES + NHEADER_LINES + 2) {
+		log_it(fname, getpid(), "ERROR", "crontab must not be longer "
+				"than " Stringify(MAX_TAB_LINES) " lines, "
+				"this crontab file will be ignored");
+		free_user(u);
+		u = NULL;
+		goto done;
+	}
 
  done:
 	env_free(envp);

--- End Message ---
--- Begin Message ---
Hi,

I did unblock it, but please try to be more careful next time to avoid the
large diff.

On Mon, Mar 25, 2019 at 05:21:49PM +0100, Christian Kastner wrote:
> brief update: Since the upload, one new bug has been reported for one of
> the security fixes, which had been cherry-picked for jessie-security.
> See below.
> 
> Otherwise, -133 has not triggered any new bug reports so far.
> 
> On 2019-03-21 20:19:01 +0100 Christian Kastner wrote:> I'd like to
> request an unblock for cron/3.0pl1-133. The notable changes
> > are smallish, and mainly concern security fixes that have been assigned
> > CVE-2019-9704, -9705, and -9706 in the meantime. One of these fixes
> > (limiting crontabs to 1000 lines) required a debian/NEWS entry.
> 
> Contrary to my expectations, it appears that users with crontabs longer
> than 1000 lines do exist. In #925276, a user reported hitting this limit
> with a programmatically generated crontab.
> 
> I would like to fix this by making the limit configurable, that is:
> defaulting to 1.000 lines, but allowing a different limit in
> /etc/default/cron, with a corresponding update to debian/NEWS.
> 
> However, I'd appreciate your feedback on the -133 changes, before adding
> new ones on top of that.

Once you get confirmation that -133 is in testing, you can upload a targeted
fix for these issues and file a new unblock request.

Thanks,

Ivo

--- End Message ---

Reply to: