diff --git a/SOURCES/logrotate-3.8.6-config-error.patch b/SOURCES/logrotate-3.8.6-config-error.patch
new file mode 100644
index 0000000..6231284
--- /dev/null
+++ b/SOURCES/logrotate-3.8.6-config-error.patch
@@ -0,0 +1,225 @@
+From 71c2315b76ef0d5408bfa37c31ad1b5a27e2b3e7 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Wed, 7 Dec 2016 10:39:55 +0100
+Subject: [PATCH 1/4] config.c: skip a duplicated log entry but continue
+ reading
+
+... other entries which are not duplicated.
+
+Closes #81
+
+Upstream-commit: 06ede862d319efc98942536cba11bdfdbdc9cc72
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ config.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/config.c b/config.c
+index 2a610de..aaf4fbb 100644
+--- a/config.c
++++ b/config.c
+@@ -1389,7 +1389,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
+ 
+ 				newlog->files = NULL;
+ 				newlog->numFiles = 0;
+-				for (argNum = 0; argNum < argc && logerror != 1; argNum++) {
++				for (argNum = 0; argNum < argc; argNum++) {
+ 				if (globerr_msg) {
+ 					free(globerr_msg);
+ 					globerr_msg = NULL;
+@@ -1672,7 +1672,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
+ 
+ 	munmap(buf, (size_t) length);
+ 	close(fd);
+-    return 0;
++    return logerror;
+ error:
+ 	if (key)
+ 		free(key);
+-- 
+2.20.1
+
+
+From 9915dc4c4bf84b1ff16f34d7d34178098a03cf7c Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 2 Jan 2017 20:35:17 +0100
+Subject: [PATCH 2/4] config.c: recover from failures of readConfigFile()
+
+Closes #81
+
+Upstream-commit: 56598fd1e9338b45ba3e1bda1b91522e75b40e06
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ config.c | 30 ++++++++++++++----------------
+ 1 file changed, 14 insertions(+), 16 deletions(-)
+
+diff --git a/config.c b/config.c
+index aaf4fbb..203b3e3 100644
+--- a/config.c
++++ b/config.c
+@@ -510,8 +510,8 @@ static void freeTailLogs(int num)
+ static int readConfigPath(const char *path, struct logInfo *defConfig)
+ {
+     struct stat sb;
+-    int here, oldnumlogs, result = 1;
+-	struct logInfo defConfigBackup;
++    int here, result = 1;
++    struct logInfo defConfigBackup;
+ 
+     if (stat(path, &sb)) {
+ 	message(MESS_ERROR, "cannot stat %s: %s\n", path, strerror(errno));
+@@ -588,11 +588,9 @@ static int readConfigPath(const char *path, struct logInfo *defConfig)
+ 
+ 	for (i = 0; i < files_count; ++i) {
+ 	    assert(namelist[i] != NULL);
+-	    oldnumlogs = numLogs;
+ 	    copyLogInfo(&defConfigBackup, defConfig);
+ 	    if (readConfigFile(namelist[i], defConfig)) {
+ 		message(MESS_ERROR, "found error in file %s, skipping\n", namelist[i]);
+-		freeTailLogs(numLogs - oldnumlogs);
+ 		freeLogInfo(defConfig);
+ 		copyLogInfo(defConfig, &defConfigBackup);
+ 		freeLogInfo(&defConfigBackup);
+@@ -609,10 +607,8 @@ static int readConfigPath(const char *path, struct logInfo *defConfig)
+ 	close(here);
+ 	free_2d_array(namelist, files_count);
+     } else {
+-    	oldnumlogs = numLogs;
+ 	copyLogInfo(&defConfigBackup, defConfig);
+ 	if (readConfigFile(path, defConfig)) {
+-	    freeTailLogs(numLogs - oldnumlogs);
+ 	    freeLogInfo(defConfig);
+ 	    copyLogInfo(defConfig, &defConfigBackup);
+ 	} else {
+@@ -678,10 +674,8 @@ int readAllConfigPaths(const char **paths)
+     }
+ 
+     for (file = paths; *file; file++) {
+-	if (readConfigPath(*file, &defConfig)) {
++	if (readConfigPath(*file, &defConfig))
+ 	    result = 1;
+-	    break;
+-	}
+     }
+     free_2d_array(tabooExts, tabooCount);
+     freeLogInfo(&defConfig);
+@@ -1207,17 +1201,21 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
+ 							&buf, length)) != NULL) {
+ 
+ 						message(MESS_DEBUG, "including %s\n", key);
+-						if (++recursion_depth > MAX_NESTING) {
++						if (recursion_depth >= MAX_NESTING) {
+ 							message(MESS_ERROR, "%s:%d include nesting too deep\n",
+ 									configFile, lineNum);
+-							--recursion_depth;
+-							goto error;
+-						}
+-						if (readConfigPath(key, newlog)) {
+-							--recursion_depth;
+-							goto error;
++							logerror = 1;
++							continue;
+ 						}
++
++						++recursion_depth;
++						rv = readConfigPath(key, newlog);
+ 						--recursion_depth;
++
++						if (rv) {
++							logerror = 1;
++							continue;
++						}
+ 					}
+ 					else continue;
+ 				} else if (!strcmp(key, "olddir")) {
+-- 
+2.20.1
+
+
+From ed099a0321e799d4be72f9096532bb976680aad8 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Thu, 12 Jan 2017 08:44:39 +0100
+Subject: [PATCH 3/4] config.c: propagate errors from readConfigFile() properly
+
+Closes #81
+
+Upstream-commit: 6a75cdeab61a29ea99d49a85461f597c1d8d055c
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ config.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/config.c b/config.c
+index 203b3e3..72981b0 100644
+--- a/config.c
++++ b/config.c
+@@ -510,7 +510,7 @@ static void freeTailLogs(int num)
+ static int readConfigPath(const char *path, struct logInfo *defConfig)
+ {
+     struct stat sb;
+-    int here, result = 1;
++    int here, result = 0;
+     struct logInfo defConfigBackup;
+ 
+     if (stat(path, &sb)) {
+@@ -594,9 +594,8 @@ static int readConfigPath(const char *path, struct logInfo *defConfig)
+ 		freeLogInfo(defConfig);
+ 		copyLogInfo(defConfig, &defConfigBackup);
+ 		freeLogInfo(&defConfigBackup);
++		result = 1;
+ 		continue;
+-	    } else {
+-		result = 0;
+ 	    }
+ 	    freeLogInfo(&defConfigBackup);
+ 	}
+@@ -611,8 +610,7 @@ static int readConfigPath(const char *path, struct logInfo *defConfig)
+ 	if (readConfigFile(path, defConfig)) {
+ 	    freeLogInfo(defConfig);
+ 	    copyLogInfo(defConfig, &defConfigBackup);
+-	} else {
+-	    result = 0;
++	    result = 1;
+ 	}
+ 	freeLogInfo(&defConfigBackup);
+     }
+-- 
+2.20.1
+
+
+From 58f8efbfde9d0ff2d8fbb0cef30ed842928835cd Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Thu, 12 Jan 2017 08:50:55 +0100
+Subject: [PATCH 4/4] do not treat errors in reading configuration as fatal
+
+Closes #81
+
+Upstream-commit: 74b788f790990d5958314df5f908a6fc5eaeccdd
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ logrotate.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/logrotate.c b/logrotate.c
+index 976210e..459e01e 100644
+--- a/logrotate.c
++++ b/logrotate.c
+@@ -2417,12 +2417,10 @@ int main(int argc, const char **argv)
+     selinux_enforce = security_getenforce();
+ #endif
+ 
+-	TAILQ_INIT(&logs);
++    TAILQ_INIT(&logs);
+ 
+-	if (readAllConfigPaths(files)) {
+-	poptFreeContext(optCon);
+-	exit(1);
+-    }
++    if (readAllConfigPaths(files))
++	rc = 1;
+ 
+     poptFreeContext(optCon);
+     nowSecs = time(NULL);
+-- 
+2.20.1
+
diff --git a/SOURCES/logrotate-3.8.6-rename-existing.patch b/SOURCES/logrotate-3.8.6-rename-existing.patch
new file mode 100644
index 0000000..15d8b43
--- /dev/null
+++ b/SOURCES/logrotate-3.8.6-rename-existing.patch
@@ -0,0 +1,206 @@
+From def2d2aebad1a6d1b149780181943e0cafa63bdc Mon Sep 17 00:00:00 2001
+From: Mathieu Parent <Mathieu.PARENT@nantesmetropole.fr>
+Date: Tue, 8 Mar 2016 16:56:50 +0100
+Subject: [PATCH 1/3] createOutputFile: rename already existing file
+
+See https://bugs.debian.org/734688
+
+Closes #23
+
+Upstream-commit: fc1c3eff61edf8e9f0a4bfa980f3a6030a6b271f
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ logrotate.c            | 20 ++++++++++++++++++--
+ test/test              | 26 ++++++++++++++++++++++++++
+ test/test-config.72.in |  7 +++++++
+ 3 files changed, 51 insertions(+), 2 deletions(-)
+ create mode 100644 test/test-config.72.in
+
+diff --git a/logrotate.c b/logrotate.c
+index f13d140..976210e 100644
+--- a/logrotate.c
++++ b/logrotate.c
+@@ -395,8 +395,24 @@ 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;
+-	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);
+diff --git a/test/test b/test/test
+index bcdfe05..b47ac6a 100755
+--- a/test/test
++++ b/test/test
+@@ -1586,6 +1586,32 @@ EOF
+ rm -rf testdir adir
+ rm -rf testdir bdir
+ 
++cleanup 72
++
++# ------------------------------- Test 72 ------------------------------------
++preptest test.log 72 2
++
++$RLR test-config.72 --force
++
++checkoutput <<EOF
++test.log 0
++test.log.1 0 zero
++test.log.2.gz 1 first
++EOF
++
++echo 'unexpected' > test.log.1.gz
++
++$RLR test-config.72 --force
++dt="$(date +%Y%m%d%H)"
++
++checkoutput <<EOF
++test.log 0
++test.log.1 0
++test.log.1.gz-$dt.backup 0 unexpected
++test.log.2.gz 1 zero
++test.log.3.gz 1 first
++EOF
++
+ cleanup 73
+ 
+ # ------------------------------- Test 73 ------------------------------------
+diff --git a/test/test-config.72.in b/test/test-config.72.in
+new file mode 100644
+index 0000000..9fe50a2
+--- /dev/null
++++ b/test/test-config.72.in
+@@ -0,0 +1,7 @@
++&DIR&/test.log {
++    daily
++    rotate 3
++    compress
++    delaycompress
++    create
++}
+-- 
+2.17.2
+
+
+From 1fa3ff8477d3766f0cc39631ace8c63ee99a1974 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 17 Oct 2016 17:59:31 +0200
+Subject: [PATCH 2/3] createOutputFile: eliminate stat/open TOCTOU race
+
+Upstream-commit: aff4a30807218a52b6b5f200c5aa0eea335547ba
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ logrotate.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/logrotate.c b/logrotate.c
+index 976210e..fdc81ac 100644
+--- a/logrotate.c
++++ b/logrotate.c
+@@ -394,11 +394,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);
+@@ -412,11 +419,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.20.1
+
+
+From 86d67f5769575104add7846b822069008c912b3c Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 17 Oct 2016 18:13:32 +0200
+Subject: [PATCH 3/3] createOutputFile: improve code readability
+
+Upstream-commit: 5ecd908033a481c1e127ba583697d6662ffea4a3
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ logrotate.c | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/logrotate.c b/logrotate.c
+index fdc81ac..5b0df30 100644
+--- a/logrotate.c
++++ b/logrotate.c
+@@ -409,14 +409,24 @@ int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, i
+ 	/* 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);
++	size_t buf_size = fileName_size + sizeof("-YYYYMMDDHH.backup");
++	char *backupName = alloca(buf_size);
++	char *ptr = backupName;
++
++	/* construct backupName starting with fileName */
++	strcpy(ptr, fileName);
++	ptr += fileName_size;
++	buf_size -= fileName_size;
++
++	/* append the -YYYYMMDDHH time stamp and the .backup suffix */
++	ptr += strftime(ptr, buf_size, "-%Y%m%d%H", &now);
++	strcpy(ptr, ".backup");
++
++	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));
++	    message(MESS_ERROR, "error renaming already existing output file"
++		    " %s to %s: %s\n", fileName, backupName, strerror(errno));
+ 	    return -1;
+ 	}
+ 	/* existing file renamed, try it once again */
+-- 
+2.20.1
+
diff --git a/SPECS/logrotate.spec b/SPECS/logrotate.spec
index 1c61f5d..d689299 100644
--- a/SPECS/logrotate.spec
+++ b/SPECS/logrotate.spec
@@ -1,7 +1,7 @@
 Summary: Rotates, compresses, removes and mails system log files
 Name: logrotate
 Version: 3.8.6
