Date: Thu, 26 Oct 2000 18:30:55 +0100 From: David Malone <dwmalone@maths.tcd.ie> To: audit@freebsd.org Cc: kris@freebsd.org, rwatson@freebsd.org Subject: Patch for crontab. Message-ID: <200010261830.aa94658@salmon.maths.tcd.ie>
next in thread | raw e-mail | index | archive | help
Can someone review this for me? It's a fix for the crontab problem
based on what OpenBSD have done. We used to reopen NewCrontab after
editing as root and reread the file. The patch I suggested last
night just changed who we opened the file as (which works OK).
What OpenBSD have done is arange to keep NewCrontab open during
the edit. Then they just rewind and reread the file. This has the
advantage that people just can't make a symlink to /dev/zero or
/dev/random. Crontab would happily copy these byte-by-byte into
the crontab spool directory.
The down side to the OpenBSD patch is that it won't work with
editors which unlink the file they are editing. Vi, vim, emacs,
xemacs and ee all do the right thing so it looks like it isn't
going to bite too many people.
To try to alert people who might get caught by this I've aranged
for the temp file to be stated and compared to the results of fstat
for the file crontab has open. If they don't match it gives a
warning and exits. This way edits made to crontab with fooedit
don't silently fail.
David.
Index: crontab.c
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/usr.sbin/cron/crontab/crontab.c,v
retrieving revision 1.13
diff -u -r1.13 crontab.c
--- crontab.c 2000/10/15 00:35:34 1.13
+++ crontab.c 2000/10/26 16:59:47
@@ -285,7 +285,7 @@
char n[MAX_FNAME], q[MAX_TEMPSTR], *editor;
FILE *f;
int ch, t, x;
- struct stat statbuf;
+ struct stat statbuf, fsbuf;
time_t mtime;
WAIT_T waiter;
PID_T pid, xpid;
@@ -317,7 +317,7 @@
warn("fchown");
goto fatal;
}
- if (!(NewCrontab = fdopen(t, "w"))) {
+ if (!(NewCrontab = fdopen(t, "r+"))) {
warn("fdopen");
goto fatal;
}
@@ -347,14 +347,20 @@
while (EOF != (ch = get_char(f)))
putc(ch, NewCrontab);
fclose(f);
- if (fclose(NewCrontab))
+ if (fflush(NewCrontab))
err(ERROR_EXIT, "%s", Filename);
+ if (fstat(t, &fsbuf) < 0) {
+ warn("unable to fstat temp file");
+ goto fatal;
+ }
again:
if (stat(Filename, &statbuf) < 0) {
warn("stat");
fatal: unlink(Filename);
exit(ERROR_EXIT);
}
+ if (statbuf.st_dev != fsbuf.st_dev || statbuf.st_ino != fsbuf.st_ino)
+ errx(ERROR_EXIT, "temp file must be edited in place");
mtime = statbuf.st_mtime;
if ((!(editor = getenv("VISUAL")))
@@ -419,15 +425,13 @@
warn("stat");
goto fatal;
}
+ if (statbuf.st_dev != fsbuf.st_dev || statbuf.st_ino != fsbuf.st_ino)
+ errx(ERROR_EXIT, "temp file must be edited in place");
if (mtime == statbuf.st_mtime) {
warnx("no changes made to crontab");
goto remove;
}
warnx("installing new crontab");
- if (!(NewCrontab = fopen(Filename, "r"))) {
- warn("%s", Filename);
- goto fatal;
- }
switch (replace_cmd()) {
case 0:
break;
@@ -497,10 +501,10 @@
/* copy the crontab to the tmp
*/
+ rewind(NewCrontab);
Set_LineNum(1)
while (EOF != (ch = get_char(NewCrontab)))
putc(ch, tmp);
- fclose(NewCrontab);
ftruncate(fileno(tmp), ftell(tmp));
fflush(tmp); rewind(tmp);
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200010261830.aa94658>
