diff --git a/logrotate-CVE-2011-1098.patch b/logrotate-CVE-2011-1098.patch new file mode 100644 index 0000000..9ad4c60 --- /dev/null +++ b/logrotate-CVE-2011-1098.patch @@ -0,0 +1,33 @@ +Index: logrotate-3.7.9/logrotate.c +=================================================================== +--- logrotate-3.7.9.orig/logrotate.c ++++ logrotate-3.7.9/logrotate.c +@@ -204,7 +204,9 @@ int createOutputFile(char *fileName, int + { + int fd; + +- fd = open(fileName, flags, sb->st_mode); ++ unlink(fileName); ++ fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW), ++ (S_IRUSR | S_IWUSR) & sb->st_mode); + if (fd < 0) { + message(MESS_ERROR, "error creating output file %s: %s\n", + fileName, strerror(errno)); +@@ -316,7 +318,7 @@ static int compressLogFile(char *name, s + } + + outFile = +- createOutputFile(compressedName, O_RDWR | O_CREAT | O_TRUNC, sb); ++ createOutputFile(compressedName, O_RDWR | O_CREAT, sb); + if (outFile < 0) { + close(inFile); + return 1; +@@ -495,7 +497,7 @@ static int copyTruncate(char *currLog, c + } + #endif + fdsave = +- createOutputFile(saveLog, O_WRONLY | O_CREAT | O_TRUNC, sb); ++ createOutputFile(saveLog, O_WRONLY | O_CREAT, sb); + #ifdef WITH_SELINUX + if (selinux_enabled) { + setfscreatecon_raw(prev_context); diff --git a/logrotate-CVE-2011-1155.patch b/logrotate-CVE-2011-1155.patch new file mode 100644 index 0000000..ba10d1d --- /dev/null +++ b/logrotate-CVE-2011-1155.patch @@ -0,0 +1,96 @@ +Index: logrotate.c +=================================================================== +--- logrotate.c.orig ++++ logrotate.c +@@ -36,6 +36,12 @@ int selinux_enforce = 0; + #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 @@ static int globerr(const char *pathname, + 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) + { +@@ -1467,7 +1501,13 @@ static int writeState(char *stateFilenam + for (chptr = p->fn; *chptr; chptr++) { + switch (*chptr) { + case '"': ++ case '\\': + fputc('\\', f); ++ break; ++ case '\n': ++ fputc('\\', f); ++ fputc('n', f); ++ continue; + } + + fputc(*chptr, f); +@@ -1488,7 +1528,8 @@ static int writeState(char *stateFilenam + 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; +@@ -1599,7 +1640,10 @@ static int readState(char *stateFilename + + 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; +@@ -1611,6 +1655,7 @@ static int readState(char *stateFilename + st->lastRotated = *localtime(&lr_time); + + free(argv); ++ free(filename); + } + + fclose(f); diff --git a/logrotate-shred-CVE-2011-1154.patch b/logrotate-shred-CVE-2011-1154.patch new file mode 100644 index 0000000..1105567 --- /dev/null +++ b/logrotate-shred-CVE-2011-1154.patch @@ -0,0 +1,144 @@ +Index: logrotate.c +=================================================================== +--- logrotate.c.orig ++++ logrotate.c +@@ -71,7 +71,7 @@ const char * compress_cmd_list[][2] = { + + 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) + { +@@ -233,58 +233,78 @@ int createOutputFile(char *fileName, int + 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); ++ } ++ else { ++ fullCommand = alloca(sizeof(*fullCommand) * 4); + } +- strcpy(cmd, SHRED_CALL); ++ 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) { +- message(MESS_ERROR, "Failed to shred %s\n, trying unlink", filename); +- if (ret != -1) { +- message(MESS_NORMAL, "Shred returned %d\n", ret); ++ 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); + 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) + { ++ int fd; + message(MESS_DEBUG, "removing old log %s\n", name); + +- if (!debug && shred_file(name, log)) { ++ 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; + } + +@@ -312,7 +332,7 @@ static int compressLogFile(char *name, s + 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; + } +@@ -334,7 +354,6 @@ static int compressLogFile(char *name, s + exit(1); + } + +- close(inFile); + close(outFile); + + wait(&status); +@@ -350,7 +369,8 @@ static int compressLogFile(char *name, s + /* 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/logrotate.changes b/logrotate.changes index b0702c2..fb4dee3 100644 --- a/logrotate.changes +++ b/logrotate.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue May 10 14:23:08 UTC 2011 - puzel@novell.com + +- add logrotate-CVE-2011-1098.patch (bnc#677336) +- add logrotate-shred-CVE-2011-1154.patch (bnc#679661) +- add logrotate-CVE-2011-1155.patch (bnc#679662) +- use spec-cleaner + ------------------------------------------------------------------- Thu Nov 18 12:44:55 UTC 2010 - lnussel@suse.de diff --git a/logrotate.spec b/logrotate.spec index 4715df9..2ef5119 100644 --- a/logrotate.spec +++ b/logrotate.spec @@ -15,28 +15,33 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # -# norootforbuild Url: https://fedorahosted.org/releases/l/o/logrotate Name: logrotate -BuildRequires: popt-devel -BuildRequires: libselinux-devel -Summary: Rotate, Compress, Remove, and Mail System Log Files Version: 3.7.9 -Release: 2 +Release: 3 License: GPLv2+ +Summary: Rotate, compress, remove, and mail system log files Group: System/Base Source: %{name}-%{version}.tar.bz2 Source100: %{name}-rpmlintrc -Patch: logrotate-3.7.8-suse.patch +Patch0: logrotate-3.7.8-suse.patch Patch1: logrotate-3.7.8-conf.patch Patch2: logrotate-3.7.8-autoext.patch Patch3: logrotate-3.7.8-addextension.patch Patch4: logrotate-3.7.8-mess_err.patch +Patch5: logrotate-CVE-2011-1098.patch +Patch6: logrotate-shred-CVE-2011-1154.patch +Patch7: logrotate-CVE-2011-1155.patch +BuildRequires: libselinux-devel +BuildRequires: popt-devel +PreReq: %fillup_prereq +PreReq: /bin/mv +PreReq: /bin/rm +Requires: bzip2 +Requires: cron BuildRoot: %{_tmppath}/%{name}-%{version}-build -PreReq: %fillup_prereq /bin/rm /bin/mv -Requires: bzip2 cron %description The logrotate utility is designed to simplify the administration of log @@ -46,35 +51,30 @@ Logrotate can be set to handle a log file daily, weekly, monthly, or when the log file reaches a certain size. Normally, logrotate runs as a daily cron job. - - -Authors: --------- - Erik Troan - Matt Wilson - Preston Brown - %prep %setup -q -%patch +%patch0 %patch1 %patch2 %patch3 %patch4 +%patch5 -p1 +%patch6 +%patch7 %build -make %{?_smp_mflags} RPM_OPT_FLAGS="$RPM_OPT_FLAGS" WITH_SELINUX=yes +make %{?_smp_mflags} RPM_OPT_FLAGS="%{optflags}" WITH_SELINUX=yes %check make test %install -make PREFIX=$RPM_BUILD_ROOT install -mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,cron.daily} -mkdir -p $RPM_BUILD_ROOT/usr/sbin -install -m 644 examples/logrotate-default $RPM_BUILD_ROOT/etc/logrotate.conf -install -m 755 examples/logrotate.cron $RPM_BUILD_ROOT/etc/cron.daily/logrotate -install -m 644 examples/logrotate.wtmp $RPM_BUILD_ROOT/etc/logrotate.d/wtmp +make PREFIX=%{buildroot} install +mkdir -p %{buildroot}%{_sysconfdir}/{logrotate.d,cron.daily} +mkdir -p %{buildroot}%{_prefix}/sbin +install -m 644 examples/logrotate-default %{buildroot}%{_sysconfdir}/logrotate.conf +install -m 755 examples/logrotate.cron %{buildroot}%{_sysconfdir}/cron.daily/logrotate +install -m 644 examples/logrotate.wtmp %{buildroot}%{_sysconfdir}/logrotate.d/wtmp %post %{remove_and_set MAX_DAYS_FOR_LOG_FILES} @@ -84,7 +84,7 @@ if [ -f /etc/logrotate.d/aaa_base ] ; then fi %clean -rm -rf $RPM_BUILD_ROOT +rm -rf %{buildroot} %files %defattr(-,root,root) @@ -92,8 +92,8 @@ rm -rf $RPM_BUILD_ROOT %{_sbindir}/logrotate %{_mandir}/man8/logrotate.8* %{_mandir}/man5/logrotate.conf.5* -/etc/cron.daily/logrotate -%config /etc/logrotate.conf +%{_sysconfdir}/cron.daily/logrotate +%config %{_sysconfdir}/logrotate.conf %config(noreplace)/etc/logrotate.d/wtmp %changelog