summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2011-04-05 13:59:51 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2011-04-05 13:59:51 +0000
commit8595545317cb1c30a0a59dbd8fc3426b1cab6282 (patch)
treecb226e7cc63e6bd05be49fa4ee46d0cf3026e484
parent2b513dbb1c52763aa686ec32a54697f26bce12a7 (diff)
main/logrotate: security fixes
fixes #568 fix CVE-2011-1154, CVE-2011-1155 and CVE-2011-1098 (cherry picked from commit e30653b7a5011b09138e547bd80561ccba16f0c4) Conflicts: main/logrotate/APKBUILD
-rw-r--r--main/logrotate/APKBUILD12
-rw-r--r--main/logrotate/logrotate-3.7.9-atomic-create.patch70
-rw-r--r--main/logrotate/logrotate-3.7.9-shred.patch151
-rw-r--r--main/logrotate/logrotate-3.7.9-statefile.patch96
4 files changed, 326 insertions, 3 deletions
diff --git a/main/logrotate/APKBUILD b/main/logrotate/APKBUILD
index 5eee0d551f5..f181bd9feec 100644
--- a/main/logrotate/APKBUILD
+++ b/main/logrotate/APKBUILD
@@ -1,7 +1,7 @@
# Contributor: Carlo Landmeter <clandmeter@gmail.com>
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=logrotate
-pkgver=3.7.8
+pkgver=3.7.9
pkgrel=2
pkgdesc="Tool to rotate logfiles"
url="https://fedorahosted.org/logrotate/"
@@ -9,7 +9,10 @@ license="GPL"
depends=
makedepends="popt-dev wget"
subpackages="$pkgname-doc"
-source="https://fedorahosted.org/releases/l/o/logrotate/logrotate-3.7.8.tar.gz
+source="https://fedorahosted.org/releases/l/o/logrotate/logrotate-$pkgver.tar.gz
+ logrotate-3.7.9-atomic-create.patch
+ logrotate-3.7.9-shred.patch
+ logrotate-3.7.9-statefile.patch
logrotate.conf"
build() {
@@ -26,5 +29,8 @@ package() {
install -Dm755 examples/logrotate.cron "$pkgdir"/etc/periodic/daily/logrotate
}
-md5sums="b3589bea6d8d5afc8a84134fddaae973 logrotate-3.7.8.tar.gz
+md5sums="eeba9dbca62a9210236f4b83195e4ea5 logrotate-3.7.9.tar.gz
+0273f868dc4208eed0a442759d86e77c logrotate-3.7.9-atomic-create.patch
+74216579397b03c44d1d85dd233306d8 logrotate-3.7.9-shred.patch
+82ebd23da8a7f0650a4c80577dbdc739 logrotate-3.7.9-statefile.patch
fef6415a79a6fede8cf9b9b6b8410090 logrotate.conf"
diff --git a/main/logrotate/logrotate-3.7.9-atomic-create.patch b/main/logrotate/logrotate-3.7.9-atomic-create.patch
new file mode 100644
index 00000000000..b888dc0231a
--- /dev/null
+++ b/main/logrotate/logrotate-3.7.9-atomic-create.patch
@@ -0,0 +1,70 @@
+diff --git a/logrotate.c b/logrotate.c
+index 3748918..fbe232a 100644
+--- a/logrotate.c
++++ b/logrotate.c
+@@ -194,31 +194,41 @@ static int runScript(char *logfn, char *script)
+ int createOutputFile(char *fileName, int flags, struct stat *sb)
+ {
+ int fd;
++ char template[PATH_MAX + 1];
++ mode_t umask_value;
++ snprintf(template, PATH_MAX, "%s/logrotate_temp.XXXXXX", ourDirName(fileName));
++
++ umask_value = umask(0000);
++ fd = mkstemp(template);
++ umask(umask_value);
++
++ if (fd < 0) {
++ message(MESS_ERROR, "error creating unique temp file: %s\n",
++ strerror(errno));
++ return -1;
++ }
++
++ if (fchown(fd, sb->st_uid, sb->st_gid)) {
++ message(MESS_ERROR, "error setting owner of %s: %s\n",
++ fileName, strerror(errno));
++ close(fd);
++ return -1;
++ }
++
++ if (fchmod(fd, sb->st_mode)) {
++ message(MESS_ERROR, "error setting mode of %s: %s\n",
++ fileName, strerror(errno));
++ close(fd);
++ return -1;
++ }
++
++ if (rename(template, fileName)) {
++ message(MESS_ERROR, "error renaming temp file to %s: %s\n",
++ fileName, strerror(errno));
++ close(fd);
++ return -1;
++ }
+
+- fd = open(fileName, flags, sb->st_mode);
+- if (fd < 0) {
+- message(MESS_ERROR, "error creating output file %s: %s\n",
+- fileName, strerror(errno));
+- return -1;
+- }
+- if (fchmod(fd, (S_IRUSR | S_IWUSR) & sb->st_mode)) {
+- message(MESS_ERROR, "error setting mode of %s: %s\n",
+- fileName, strerror(errno));
+- close(fd);
+- return -1;
+- }
+- if (fchown(fd, sb->st_uid, sb->st_gid)) {
+- message(MESS_ERROR, "error setting owner of %s: %s\n",
+- fileName, strerror(errno));
+- close(fd);
+- return -1;
+- }
+- if (fchmod(fd, sb->st_mode)) {
+- message(MESS_ERROR, "error setting mode of %s: %s\n",
+- fileName, strerror(errno));
+- close(fd);
+- return -1;
+- }
+ return fd;
+ }
+
diff --git a/main/logrotate/logrotate-3.7.9-shred.patch b/main/logrotate/logrotate-3.7.9-shred.patch
new file mode 100644
index 00000000000..d9780007f35
--- /dev/null
+++ b/main/logrotate/logrotate-3.7.9-shred.patch
@@ -0,0 +1,151 @@
+Index: logrotate.c
+===================================================================
+--- logrotate.c (revision 310)
++++ logrotate.c (working copy)
+@@ -71,7 +71,7 @@
+ char *mailCommand = DEFAULT_MAIL_COMMAND;
+ time_t nowSecs = 0;
+
+-static int shred_file(char *filename, struct logInfo *log);
++static int shred_file(int fd, char *filename, struct logInfo *log);
+
+ static int globerr(const char *pathname, int theerr)
+ {
+@@ -231,59 +231,79 @@
+ return fd;
+ }
+
+-#define SHRED_CALL "shred -u "
+-#define SHRED_COUNT_FLAG "-n "
+ #define DIGITS 10
++
+ /* unlink, but try to call shred from GNU fileutils */
+-static int shred_file(char *filename, struct logInfo *log)
++static int shred_file(int fd, char *filename, struct logInfo *log)
+ {
+- int len, ret;
+- char *cmd;
+ char count[DIGITS]; /* that's a lot of shredding :) */
++ const char **fullCommand;
++ int id = 0;
++ int status;
+
+ if (!(log->flags & LOG_FLAG_SHRED)) {
+ return unlink(filename);
+ }
+
+- len = strlen(filename) + strlen(SHRED_CALL);
+- len += strlen(SHRED_COUNT_FLAG) + DIGITS;
+- cmd = malloc(len);
++ message(MESS_DEBUG, "Using shred to remove the file %s\n", filename);
+
+- if (!cmd) {
+- message(MESS_ERROR, "malloc error while shredding");
+- return unlink(filename);
++ if (log->shred_cycles != 0) {
++ fullCommand = alloca(sizeof(*fullCommand) * 6);
+ }
+- strcpy(cmd, SHRED_CALL);
++ else {
++ fullCommand = alloca(sizeof(*fullCommand) * 4);
++ }
++ fullCommand[id++] = "shred";
++ fullCommand[id++] = "-u";
++
+ if (log->shred_cycles != 0) {
+- strcat(cmd, SHRED_COUNT_FLAG);
++ fullCommand[id++] = "-n";
+ snprintf(count, DIGITS - 1, "%d", log->shred_cycles);
+- strcat(count, " ");
+- strcat(cmd, count);
++ fullCommand[id++] = count;
+ }
+- strcat(cmd, filename);
+- ret = system(cmd);
+- free(cmd);
+- if (ret != 0) {
++ fullCommand[id++] = "-";
++ fullCommand[id++] = NULL;
++
++ if (!fork()) {
++ dup2(fd, 1);
++ close(fd);
++
++ execvp(fullCommand[0], (void *) fullCommand);
++ exit(1);
++ }
++
++ wait(&status);
++
++ if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+ message(MESS_ERROR, "Failed to shred %s\n, trying unlink", filename);
+- if (ret != -1) {
+- message(MESS_NORMAL, "Shred returned %d\n", ret);
+- }
+ return unlink(filename);
+- } else {
+- return ret;
+ }
++
++ /* We have to unlink it after shred anyway,
++ * because it doesn't remove the file itself */
++ return unlink(filename);
+ }
+
+ static int removeLogFile(char *name, struct logInfo *log)
+ {
+- message(MESS_DEBUG, "removing old log %s\n", name);
++ int fd;
++ message(MESS_DEBUG, "removing old log %s\n", name);
+
+- if (!debug && shred_file(name, log)) {
+- message(MESS_ERROR, "Failed to remove old log %s: %s\n",
+- name, strerror(errno));
+- return 1;
+- }
+- return 0;
++ if ((fd = open(name, O_RDWR)) < 0) {
++ message(MESS_ERROR, "error opening %s: %s\n",
++ name, strerror(errno));
++ return 1;
++ }
++
++ if (!debug && shred_file(fd, name, log)) {
++ message(MESS_ERROR, "Failed to remove old log %s: %s\n",
++ name, strerror(errno));
++ close(fd);
++ return 1;
++ }
++
++ close(fd);
++ return 0;
+ }
+
+ static int compressLogFile(char *name, struct logInfo *log, struct stat *sb)
+@@ -310,7 +330,7 @@
+ compressedName = alloca(strlen(name) + strlen(log->compress_ext) + 2);
+ sprintf(compressedName, "%s%s", name, log->compress_ext);
+
+- if ((inFile = open(name, O_RDONLY)) < 0) {
++ if ((inFile = open(name, O_RDWR)) < 0) {
+ message(MESS_ERROR, "unable to open %s for compression\n", name);
+ return 1;
+ }
+@@ -357,7 +377,6 @@
+ exit(1);
+ }
+
+- close(inFile);
+ close(outFile);
+
+ wait(&status);
+@@ -373,7 +392,8 @@
+ /* If we can't change atime/mtime, it's not a disaster.
+ It might possibly fail under SELinux. */
+
+- shred_file(name, log);
++ shred_file(inFile, name, log);
++ close(inFile);
+
+ return 0;
+ }
diff --git a/main/logrotate/logrotate-3.7.9-statefile.patch b/main/logrotate/logrotate-3.7.9-statefile.patch
new file mode 100644
index 00000000000..daa02402fad
--- /dev/null
+++ b/main/logrotate/logrotate-3.7.9-statefile.patch
@@ -0,0 +1,96 @@
+Index: logrotate.c
+===================================================================
+--- logrotate.c (revision 314)
++++ logrotate.c (working copy)
+@@ -45,6 +45,12 @@
+ #define GLOB_ABORTED GLOB_ABEND
+ #endif
+
++#ifdef PATH_MAX
++#define STATEFILE_BUFFER_SIZE 2 * PATH_MAX + 16
++#else
++#define STATEFILE_BUFFER_SIZE 4096
++#endif
++
+ struct logState {
+ char *fn;
+ struct tm lastRotated; /* only tm.mon, tm_mday, tm_year are good! */
+@@ -82,6 +88,34 @@
+ return 1;
+ }
+
++static void unescape(char *arg)
++{
++ char *p = arg;
++ char *next;
++ char escaped;
++ while ((next = strchr(p, '\\')) != NULL) {
++
++ p = next;
++
++ switch (p[1]) {
++ case 'n':
++ escaped = '\n';
++ break;
++ case '\\':
++ escaped = '\\';
++ break;
++ default:
++ ++p;
++ continue;
++ }
++
++ /* Overwrite the backslash with the intended character,
++ * and shift everything down one */
++ *p++ = escaped;
++ memmove(p, p+1, 1 + strlen(p+1));
++ }
++}
++
+ #define HASH_SIZE_MIN 64
+ static int allocateHash(void)
+ {
+@@ -1546,7 +1580,13 @@
+ for (chptr = p->fn; *chptr; chptr++) {
+ switch (*chptr) {
+ case '"':
++ case '\\':
+ fputc('\\', f);
++ break;
++ case '\n':
++ fputc('\\', f);
++ fputc('n', f);
++ continue;
+ }
+
+ fputc(*chptr, f);
+@@ -1567,7 +1607,8 @@
+ static int readState(char *stateFilename)
+ {
+ FILE *f;
+- char buf[1024];
++ char buf[STATEFILE_BUFFER_SIZE];
++ char *filename;
+ const char **argv;
+ int argc;
+ int year, month, day;
+@@ -1678,7 +1719,10 @@
+
+ year -= 1900, month -= 1;
+
+- if ((st = findState(argv[0])) == NULL)
++ filename = strdup(argv[0]);
++ unescape(filename);
++
++ if ((st = findState(filename)) == NULL)
+ return 1;
+
+ st->lastRotated.tm_mon = month;
+@@ -1690,6 +1734,7 @@
+ st->lastRotated = *localtime(&lr_time);
+
+ free(argv);
++ free(filename);
+ }
+
+ fclose(f);