From: Christian Kastner <ckk@kvr.at>
Date: Sat, 26 Dec 2015 00:02:08 +0100
Subject: Improve mode checks for crontabs

Improve mode checks for crontabs to improve security. Specifically, check for:
 * Invalid owner
 * Invalid filetype
 * Insecure mode
 * Hard links

 Forwarded: no
 Last-Update: 2015-12-26
Index: cron/database.c
===================================================================
--- cron.orig/database.c
+++ cron/database.c
@@ -222,7 +222,7 @@ process_crontab(uname, fname, tabname, s
 		goto next_crontab;
 	}
 
-	if ((crontab_fd = open(tabname, O_RDONLY, 0)) < OK) {
+	if ((crontab_fd = open(tabname, O_RDONLY|O_NOFOLLOW, 0)) < OK) {
 		/* crontab not accessible?
 		 */
 		log_it(fname, getpid(), "CAN'T OPEN", tabname);
@@ -233,6 +233,32 @@ process_crontab(uname, fname, tabname, s
 		log_it(fname, getpid(), "FSTAT FAILED", tabname);
 		goto next_crontab;
 	}
+	/* 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);
+		goto next_crontab;
+	}
+
+	/* Check to make sure that the crontab is a regular file */
+	if (!S_ISREG(statbuf->st_mode)) {
+		log_it(fname, getpid(), "NOT A REGULAR FILE", tabname);
+		goto next_crontab;
+	}
+
+	/* Check to make sure that the crontab's permissions are secure */
+	if ((statbuf->st_mode & 07777) != 0600) {
+		log_it(fname, getpid(), "INSECURE MODE (mode 0600 expected)", tabname);
+		goto next_crontab;
+	}
+
+	/* Check to make sure that there are no hardlinks to the crontab */
+	if (statbuf->st_nlink != 1) {
+		log_it(fname, getpid(), "NUMBER OF HARD LINKS > 1", tabname);
+		goto next_crontab;
+	}
 
 	Debug(DLOAD, ("\t%s:", fname))
 	u = find_user(old_db, fname);
Index: cron/cron.8
===================================================================
--- cron.orig/cron.8
+++ cron/cron.8
@@ -41,6 +41,8 @@ command should be used to access and upd
 .I cron
 also reads /etc/crontab, which is in a slightly different format (see
 .IR crontab (5)).
+/etc/crontab must be owned by root, and must not
+be group-or other-writable.
 .I cron
 then wakes up every minute, examining all stored crontabs, checking
 each command to see if it should be run in the current minute.  When
