Merge pull request #174584 from oxzi/logrotate-3.20.1-21.11

[Backport release-21.11] logrotate: fix CVE-2022-1348
This commit is contained in:
ajs124
2022-05-26 13:48:09 +02:00
committed by GitHub
2 changed files with 77 additions and 0 deletions

View File

@@ -14,6 +14,14 @@ stdenv.mkDerivation rec {
sha256 = "sha256-OJOV++rtN9ry+l0c0eanpu/Pwu8cOHfyEaDWp3FZjkw=";
};
patches = [
# Fix CVE-2022-1348 by backporting two upstream commits
# - 1f76a381e2caa0603ae3dbc51ed0f1aa0d6658b9 and
# - addbd293242b0b78aa54f054e6c1d249451f137d
# in a custom patch, as cherry-picking directly failed.
./fix-cve-2022-1348.diff
];
# Logrotate wants to access the 'mail' program; to be done.
configureFlags = [
"--with-compress-command=${gzip}/bin/gzip"

View File

@@ -0,0 +1,69 @@
diff --git a/logrotate.c b/logrotate.c
index d7a1c19..45b985a 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -2514,6 +2514,7 @@ static int writeState(const char *stateFilename)
struct tm now;
time_t now_time, last_time;
char *prevCtx;
+ int force_mode = 0;
localtime_r(&nowSecs, &now);
@@ -2581,7 +2582,13 @@ static int writeState(const char *stateFilename)
close(fdcurr);
- fdsave = createOutputFile(tmpFilename, O_RDWR | O_CREAT | O_TRUNC, &sb, prev_acl, 0);
+ if (sb.st_mode & (mode_t)S_IROTH) {
+ /* drop world-readable flag to prevent others from locking */
+ sb.st_mode &= ~(mode_t)S_IROTH;
+ force_mode = 1;
+ }
+
+ fdsave = createOutputFile(tmpFilename, O_RDWR | O_CREAT | O_TRUNC, &sb, prev_acl, force_mode);
#ifdef WITH_ACL
if (prev_acl) {
acl_free(prev_acl);
@@ -2915,14 +2922,16 @@ static int readState(const char *stateFilename)
static int lockState(const char *stateFilename, int skip_state_lock)
{
int lockFd = open(stateFilename, O_RDWR | O_CLOEXEC);
+ struct stat sb;
+
if (lockFd == -1) {
if (errno == ENOENT) {
message(MESS_DEBUG, "Creating stub state file: %s\n",
stateFilename);
- /* create a stub state file with mode 0644 */
+ /* create a stub state file with mode 0640 */
lockFd = open(stateFilename, O_CREAT | O_EXCL | O_WRONLY,
- S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
+ S_IWUSR | S_IRUSR | S_IRGRP);
if (lockFd == -1) {
message(MESS_ERROR, "error creating stub state file %s: %s\n",
stateFilename, strerror(errno));
@@ -2942,6 +2951,22 @@ static int lockState(const char *stateFilename, int skip_state_lock)
return 0;
}
+ if (fstat(lockFd, &sb) == -1) {
+ message(MESS_ERROR, "error stat()ing state file %s: %s\n",
+ stateFilename, strerror(errno));
+ close(lockFd);
+ return 1;
+ }
+
+ if (sb.st_mode & S_IROTH) {
+ message(MESS_ERROR, "state file %s is world-readable and thus can"
+ " be locked from other unprivileged users."
+ " Skipping lock acquisition...\n",
+ stateFilename);
+ close(lockFd);
+ return 0;
+ }
+
if (flock(lockFd, LOCK_EX | LOCK_NB) == -1) {
if (errno == EWOULDBLOCK) {
message(MESS_ERROR, "state file %s is already locked\n"