-Release: 17%{?dist}
+Release: 19%{?dist}
 License: GPL+
 Group: System Environment/Base
 URL: https://github.com/logrotate/logrotate
@@ -54,6 +54,12 @@ Patch19: logrotate-3.8.6-monthly-dst.patch
 # fix #1374550 - unlink destination file when rotation fails
 Patch20: logrotate-3.8.6-unlink-on-failure.patch
 
+# fix #1631218 - rename already existing file
+Patch21: logrotate-3.8.6-rename-existing.patch
+
+# fix #1680436 - do not treat errors in reading configuration as fatal
+Patch22: logrotate-3.8.6-config-error.patch
+
 Requires: coreutils >= 5.92 popt
 BuildRequires: libselinux-devel popt-devel libacl-devel acl
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -92,6 +98,8 @@ log files on your system.
 %patch18 -p1
 %patch19 -p1
 %patch20 -p1
+%patch21 -p1
+%patch22 -p1
 
 %build
 make %{?_smp_mflags} RPM_OPT_FLAGS="$RPM_OPT_FLAGS" WITH_SELINUX=yes WITH_ACL=yes
@@ -140,6 +148,13 @@ rm -rf $RPM_BUILD_ROOT
 %config(noreplace) %{_sysconfdir}/rwtab.d/logrotate
 
 %changelog
+* Wed Aug 07 2019 Kamil Dudka <kdudka@redhat.com> - 3.8.6-19
+- related #1631218 - eliminate a time-of-check/time-of-use race condition
+
+* Tue Aug 06 2019 Kamil Dudka <kdudka@redhat.com> - 3.8.6-18
+- fix #1680436 - do not treat errors in reading configuration as fatal
+- fix #1631218 - rename already existing file
+
 * Fri Jun 15 2018 Kamil Dudka <kdudka@redhat.com> - 3.8.6-17
 - fix #1374550 - unlink destination file when rotation fails