Blame SOURCES/0004-logrotate-3.18.0-CVE-2022-1348.patch

d348c3
From 53e0dc4a8ddcb169b0ba36472de03f4366f45159 Mon Sep 17 00:00:00 2001
d348c3
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
d348c3
Date: Tue, 29 Mar 2022 21:06:54 +0200
d348c3
Subject: [PATCH 1/3] skip locking if state file is world-readable
d348c3
d348c3
Fixes: CVE-2022-1348 - potential DoS from unprivileged users via the state file
d348c3
Bug: https://bugzilla.redhat.com/CVE-2022-1348
d348c3
d348c3
Upstream-commit: 1f76a381e2caa0603ae3dbc51ed0f1aa0d6658b9
d348c3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
d348c3
---
d348c3
 logrotate.c            | 24 ++++++++++++++++++++++--
d348c3
 logrotate.spec.in      |  3 +--
d348c3
 test/Makefile.am       |  1 +
d348c3
 test/test-0087.sh      |  1 +
d348c3
 test/test-0092.sh      | 19 +++++++++++++++++++
d348c3
 test/test-config.92.in |  4 ++++
d348c3
 6 files changed, 48 insertions(+), 4 deletions(-)
d348c3
 create mode 100755 test/test-0092.sh
d348c3
 create mode 100644 test/test-config.92.in
d348c3
d348c3
diff --git a/logrotate.c b/logrotate.c
d348c3
index d3f2825..78153b3 100644
d348c3
--- a/logrotate.c
d348c3
+++ b/logrotate.c
d348c3
@@ -2565,6 +2565,9 @@ static int writeState(const char *stateFilename)
d348c3
 
d348c3
     close(fdcurr);
d348c3
 
d348c3
+    /* drop world-readable flag to prevent others from locking */
d348c3
+    sb.st_mode &= ~(mode_t)S_IROTH;
d348c3
+
d348c3
     fdsave = createOutputFile(tmpFilename, O_RDWR | O_CREAT | O_TRUNC, &sb, prev_acl, 0);
d348c3
 #ifdef WITH_ACL
