diff -Nru logrotate-3.8.7/debian/changelog logrotate-3.8.7/debian/changelog --- logrotate-3.8.7/debian/changelog 2014-01-22 19:05:42.000000000 +0000 +++ logrotate-3.8.7/debian/changelog 2017-03-22 11:43:44.000000000 +0000 @@ -1,3 +1,11 @@ +logrotate (3.8.7-1ubuntu1.1) trusty; urgency=medium + + * createOutputFile: rename already existing file (LP: #1630516) + - d/p/ubuntu/createOutputFile-eliminate-stat-open-TOCTOU-race.patch + - d/p/ubuntu/createOutputFile-rename-already-existing-file.patch + + -- Christian Ehrhardt Wed, 22 Mar 2017 12:43:10 +0100 + logrotate (3.8.7-1ubuntu1) trusty; urgency=medium * Merge from Debian unstable, remaining changes: diff -Nru logrotate-3.8.7/debian/patches/series logrotate-3.8.7/debian/patches/series --- logrotate-3.8.7/debian/patches/series 2014-01-22 18:20:23.000000000 +0000 +++ logrotate-3.8.7/debian/patches/series 2017-03-22 11:42:00.000000000 +0000 @@ -5,3 +5,5 @@ chown-484762.patch mktime-718332.patch man-su-explanation-729315.patch +ubuntu/createOutputFile-rename-already-existing-file.patch +ubuntu/createOutputFile-eliminate-stat-open-TOCTOU-race.patch diff -Nru logrotate-3.8.7/debian/patches/ubuntu/createOutputFile-eliminate-stat-open-TOCTOU-race.patch logrotate-3.8.7/debian/patches/ubuntu/createOutputFile-eliminate-stat-open-TOCTOU-race.patch --- logrotate-3.8.7/debian/patches/ubuntu/createOutputFile-eliminate-stat-open-TOCTOU-race.patch 1970-01-01 00:00:00.000000000 +0000 +++ logrotate-3.8.7/debian/patches/ubuntu/createOutputFile-eliminate-stat-open-TOCTOU-race.patch 2017-03-22 11:41:42.000000000 +0000 @@ -0,0 +1,57 @@ +Description: createOutputFile: eliminate stat/open TOCTOU race + +From aff4a30807218a52b6b5f200c5aa0eea335547ba Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 17 Oct 2016 17:59:31 +0200 +Subject: [PATCH] createOutputFile: eliminate stat/open TOCTOU race + +--- + logrotate.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +Original-Author: Kamil Dudka +Origin: https://github.com/logrotate/logrotate/commit/aff4a30807218a52b6b5f200c5aa0eea335547ba +Bug-Ubuntu: http://bugs.launchpad.net/bugs/1630516 +Author: Christian Ehrhardt +Last-Update: 2017-03-22 +diff --git a/logrotate.c b/logrotate.c +index 10f4b52..79f4755 100644 +--- a/logrotate.c ++++ b/logrotate.c +@@ -366,11 +366,18 @@ static int runScript(struct logInfo *log, char *logfn, char *script) + + int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, int force_mode) + { +- int fd; ++ int fd = -1; + struct stat sb_create; + int acl_set = 0; ++ int i; ++ ++ for (i = 0; i < 2; ++i) { ++ fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW), ++ (S_IRUSR | S_IWUSR) & sb->st_mode); ++ ++ if ((fd >= 0) || (errno != EEXIST)) ++ break; + +- if (stat(fileName, &sb_create) == 0) { + /* the destination file already exists, while it should not */ + struct tm now = *localtime(&nowSecs); + size_t fileName_size = strlen(fileName); +@@ -384,11 +391,9 @@ int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, i + fileName, backupName, strerror(errno)); + return -1; + } ++ /* existing file renamed, try it once again */ + } + +- 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)); +-- +2.7.4 + diff -Nru logrotate-3.8.7/debian/patches/ubuntu/createOutputFile-rename-already-existing-file.patch logrotate-3.8.7/debian/patches/ubuntu/createOutputFile-rename-already-existing-file.patch --- logrotate-3.8.7/debian/patches/ubuntu/createOutputFile-rename-already-existing-file.patch 1970-01-01 00:00:00.000000000 +0000 +++ logrotate-3.8.7/debian/patches/ubuntu/createOutputFile-rename-already-existing-file.patch 2017-03-22 11:41:42.000000000 +0000 @@ -0,0 +1,95 @@ +Description: createOutputFile: rename already existing file + +From fc1c3eff61edf8e9f0a4bfa980f3a6030a6b271f Mon Sep 17 00:00:00 2001 +From: Mathieu Parent +Date: Tue, 8 Mar 2016 16:56:50 +0100 +Subject: [PATCH] createOutputFile: rename already existing file + +See https://bugs.debian.org/734688 + +Closes #23 +--- + logrotate.c | 20 ++++++++++++++++++-- + test/test | 29 ++++++++++++++++++++++++++++- + test/test-config.72.in | 7 +++++++ + 3 files changed, 53 insertions(+), 3 deletions(-) + create mode 100644 test/test-config.72.in + +Original-Author: Mathieu Parent +Origin: https://github.com/logrotate/logrotate/commit/fc1c3eff61edf8e9f0a4bfa980f3a6030a6b271f +Bug-Ubuntu: http://bugs.launchpad.net/bugs/1630516 +Author: Christian Ehrhardt +Last-Update: 2017-03-22 +--- a/logrotate.c ++++ b/logrotate.c +@@ -300,8 +300,24 @@ + int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, int force_mode) + { + int fd; +- struct stat sb_create; +- int acl_set = 0; ++ struct stat sb_create; ++ int acl_set = 0; ++ ++ if (stat(fileName, &sb_create) == 0) { ++ /* the destination file already exists, while it should not */ ++ struct tm now = *localtime(&nowSecs); ++ size_t fileName_size = strlen(fileName); ++ char* backupName = alloca(fileName_size + sizeof("-YYYYMMDDHH.backup")); ++ strncpy(backupName, fileName, fileName_size); ++ size_t date_size=strftime(backupName+fileName_size, 12, "-%Y%m%d%H", &now); ++ strncpy(backupName+fileName_size+date_size, ".backup\0", 8); ++ message(MESS_ERROR, "destination %s already exists, renaming to %s\n", fileName, backupName); ++ if (rename(fileName, backupName) != 0) { ++ message(MESS_ERROR, "error renaming already existing output file %s to %s: %s\n", ++ fileName, backupName, strerror(errno)); ++ return -1; ++ } ++ } + + fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW), + (S_IRUSR | S_IWUSR) & sb->st_mode); +--- /dev/null ++++ b/test/test-config.72.in +@@ -0,0 +1,7 @@ ++&DIR&/test.log { ++ daily ++ rotate 3 ++ compress ++ delaycompress ++ create ++} +--- a/test/test ++++ b/test/test +@@ -1358,4 +1358,31 @@ + test.log.1 0 zero + EOF + ++# Test backported with bugfix for http://pad.lv/1630516 ++cleanup 72 ++ ++# ------------------------------- Test 72 ------------------------------------ ++preptest test.log 72 2 ++ ++$RLR test-config.72 --force ++ ++checkoutput < test.log.1.gz ++ ++$RLR test-config.72 --force ++dt="$(date +%Y%m%d%H)" ++ ++checkoutput <