Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/cron/dist - Don't allow bypassing file size lim...
details: https://anonhg.NetBSD.org/src/rev/c60b85e32adc
branches: trunk
changeset: 334933:c60b85e32adc
user: christos <christos%NetBSD.org@localhost>
date: Mon Dec 15 16:45:26 2014 +0000
description:
- Don't allow bypassing file size limits with crontabs from stdin.
- Allow signals while reading the user crontab file; doing "crontab -"
does not let you abort otherwise, and doing ^Z, kill %1 leaves turds
in /var/cron/tabs
diffstat:
external/bsd/cron/dist/crontab.c | 215 ++++++++++++++++++++++++--------------
1 files changed, 135 insertions(+), 80 deletions(-)
diffs (truncated from 307 to 300 lines):
diff -r 346353b5abc0 -r c60b85e32adc external/bsd/cron/dist/crontab.c
--- a/external/bsd/cron/dist/crontab.c Mon Dec 15 15:49:25 2014 +0000
+++ b/external/bsd/cron/dist/crontab.c Mon Dec 15 16:45:26 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: crontab.c,v 1.11 2014/09/07 13:34:12 joerg Exp $ */
+/* $NetBSD: crontab.c,v 1.12 2014/12/15 16:45:26 christos Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
@@ -25,7 +25,7 @@
#if 0
static char rcsid[] = "Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp";
#else
-__RCSID("$NetBSD: crontab.c,v 1.11 2014/09/07 13:34:12 joerg Exp $");
+__RCSID("$NetBSD: crontab.c,v 1.12 2014/12/15 16:45:26 christos Exp $");
#endif
#endif
@@ -169,7 +169,7 @@
{
struct timespec ts1[2];
get_time(st, ts1);
-
+
return ts1[1].tv_sec == ts2[1].tv_sec
#if defined(HAVE_UTIMENSAT)
&& ts1[1].tv_nsec == ts2[1].tv_nsec
@@ -286,7 +286,7 @@
{
int ch;
int x;
-
+
/* ignore the top few comments since we probably put them there.
*/
for (x = 0; x < NHEADER_LINES; x++) {
@@ -554,50 +554,12 @@
log_it(RealUser, Pid, "END EDIT", User);
}
-/* returns 0 on success
- * -1 on syntax error
- * -2 on install error
- */
-static int
-replace_cmd(void) {
- char n[MAX_FNAME], n2[MAX_FNAME], envstr[MAX_ENVSTR];
- int lastch;
- FILE *tmp, *fmaxtabsize;
- int ch, eof, fd;
- int error = 0;
- entry *e;
- sig_t oint, oabrt, oquit, ohup;
- uid_t file_owner;
- time_t now = time(NULL);
- char **envp = env_init();
- size_t maxtabsize;
- struct stat statbuf;
-
- if (envp == NULL) {
- warn("Cannot allocate memory.");
- return (-2);
- }
-
- if (!glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR,
- "tmp.XXXXXXXXXX", '/')) {
- TempFilename[0] = '\0';
- warnx("path too long");
- return (-2);
- }
- if ((fd = mkstemp(TempFilename)) == -1 || !(tmp = fdopen(fd, "w+"))) {
- warn("cannot create `%s'", TempFilename);
- if (fd != -1) {
- (void)close(fd);
- (void)unlink(TempFilename);
- }
- TempFilename[0] = '\0';
- return (-2);
- }
-
- ohup = signal(SIGHUP, SIG_IGN);
- oint = signal(SIGINT, SIG_IGN);
- oquit = signal(SIGQUIT, SIG_IGN);
- oabrt = signal(SIGABRT, SIG_IGN);
+static size_t
+getmaxtabsize(void)
+{
+ char n2[MAX_FNAME];
+ FILE *fmaxtabsize;
+ size_t maxtabsize;
/* Make sure that the crontab is not an unreasonable size.
*
@@ -611,44 +573,138 @@
*/
(void)snprintf(n2, sizeof(n2), "%s/%s", CRONDIR, MAXTABSIZE_FILE);
if ((fmaxtabsize = fopen(n2, "r")) != NULL) {
- if (fgets(n2, (int)sizeof(n2), fmaxtabsize) == NULL) {
- maxtabsize = 0;
- } else {
- maxtabsize = (size_t)atoi(n2);
- }
- (void)fclose(fmaxtabsize);
+ if (fgets(n2, (int)sizeof(n2), fmaxtabsize) == NULL) {
+ maxtabsize = 0;
+ } else {
+ maxtabsize = (size_t)atoi(n2);
+ }
+ (void)fclose(fmaxtabsize);
} else {
- maxtabsize = MAXTABSIZE_DEFAULT;
+ maxtabsize = MAXTABSIZE_DEFAULT;
+ }
+ return maxtabsize;
+}
+
+static int
+checkmaxtabsize(FILE *fp, size_t maxtabsize)
+{
+ struct stat statbuf;
+
+ if (fstat(fileno(fp), &statbuf)) {
+ warn("error stat'ing crontab input");
+ return 0;
+ }
+ if ((uintmax_t)statbuf.st_size > (uintmax_t)maxtabsize) {
+ warnx("%ju bytes is larger than the maximum size of %ju bytes",
+ (uintmax_t)statbuf.st_size, (uintmax_t)maxtabsize);
+ return 0;
+ }
+ return 1;
+}
+
+static void
+cleanTempFile(void)
+{
+
+ if (TempFilename[0]) {
+ (void) unlink(TempFilename);
+ TempFilename[0] = '\0';
+ }
+}
+
+static void
+bail(int signo)
+{
+
+ cleanTempFile();
+ errx(ERROR_EXIT, "Exiting on signal %d", signo);
+}
+
+/* returns 0 on success
+ * -1 on syntax error
+ * -2 on install error
+ */
+static int
+replace_cmd(void) {
+ char n[MAX_FNAME], envstr[MAX_ENVSTR];
+ int lastch;
+ FILE *tmp = NULL;
+ int ch, eof, fd;
+ int error = 0;
+ entry *e;
+ sig_t oint, oabrt, oquit, ohup;
+ uid_t file_owner;
+ time_t now = time(NULL);
+ char **envp = env_init();
+ size_t i, maxtabsize;
+
+ if (envp == NULL) {
+ warn("Cannot allocate memory.");
+ return (-2);
}
- if (fstat(fileno(NewCrontab), &statbuf)) {
- warn("error stat'ing crontab input");
- error = -2;
- goto done;
+ if (!glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR,
+ "tmp.XXXXXXXXXX", '/')) {
+ TempFilename[0] = '\0';
+ warnx("path too long");
+ return (-2);
}
- if ((uintmax_t)statbuf.st_size > (uintmax_t)maxtabsize) {
- warnx("%ld bytes is larger than the maximum size of %ld bytes",
- (long) statbuf.st_size, (long) maxtabsize);
- error = -2;
- goto done;
+
+ /* Interruptible while doing I/O */
+ ohup = signal(SIGHUP, bail);
+ oint = signal(SIGINT, bail);
+ oquit = signal(SIGQUIT, bail);
+ oabrt = signal(SIGABRT, bail);
+
+ if ((fd = mkstemp(TempFilename)) == -1 || !(tmp = fdopen(fd, "w+"))) {
+ warn("cannot create `%s'", TempFilename);
+ if (fd != -1)
+ (void)close(fd);
+ error = -2;
+ goto done;
+ }
+
+ maxtabsize = getmaxtabsize();
+
+ /* This does not work for stdin, so we'll also check later */
+ if (!checkmaxtabsize(NewCrontab, maxtabsize)) {
+ error = -2;
+ goto done;
}
/* write a signature at the top of the file.
*
* VERY IMPORTANT: make sure NHEADER_LINES agrees with this code.
*/
- (void)fprintf(tmp, "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n");
- (void)fprintf(tmp, "# (%s installed on %-24.24s)\n", Filename, ctime(&now));
- (void)fprintf(tmp, "# (Cron version %s -- %s)\n", CRON_VERSION, "$NetBSD: crontab.c,v 1.11 2014/09/07 13:34:12 joerg Exp $");
+ (void)fprintf(tmp,
+ "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n");
+ (void)fprintf(tmp,
+ "# (%s installed on %-24.24s)\n", Filename, ctime(&now));
+ (void)fprintf(tmp,
+ "# (Cron version %s -- %s)\n", CRON_VERSION,
+ "$NetBSD: crontab.c,v 1.12 2014/12/15 16:45:26 christos Exp $");
/* copy the crontab to the tmp
*/
(void)rewind(NewCrontab);
Set_LineNum(1);
lastch = EOF;
- while (EOF != (ch = get_char(NewCrontab)))
+ for (i = 0; i < maxtabsize && EOF != (ch = get_char(NewCrontab)); i++)
(void)putc(lastch = (char)ch, tmp);
+ /* Non-Interruptible while installing */
+ (void)signal(SIGHUP, SIG_IGN);
+ (void)signal(SIGINT, SIG_IGN);
+ (void)signal(SIGQUIT, SIG_IGN);
+ (void)signal(SIGABRT, SIG_IGN);
+
+ if (i == maxtabsize) {
+ warnx("is larger than the maximum size of %ju bytes",
+ (uintmax_t)maxtabsize);
+ error = -2;
+ goto done;
+ }
+
if (lastch != EOF && lastch != '\n') {
warnx("missing trailing newline in `%s'", Filename);
error = -1;
@@ -666,7 +722,6 @@
(void)fflush(tmp);
if (ferror(tmp)) {
- (void)fclose(tmp);
warn("error while writing new crontab to `%s'", TempFilename);
error = -2;
goto done;
@@ -704,7 +759,6 @@
if (CheckErrorCount != 0) {
warnx("errors in crontab file, can't install.");
- (void)fclose(tmp);
error = -1;
goto done;
}
@@ -716,16 +770,18 @@
#else
error = chown(TempFilename, file_owner, (gid_t)-1);
#endif
- if (error < OK) {
- warn("cannot chown `%s'", TempFilename);
- (void)fclose(tmp);
- error = -2;
- goto done;
- }
if (fclose(tmp) == EOF) {
warn("error closing file");
error = -2;
+ tmp = NULL;
+ goto done;
+ }
+ tmp = NULL;
+
+ if (error < OK) {
+ warn("cannot chown `%s'", TempFilename);
+ error = -2;
goto done;
}
@@ -749,10 +805,9 @@
(void)signal(SIGINT, oint);
(void)signal(SIGQUIT, oquit);
(void)signal(SIGABRT, oabrt);
- if (TempFilename[0]) {
- (void) unlink(TempFilename);
- TempFilename[0] = '\0';
Home |
Main Index |
Thread Index |
Old Index