1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
From: Christian Kastner <ckk@kvr.at>
Date: Wed, 23 Dec 2015 12:25:52 +0100
Subject: Avoid predictable filenames
Prevent symlink attack by using mkstemp() instead of predictable filenames.
Based on a fix originally provided by Daniel Jacobowitz.
Forwarded: no
Last-Update: 2015-12-25
---
crontab.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/crontab.c b/crontab.c
index 8389f96..5f9d977 100644
--- a/crontab.c
+++ b/crontab.c
@@ -333,9 +333,9 @@ edit_cmd() {
}
}
- (void) snprintf(Filename, sizeof(Filename)-1, "/tmp/crontab.%d", Pid);
+ (void) snprintf(Filename, sizeof(Filename)-1, "/tmp/crontab.XXXXXX");
Filename[sizeof(Filename)-1] = '\0';
- if (-1 == (t = open(Filename, O_CREAT|O_EXCL|O_RDWR, 0600))) {
+ if (-1 == (t = mkstemp(Filename))) {
perror(Filename);
goto fatal;
}
@@ -517,7 +517,7 @@ static int
replace_cmd() {
char n[MAX_FNAME], envstr[MAX_ENVSTR], tn[MAX_FNAME];
FILE *tmp;
- int ch, eof;
+ int ch, eof, fd;
int nl = FALSE;
entry *e;
time_t now = time(NULL);
@@ -527,10 +527,15 @@ replace_cmd() {
fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
return (-2);
}
- (void) snprintf(n, MAX_FNAME, "tmp.%d", Pid);
- (void) snprintf(tn, MAX_FNAME, CRON_TAB(n));
- if (!(tmp = fopen(tn, "w+"))) {
- perror(tn);
+ (void) snprintf(tn, MAX_FNAME, CRON_TAB("tmp.XXXXXX"));
+ fd = mkstemp(tn);
+ if (fd < 0) {
+ fprintf(stderr, "%s/: mkstemp: %s\n", CRONDIR, strerror(errno));
+ return(-2);
+ }
+ tmp = fdopen(fd, "w+");
+ if (!tmp) {
+ fprintf(stderr, "%s/: fdopen: %s\n", CRONDIR, strerror(errno));
return (-2);
}
@@ -549,7 +554,7 @@ replace_cmd() {
while (EOF != (ch = get_char(NewCrontab)))
putc(ch, tmp);
- if (ferror(tmp) || fflush(tmp) || fsync(fileno(tmp))) {
+ if (ferror(tmp) || fflush(tmp) || fsync(fd)) {
fprintf(stderr, "%s: %s: %s\n",
ProgramName, tn, strerror(errno));
fclose(tmp); unlink(tn);
|