d348c3
     if (prev_acl) {
d348c3
@@ -2898,15 +2901,16 @@ static int readState(const char *stateFilename)
d348c3
 
d348c3
 static int lockState(const char *stateFilename, int skip_state_lock)
d348c3
 {
d348c3
+    struct stat sb;
d348c3
     int lockFd = open(stateFilename, O_RDWR | O_CLOEXEC);
d348c3
     if (lockFd == -1) {
d348c3
         if (errno == ENOENT) {
d348c3
             message(MESS_DEBUG, "Creating stub state file: %s\n",
d348c3
                     stateFilename);
d348c3
 
d348c3
-            /* create a stub state file with mode 0644 */
d348c3
+            /* create a stub state file with mode 0640 */
d348c3
             lockFd = open(stateFilename, O_CREAT | O_EXCL | O_WRONLY,
d348c3
-                          S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
d348c3
+                          S_IWUSR | S_IRUSR | S_IRGRP);
d348c3
             if (lockFd == -1) {
d348c3
                 message(MESS_ERROR, "error creating stub state file %s: %s\n",
d348c3
                         stateFilename, strerror(errno));
d348c3
@@ -2926,6 +2930,22 @@ static int lockState(const char *stateFilename, int skip_state_lock)
d348c3
         return 0;
d348c3
     }
d348c3
 
d348c3
+    if (fstat(lockFd, &sb) == -1) {
d348c3
+        message(MESS_ERROR, "error stat()ing state file %s: %s\n",
d348c3
+                stateFilename, strerror(errno));
d348c3
+        close(lockFd);
d348c3
+        return 1;
d348c3
+    }
d348c3
+
d348c3
+    if (sb.st_mode & S_IROTH) {
d348c3
+        message(MESS_ERROR, "state file %s is world-readable and thus can"
d348c3
+                " be locked from other unprivileged users."
d348c3
+                " Skipping lock acquisition...\n",
d348c3
+                stateFilename);
d348c3
+        close(lockFd);
d348c3
+        return 0;
d348c3
+    }
d348c3
+
d348c3
     if (flock(lockFd, LOCK_EX | LOCK_NB) == -1) {
d348c3
         if (errno == EWOULDBLOCK) {
d348c3
             message(MESS_ERROR, "state file %s is already locked\n"
d348c3
diff --git a/logrotate.spec.in b/logrotate.spec.in
d348c3
index 92e1d97..3caabf2 100644
d348c3
--- a/logrotate.spec.in
d348c3
+++ b/logrotate.spec.in
d348c3
@@ -41,7 +41,6 @@ install -p -m 644 examples/logrotate.conf $RPM_BUILD_ROOT%{_sysconfdir}/logrotat
d348c3
 install -p -m 644 examples/btmp $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/btmp
d348c3
 install -p -m 644 examples/wtmp $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/wtmp
d348c3
 install -p -m 755 examples/logrotate.cron $RPM_BUILD_ROOT%{_sysconfdir}/cron.daily/logrotate
d348c3
-touch $RPM_BUILD_ROOT%{_localstatedir}/lib/logrotate.status
d348c3
 
d348c3
 %clean
d348c3
 rm -rf $RPM_BUILD_ROOT
d348c3
@@ -55,4 +54,4 @@ rm -rf $RPM_BUILD_ROOT
d348c3
 %attr(0755, root, root) %{_sysconfdir}/cron.daily/logrotate
d348c3
 %attr(0644, root, root) %config(noreplace) %{_sysconfdir}/logrotate.conf
d348c3
 %attr(0755, root, root) %{_sysconfdir}/logrotate.d
d348c3
-%attr(0644, root, root) %verify(not size md5 mtime) %config(noreplace) %{_localstatedir}/lib/logrotate.status
d348c3
+%ghost %attr(0640, root, root) %verify(not size md5 mtime) %{_localstatedir}/lib/logrotate.status
d348c3
diff --git a/test/Makefile.am b/test/Makefile.am
d348c3
index 914fe65..d6fb7c8 100644
d348c3
--- a/test/Makefile.am
d348c3
+++ b/test/Makefile.am
d348c3
@@ -87,6 +87,7 @@ TEST_CASES = \
d348c3
 	test-0086.sh \
d348c3
 	test-0087.sh \
d348c3
 	test-0088.sh \
d348c3
+	test-0092.sh \
d348c3
 	test-0100.sh \
d348c3
 	test-0101.sh
d348c3
 
d348c3
diff --git a/test/test-0087.sh b/test/test-0087.sh
d348c3
index 91e5266..aeff2c6 100755
d348c3
--- a/test/test-0087.sh
d348c3
+++ b/test/test-0087.sh
d348c3
@@ -8,6 +8,7 @@ cleanup 87
d348c3
 preptest test.log 87 1
d348c3
 
d348c3
 touch state
d348c3
+chmod 0640 state
d348c3
 
d348c3
 $RLR test-config.87 -f &
d348c3
 
d348c3
diff --git a/test/test-0092.sh b/test/test-0092.sh
d348c3
new file mode 100755
d348c3
index 0000000..be52e14
d348c3
--- /dev/null
d348c3
+++ b/test/test-0092.sh
d348c3
@@ -0,0 +1,19 @@
d348c3
+#!/bin/sh
d348c3
+
d348c3
+. ./test-common.sh
d348c3
+
d348c3
+# check state file locking
d348c3
+cleanup 92
d348c3
+
d348c3
+preptest test.log 92 1
d348c3
+
d348c3
+touch state
d348c3
+chmod 0644 state
d348c3
+flock state -c "sleep 10" &
d348c3
+
d348c3
+$RLR -f test-config.92 || exit 23
d348c3
+
d348c3
+checkoutput <
d348c3
+test.log 0
d348c3
+test.log.1 0 zero
d348c3
+EOF
d348c3
diff --git a/test/test-config.92.in b/test/test-config.92.in
d348c3
new file mode 100644
d348c3
index 0000000..ac93900
d348c3
--- /dev/null
d348c3
+++ b/test/test-config.92.in
d348c3
@@ -0,0 +1,4 @@
d348c3
+&DIR&/test.log {
d348c3
+    rotate 1
d348c3
+    create
d348c3
+}
d348c3
-- 
d348c3
2.35.3
d348c3
d348c3
d348c3
From 0d2d770cc5aa7bf14e84a2832249eeeb391b0b8a Mon Sep 17 00:00:00 2001
d348c3
From: Kamil Dudka <kdudka@redhat.com>
d348c3
Date: Wed, 25 May 2022 09:55:02 +0200
d348c3
Subject: [PATCH 2/3] drop world-readable permission on state file
d348c3
d348c3
... even when ACLs are enabled.  This is a follow-up to the fix
d348c3
of CVE-2022-1348.  It has no impact on security but makes the state
d348c3
file locking work again in more cases.
d348c3
d348c3
Closes: https://github.com/logrotate/logrotate/pull/446
d348c3
d348c3
Upstream-commit: addbd293242b0b78aa54f054e6c1d249451f137d
d348c3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
d348c3
---
d348c3
 logrotate.c       | 10 +++++++---
d348c3
 test/test-0048.sh |  1 +
d348c3
 2 files changed, 8 insertions(+), 3 deletions(-)
d348c3
d348c3
diff --git a/logrotate.c b/logrotate.c
d348c3
index 78153b3..8d49f26 100644
d348c3
--- a/logrotate.c
d348c3
+++ b/logrotate.c
d348c3
@@ -2498,6 +2498,7 @@ static int writeState(const char *stateFilename)
d348c3
     struct tm now;
d348c3
     time_t now_time, last_time;
d348c3
     char *prevCtx;
d348c3
+    int force_mode = 0;
d348c3
 
d348c3
     localtime_r(&nowSecs, &now;;
d348c3
 
d348c3
@@ -2565,10 +2566,13 @@ static int writeState(const char *stateFilename)
d348c3
 
d348c3
     close(fdcurr);
d348c3
 
d348c3
-    /* drop world-readable flag to prevent others from locking */
d348c3
-    sb.st_mode &= ~(mode_t)S_IROTH;
d348c3
+    if (sb.st_mode & (mode_t)S_IROTH) {
d348c3
+        /* drop world-readable flag to prevent others from locking */
d348c3
+        sb.st_mode &= ~(mode_t)S_IROTH;
d348c3
+        force_mode = 1;
d348c3
+    }
d348c3
 
d348c3
-    fdsave = createOutputFile(tmpFilename, O_RDWR | O_CREAT | O_TRUNC, &sb, prev_acl, 0);
d348c3
+    fdsave = createOutputFile(tmpFilename, O_RDWR | O_CREAT | O_TRUNC, &sb, prev_acl, force_mode);
d348c3
 #ifdef WITH_ACL
d348c3
     if (prev_acl) {
d348c3
         acl_free(prev_acl);
d348c3
diff --git a/test/test-0048.sh b/test/test-0048.sh
d348c3
index 62d606b..06b255a 100755
d348c3
--- a/test/test-0048.sh
d348c3
+++ b/test/test-0048.sh
d348c3
@@ -18,6 +18,7 @@ cat > state << EOF
d348c3
 logrotate state -- version 2
d348c3
 EOF
d348c3
 
d348c3
+chmod 0640 state
d348c3
 setfacl -m u:nobody:rwx state
d348c3
 
d348c3
 $RLR test-config.48
d348c3
-- 
d348c3
2.35.3
d348c3
d348c3
d348c3
From 105ed9f433a3aaf1aec93318aa9c8811b59d7b23 Mon Sep 17 00:00:00 2001
d348c3
From: Kamil Dudka <kdudka@redhat.com>
d348c3
Date: Fri, 27 May 2022 09:56:07 +0200
d348c3
Subject: [PATCH 3/3] lockState: do not print `error:` when exit code is
d348c3
 unaffected
d348c3
d348c3
Closes: https://github.com/logrotate/logrotate/pull/448
d348c3
d348c3
Upstream-commit: 31cf1099ab8514dfcae5a980bc77352edd5292f8
d348c3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
d348c3
---
d348c3
 logrotate.c | 4 ++--
d348c3
 1 file changed, 2 insertions(+), 2 deletions(-)
d348c3
d348c3
diff --git a/logrotate.c b/logrotate.c
d348c3
index 27deaf3..77db8c2 100644
d348c3
--- a/logrotate.c
d348c3
+++ b/logrotate.c
d348c3
@@ -2942,8 +2942,8 @@ static int lockState(const char *stateFilename, int skip_state_lock)
d348c3
     }
d348c3
 
d348c3
     if (sb.st_mode & S_IROTH) {
d348c3
-        message(MESS_ERROR, "state file %s is world-readable and thus can"
d348c3
-                " be locked from other unprivileged users."
d348c3
+        message(MESS_NORMAL, "warning: state file %s is world-readable"
d348c3
+                " and thus can be locked from other unprivileged users."
d348c3
                 " Skipping lock acquisition...\n",
d348c3
                 stateFilename);
d348c3
         close(lockFd);
d348c3
-- 
d348c3
2.35.3
d348c3