Compare commits

...

10 Commits

Author SHA1 Message Date
Kamil Dudka 14292701b0 Resolves: #2148934 - enforce stricter parsing of config files 2023-05-18 15:03:54 +00:00
Kamil Dudka b90be9f1f5 Related: CVE-2022-1348 - lockState: do not print `error:` when exit code is unaffected 2022-05-27 17:50:13 +02:00
Kamil Dudka 30811b8ad8 Related: CVE-2022-1348 - add gating.yaml
... taken from curl's c9s branch
2022-05-26 12:52:54 +02:00
Kamil Dudka 3e01c1aab3 Resolves: CVE-2022-1348 - potential DoS from unprivileged users via the state file 2022-05-25 17:58:14 +02:00
Mohan Boddu 064cb12ab9 Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
Signed-off-by: Mohan Boddu <mboddu@redhat.com>
2021-08-09 22:00:58 +00:00
Kamil Dudka f6894c13ee Resolves: #1934601 - make `renamecopy` and `copytruncate` override each other 2021-05-04 18:11:02 +02:00
Kamil Dudka 1e9343ea61 Resolves: #1934629 - unify documentation of copy/copytruncate/renamecopy 2021-05-04 18:10:48 +02:00
Kamil Dudka dcfa8f1adc Resolves: #1938810 - fix resource leaks reported by Coverity 2021-05-04 18:10:27 +02:00
Mohan Boddu 97cb3ded3f - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
Signed-off-by: Mohan Boddu <mboddu@redhat.com>
2021-04-16 01:51:36 +00:00
DistroBaker 1347955b9f Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/logrotate.git#e5f94db06726ff514b877815033df8acbc52f91d
2021-02-02 13:20:47 +00:00
8 changed files with 1625 additions and 5 deletions

1
.logrotate.metadata Normal file
View File

@ -0,0 +1 @@
6b9aa5efd4551377e9869e8d3303d90a946566f6 logrotate-3.18.0.tar.xz

View File

@ -0,0 +1,615 @@
From 471cf0a6a90e5d45f116f404e1276ea730dbece6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Fri, 26 Mar 2021 17:18:09 +0100
Subject: [PATCH 1/9] Do not report OOM incorrectly
In case there is no file in the set to rotate `calloc(0, ...)` is called
, which might return NULL.
Order the check for a zero number of files first, to void calling calloc
with a size of zero.
Upstream-commit: 7b65b267d73970eb59061be907c8c35b4396ada9
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
logrotate.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/logrotate.c b/logrotate.c
index 507c85a..a8c8480 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -2212,11 +2212,6 @@ static int rotateLogSet(const struct logInfo *log, int force)
struct logState **state;
struct logNames **rotNames;
- logHasErrors = calloc(log->numFiles, sizeof(int));
- if (!logHasErrors) {
- message_OOM();
- return 1;
- }
message(MESS_DEBUG, "\nrotating pattern: %s ", log->pattern);
if (force) {
message(MESS_DEBUG, "forced from command line ");
@@ -2277,10 +2272,15 @@ static int rotateLogSet(const struct logInfo *log, int force)
if (log->numFiles == 0) {
message(MESS_DEBUG, "No logs found. Rotation not needed.\n");
- free(logHasErrors);
return 0;
}
+ logHasErrors = calloc(log->numFiles, sizeof(int));
+ if (!logHasErrors) {
+ message_OOM();
+ return 1;
+ }
+
if (log->flags & LOG_FLAG_SU) {
if (switch_user(log->suUid, log->suGid) != 0) {
free(logHasErrors);
--
2.30.2
From 96203f4cdc64e2df3d203231bd1247424a20875e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 19 Apr 2021 15:35:37 +0200
Subject: [PATCH 2/9] Unify asprintf usage
Unify the error checking of asprintf(3).
Also reset the target string pointer to NULL on error, if it is non-
local, since the content is undefined according to the specification.
Also fix potential NULL-pointer usage in sprintf(3):
logrotate.c:1595:
rotNames->dirName = malloc(strlen(ld) + strlen(log->oldDir) + 2);
sprintf(rotNames->dirName, "%s/%s", ld, log->oldDir);
Upstream-commit: 5afcdeecc5a3bfe07671a3c05c7a301da9206ccd
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 28 +++++++++++++---------------
logrotate.c | 9 ++++++---
2 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/config.c b/config.c
index df2d90b..19dcfce 100644
--- a/config.c
+++ b/config.c
@@ -815,21 +815,19 @@ int readAllConfigPaths(const char **paths)
for (i = 0; i < defTabooCount; i++) {
- int bytes;
char *pattern = NULL;
/* generate a pattern by concatenating star (wildcard) to the
* suffix literal
*/
- bytes = asprintf(&pattern, "*%s", defTabooExts[i]);
- if (bytes != -1) {
- tabooPatterns[i] = pattern;
- tabooCount++;
- } else {
+ if (asprintf(&pattern, "*%s", defTabooExts[i]) < 0) {
free_2d_array(tabooPatterns, tabooCount);
message_OOM();
return 1;
}
+
+ tabooPatterns[i] = pattern;
+ tabooCount++;
}
for (file = paths; *file; file++) {
@@ -1421,7 +1419,6 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
}
while (*endtag) {
- int bytes;
char *pattern = NULL;
chptr = endtag;
@@ -1437,10 +1434,11 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
RAISE_ERROR();
}
tabooPatterns = tmp;
- bytes = asprintf(&pattern, "*%.*s", (int)(chptr - endtag), endtag);
+ if (asprintf(&pattern, "*%.*s", (int)(chptr - endtag), endtag) < 0) {
+ message_OOM();
+ RAISE_ERROR();
+ }
- /* should test for malloc() failure */
- assert(bytes != -1);
tabooPatterns[tabooCount] = pattern;
tabooCount++;
}
@@ -1481,7 +1479,6 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
}
while (*endtag) {
- int bytes;
char *pattern = NULL;
char **tmp;
@@ -1496,10 +1493,11 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
RAISE_ERROR();
}
tabooPatterns = tmp;
- bytes = asprintf(&pattern, "%.*s", (int)(chptr - endtag), endtag);
+ if (asprintf(&pattern, "%.*s", (int)(chptr - endtag), endtag) < 0) {
+ message_OOM();
+ RAISE_ERROR();
+ }
- /* should test for malloc() failure */
- assert(bytes != -1);
tabooPatterns[tabooCount] = pattern;
tabooCount++;
@@ -1540,7 +1538,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
env_home = pwd->pw_dir;
}
- if (asprintf(&new_key, "%s/%s", env_home, key + 2) == -1) {
+ if (asprintf(&new_key, "%s/%s", env_home, key + 2) < 0) {
message_OOM();
RAISE_ERROR();
}
diff --git a/logrotate.c b/logrotate.c
index a8c8480..e294352 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -1576,9 +1576,9 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
ld = dirname(logpath);
if (log->oldDir) {
if (log->oldDir[0] != '/') {
- rotNames->dirName =
- malloc(strlen(ld) + strlen(log->oldDir) + 2);
- sprintf(rotNames->dirName, "%s/%s", ld, log->oldDir);
+ if (asprintf(&rotNames->dirName, "%s/%s", ld, log->oldDir) < 0) {
+ rotNames->dirName = NULL;
+ }
} else
rotNames->dirName = strdup(log->oldDir);
} else
@@ -1983,6 +1983,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
if (asprintf(&(rotNames->finalName), "%s/%s%s%s", rotNames->dirName,
rotNames->baseName, dext_str, fileext) < 0) {
message_OOM();
+ rotNames->finalName = NULL;
return 1;
}
if (asprintf(&destFile, "%s%s", rotNames->finalName, compext) < 0) {
@@ -2001,6 +2002,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
if (asprintf(&(rotNames->finalName), "%s/%s.%d%s", rotNames->dirName,
rotNames->baseName, logStart, fileext) < 0) {
message_OOM();
+ rotNames->finalName = NULL;
}
}
@@ -2084,6 +2086,7 @@ static int rotateSingleLog(const struct logInfo *log, unsigned logNum,
free(rotNames->disposeName);
if (asprintf(&rotNames->disposeName, "%s%s", rotNames->finalName, ext) < 0) {
message_OOM();
+ rotNames->disposeName = NULL;
return 1;
}
--
2.30.2
From 3cf921e0d58993b064cd6d52b44835008345f498 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 19 Apr 2021 15:40:19 +0200
Subject: [PATCH 3/9] Update custom asprintf implementation
Check for vsnprintf(3) failures.
Silence conversion warnings.
Do not call exit(2) on allocation failure, but return -1 like the
specification says. All callers check the return value, since they
need to handle standard asprintf(3) implementations.
Upstream-commit: f917b31dbb47992bf5c5342c7312ddb2e64efc40
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/config.c b/config.c
index 19dcfce..0d79980 100644
--- a/config.c
+++ b/config.c
@@ -61,24 +61,20 @@ int asprintf(char **string_ptr, const char *format, ...)
va_start(arg, format);
size = vsnprintf(NULL, 0, format, arg);
- size++;
va_end(arg);
- va_start(arg, format);
- str = malloc(size);
+ if (size < 0) {
+ return -1;
+ }
+ str = malloc((size_t)size + 1);
if (str == NULL) {
- va_end(arg);
- /*
- * Strictly speaking, GNU asprintf doesn't do this,
- * but the caller isn't checking the return value.
- */
- message_OOM();
- exit(1);
+ return -1;
}
- rv = vsnprintf(str, size, format, arg);
+ va_start(arg, format);
+ rv = vsnprintf(str, (size_t)size + 1, format, arg);
va_end(arg);
*string_ptr = str;
- return (rv);
+ return rv;
}
#endif
--
2.30.2
From ace9818a606a0c96bb6e4da479ed151650b8fa3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 19 Apr 2021 15:45:55 +0200
Subject: [PATCH 4/9] Use asprintf instead of split malloc + sprintf
Use asprintf(3) instead of split usage of malloc(3) and sprintf(3) to
reduce the chance of potential size inconsistencies.
Upstream-commit: 001352baa924f021748513b6d09d37eca754d5cc
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 5 ++---
logrotate.c | 25 ++++++++++++-------------
2 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/config.c b/config.c
index 0d79980..2905ff7 100644
--- a/config.c
+++ b/config.c
@@ -1886,13 +1886,12 @@ duperror:
continue;
}
}
- ld = malloc(strlen(dirName) + strlen(newlog->oldDir) + 2);
- if (ld == NULL) {
+ if (asprintf(&ld, "%s/%s", dirName, newlog->oldDir) < 0) {
message_OOM();
free(dirpath);
goto error;
}
- sprintf(ld, "%s/%s", dirName, newlog->oldDir);
+
free(dirpath);
if (newlog->oldDir[0] != '/') {
diff --git a/logrotate.c b/logrotate.c
index e294352..a72329e 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -1810,15 +1810,6 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
}
}
- /* adding 2 due to / and \0 being added by snprintf */
- rotNames->firstRotated =
- malloc(strlen(rotNames->dirName) + strlen(rotNames->baseName) +
- strlen(fileext) + strlen(compext) + DATEEXT_LEN + 2 );
- if (rotNames->firstRotated == NULL) {
- message_OOM();
- return 1;
- }
-
if (log->flags & LOG_FLAG_DATEEXT) {
/* glob for compressed files with our pattern
* and compress ext */
@@ -1882,9 +1873,13 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
rotNames->disposeName = NULL;
}
/* firstRotated is most recently created/compressed rotated log */
- sprintf(rotNames->firstRotated, "%s/%s%s%s%s",
+ if (asprintf(&rotNames->firstRotated, "%s/%s%s%s%s",
rotNames->dirName, rotNames->baseName, dext_str, fileext,
- (log->flags & LOG_FLAG_DELAYCOMPRESS) ? "" : compext);
+ (log->flags & LOG_FLAG_DELAYCOMPRESS) ? "" : compext) < 0) {
+ message_OOM();
+ rotNames->firstRotated = NULL;
+ return 1;
+ }
globfree(&globResult);
free(glob_pattern);
} else {
@@ -1915,9 +1910,13 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
}
}
- sprintf(rotNames->firstRotated, "%s/%s.%d%s%s", rotNames->dirName,
+ if (asprintf(&rotNames->firstRotated, "%s/%s.%d%s%s", rotNames->dirName,
rotNames->baseName, logStart, fileext,
- (log->flags & LOG_FLAG_DELAYCOMPRESS) ? "" : compext);
+ (log->flags & LOG_FLAG_DELAYCOMPRESS) ? "" : compext) < 0) {
+ message_OOM();
+ rotNames->firstRotated = NULL;
+ return 1;
+ }
for (i = rotateCount + logStart - 1; (i >= 0) && !hasErrors; i--) {
free(newName);
--
2.30.2
From e8a655ef1977add152d79c4dc8148fe7b1c9bca2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 19 Apr 2021 17:52:48 +0200
Subject: [PATCH 5/9] Mark read-only string variable const
Prevent it accidentally being passed to free(3) or similar.
Upstream-commit: 2231aba823ff6e5a18d996e81ef63df0871224dd
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
logrotate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/logrotate.c b/logrotate.c
index a72329e..7d49261 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -1567,7 +1567,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
state->lastRotated = now;
{
- char *ld;
+ const char *ld;
char *logpath = strdup(log->files[logNum]);
if (logpath == NULL) {
message_OOM();
--
2.30.2
From c06f20f781c74b2256e8f1757433db7e043b4ddf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 19 Apr 2021 17:59:21 +0200
Subject: [PATCH 6/9] Limit scope of variable
Limit the scope of a variable, by splitting it into several distinct
block scope variables.
This makes some asprintf(3) calls obsolete, and improves readability by
splitting the purpose of the variable.
Upstream-commit: b37fb75f569b3ddde30dd85184ea160f63abb7d5
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
logrotate.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/logrotate.c b/logrotate.c
index 7d49261..962ac55 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -1529,7 +1529,6 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
struct logState *state, struct logNames *rotNames)
{
struct tm now;
- char *oldName = NULL;
const char *compext = "";
const char *fileext = "";
int hasErrors = 0;
@@ -1770,11 +1769,8 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
sortGlobResult(&globResult, strlen(rotNames->dirName) + 1 + strlen(rotNames->baseName), dformat);
for (glob_count = 0; glob_count < globResult.gl_pathc && !hasErrors; glob_count++) {
struct stat sbprev;
+ const char *oldName = globResult.gl_pathv[glob_count];
- if (asprintf(&oldName, "%s", (globResult.gl_pathv)[glob_count]) < 0) {
- message_OOM();
- return 1;
- }
if (stat(oldName, &sbprev)) {
if (errno == ENOENT)
message(MESS_DEBUG, "previous log %s does not exist\n", oldName);
@@ -1783,7 +1779,6 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
} else {
hasErrors = compressLogFile(oldName, log, &sbprev);
}
- free(oldName);
}
} else {
message(MESS_DEBUG,
@@ -1793,6 +1788,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
free(glob_pattern);
} else {
struct stat sbprev;
+ char *oldName;
if (asprintf(&oldName, "%s/%s.%d%s", rotNames->dirName,
rotNames->baseName, logStart, fileext) < 0) {
message_OOM();
@@ -1853,16 +1849,14 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
}
if (mail_out != (size_t)-1) {
/* oldName is oldest Backup found (for unlink later) */
- if (asprintf(&oldName, "%s", (globResult.gl_pathv)[mail_out]) < 0) {
- message_OOM();
- return 1;
- }
+ const char *oldName = globResult.gl_pathv[mail_out];
rotNames->disposeName = strdup(oldName);
if (rotNames->disposeName == NULL) {
message_OOM();
+ globfree(&globResult);
+ free(glob_pattern);
return 1;
}
- free(oldName);
} else {
free(rotNames->disposeName);
rotNames->disposeName = NULL;
@@ -1878,6 +1872,8 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
(log->flags & LOG_FLAG_DELAYCOMPRESS) ? "" : compext) < 0) {
message_OOM();
rotNames->firstRotated = NULL;
+ globfree(&globResult);
+ free(glob_pattern);
return 1;
}
globfree(&globResult);
@@ -1885,6 +1881,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
} else {
int i;
char *newName = NULL;
+ char *oldName;
if (rotateCount == -1) {
rotateCount = findLastRotated(rotNames, fileext, compext);
--
2.30.2
From 1a1eb69e6c4ae403edceb411cb0bbc80473e2527 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 20 Apr 2021 17:41:16 +0200
Subject: [PATCH 7/9] Free memory on noolddir configuration
Consider the following configuration:
olddir /var/log/foo
noolddir
Do not leak the memory of the initial olddir path.
Upstream-commit: 59e8e321d3221a3beaf7b9c99b17d5cb7dbcfaf0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config.c b/config.c
index 2905ff7..b7406f5 100644
--- a/config.c
+++ b/config.c
@@ -1134,7 +1134,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if (newlog->dateformat == NULL)
continue;
} else if (!strcmp(key, "noolddir")) {
- newlog->oldDir = NULL;
+ freeLogItem(oldDir);
} else if (!strcmp(key, "mailfirst")) {
newlog->flags |= LOG_FLAG_MAILFIRST;
} else if (!strcmp(key, "maillast")) {
--
2.30.2
From 4aabfd0fe19832ba1df8919356d1d2d4b463937d Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 3 May 2021 15:14:09 +0200
Subject: [PATCH 8/9] readConfigFile: release `globerr_msg` on all code paths
This eliminates the following reports by Coverity:
Error: RESOURCE_LEAK (CWE-772):
logrotate-3.18.0.18_7a4d/config.c:1798: alloc_arg: "asprintf" allocates memory that is stored into "globerr_msg". [Note: The source code implementation of the function has been overridden by a builtin model.]
logrotate-3.18.0.18_7a4d/config.c:2116: leaked_storage: Variable "globerr_msg" going out of scope leaks the storage it points to.
Error: RESOURCE_LEAK (CWE-772):
logrotate-3.18.0.18_7a4d/config.c:1798: alloc_arg: "asprintf" allocates memory that is stored into "globerr_msg". [Note: The source code implementation of the function has been overridden by a builtin model.]
logrotate-3.18.0.18_7a4d/config.c:2122: leaked_storage: Variable "globerr_msg" going out of scope leaks the storage it points to.
Closes: https://github.com/logrotate/logrotate/pull/387
Upstream-commit: 97f841be2bb52b9ac00cd564a6eb0a853d1017bd
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/config.c b/config.c
index b7406f5..91fd412 100644
--- a/config.c
+++ b/config.c
@@ -2086,12 +2086,14 @@ next_state: ;
munmap(buf, length);
close(fd);
+ free(globerr_msg);
return logerror;
error:
/* free is a NULL-safe operation */
free(key);
munmap(buf, length);
close(fd);
+ free(globerr_msg);
return 1;
}
--
2.30.2
From b5610cd1b0bc2cf9ab887007a953fbf6340cb150 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 3 May 2021 15:17:59 +0200
Subject: [PATCH 9/9] prerotateSingleLog: release `oldName` on all code paths
This eliminates the following reports by Coverity:
Error: RESOURCE_LEAK (CWE-772):
logrotate-3.18.0.18_7a4d/logrotate.c:1911: alloc_arg: "asprintf" allocates memory that is stored into "oldName". [Note: The source code implementation of the function has been overridden by a builtin model.]
logrotate-3.18.0.18_7a4d/logrotate.c:1919: noescape: Resource "oldName" is not freed or pointed-to in "strdup".
logrotate-3.18.0.18_7a4d/logrotate.c:1922: leaked_storage: Variable "oldName" going out of scope leaks the storage it points to.
Error: RESOURCE_LEAK (CWE-772):
logrotate-3.18.0.18_7a4d/logrotate.c:1911: alloc_arg: "asprintf" allocates memory that is stored into "oldName". [Note: The source code implementation of the function has been overridden by a builtin model.]
logrotate-3.18.0.18_7a4d/logrotate.c:1919: noescape: Resource "oldName" is not freed or pointed-to in "strdup".
logrotate-3.18.0.18_7a4d/logrotate.c:1931: leaked_storage: Variable "oldName" going out of scope leaks the storage it points to.
Closes: https://github.com/logrotate/logrotate/pull/387
Upstream-commit: 85bc130b19344a3d9c8b472142df14ddcd0a166d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
logrotate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/logrotate.c b/logrotate.c
index 962ac55..d3f2825 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -1903,6 +1903,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
rotNames->disposeName = strdup(oldName);
if (rotNames->disposeName == NULL) {
message_OOM();
+ free(oldName);
return 1;
}
}
@@ -1911,6 +1912,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
rotNames->baseName, logStart, fileext,
(log->flags & LOG_FLAG_DELAYCOMPRESS) ? "" : compext) < 0) {
message_OOM();
+ free(oldName);
rotNames->firstRotated = NULL;
return 1;
}
--
2.30.2

View File

@ -0,0 +1,62 @@
From 4810afca1223099c1546da8d73d653c0d1eff96e Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 27 Apr 2021 18:36:30 +0200
Subject: [PATCH 1/2] logrotate.8: unify documentation of
copy/copytruncate/renamecopy
Bug: https://bugzilla.redhat.com/1934629
Closes: https://github.com/logrotate/logrotate/pull/386
Upstream-commit: 6ac9fe5759678b4c2b312eea490ebbae25092213
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
logrotate.8.in | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/logrotate.8.in b/logrotate.8.in
index f27c279..8064d68 100644
--- a/logrotate.8.in
+++ b/logrotate.8.in
@@ -411,7 +411,8 @@ Make a copy of the log file, but don't change the original at all.
This option can be used, for instance, to make a snapshot of the current
log file, or when some other utility needs to truncate or parse the file.
When this option is used, the \fBcreate\fR option will have no effect,
-as the old log file stays in place.
+as the old log file stays in place. The \fBcopy\fR option allows storing
+rotated log files on the different devices using \fBolddir\fR directive.
.TP
\fBnocopy\fR
@@ -427,7 +428,9 @@ and thus might continue writing (appending) to the previous log file forever.
Note that there is a very small time slice between copying the file and
truncating it, so some logging data might be lost.
When this option is used, the \fBcreate\fR option will have no effect,
-as the old log file stays in place.
+as the old log file stays in place. The \fBcopytruncate\fR option allows
+storing rotated log files on the different devices using \fBolddir\fR
+directive.
.TP
\fBnocopytruncate\fR
@@ -438,9 +441,14 @@ Do not truncate the original log file in place after creating a copy
\fBrenamecopy\fR
Log file is renamed to temporary filename in the same directory by adding
".tmp" extension to it. After that, \fBpostrotate\fR script is run
-and log file is copied from temporary filename to final filename. This allows
-storing rotated log files on the different devices using \fBolddir\fR
-directive. In the end, temporary filename is removed.
+and log file is copied from temporary filename to final filename. In the end,
+temporary filename is removed. The \fBrenamecopy\fR option allows storing
+rotated log files on the different devices using \fBolddir\fR directive.
+
+.TP
+\fBnorenamecopy\fR
+Do not rename and copy the original log file
+(this overrides the \fBrenamecopy\fR option).
.TP
\fBshred\fR
--
2.30.2

View File

@ -0,0 +1,89 @@
From 337eb1492f8b694542d704c7a4612e3211f717e5 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 27 Apr 2021 20:52:32 +0200
Subject: [PATCH 2/2] make `renamecopy` and `copytruncate` override each other
These option cannot work together. This rule prevents unnecessary
rotation failure in case one of the options comes from the global
configuration and the other one from log-specific configuration.
Bug: https://bugzilla.redhat.com/1934601
Closes: https://github.com/logrotate/logrotate/pull/386
Upstream-commit: fe53a0efd21c11dbe9705564f92f5d9aa6bf855e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 2 ++
logrotate.8.in | 3 ++-
test/test-config.24.in | 3 +++
test/test-config.58.in | 3 +++
4 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/config.c b/config.c
index 91fd412..1bca9e4 100644
--- a/config.c
+++ b/config.c
@@ -1106,10 +1106,12 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
newlog->flags &= ~LOG_FLAG_SHAREDSCRIPTS;
} else if (!strcmp(key, "copytruncate")) {
newlog->flags |= LOG_FLAG_COPYTRUNCATE;
+ newlog->flags &= ~LOG_FLAG_TMPFILENAME;
} else if (!strcmp(key, "nocopytruncate")) {
newlog->flags &= ~LOG_FLAG_COPYTRUNCATE;
} else if (!strcmp(key, "renamecopy")) {
newlog->flags |= LOG_FLAG_TMPFILENAME;
+ newlog->flags &= ~LOG_FLAG_COPYTRUNCATE;
} else if (!strcmp(key, "norenamecopy")) {
newlog->flags &= ~LOG_FLAG_TMPFILENAME;
} else if (!strcmp(key, "copy")) {
diff --git a/logrotate.8.in b/logrotate.8.in
index 8064d68..f0aa23f 100644
--- a/logrotate.8.in
+++ b/logrotate.8.in
@@ -430,7 +430,7 @@ truncating it, so some logging data might be lost.
When this option is used, the \fBcreate\fR option will have no effect,
as the old log file stays in place. The \fBcopytruncate\fR option allows
storing rotated log files on the different devices using \fBolddir\fR
-directive.
+directive. The \fBcopytruncate\fR option implies \fBnorenamecopy\fR.
.TP
\fBnocopytruncate\fR
@@ -444,6 +444,7 @@ Log file is renamed to temporary filename in the same directory by adding
and log file is copied from temporary filename to final filename. In the end,
temporary filename is removed. The \fBrenamecopy\fR option allows storing
rotated log files on the different devices using \fBolddir\fR directive.
+The \fBrenamecopy\fR option implies \fBnocopytruncate\fR.
.TP
\fBnorenamecopy\fR
diff --git a/test/test-config.24.in b/test/test-config.24.in
index 35cfcd3..7a2a760 100644
--- a/test/test-config.24.in
+++ b/test/test-config.24.in
@@ -1,5 +1,8 @@
create
+# will be overridden by copytruncate
+renamecopy
+
&DIR&/test*.log {
daily
copytruncate
diff --git a/test/test-config.58.in b/test/test-config.58.in
index 34906da..79058be 100644
--- a/test/test-config.58.in
+++ b/test/test-config.58.in
@@ -1,5 +1,8 @@
create
+# will be overridden by renamecopy
+copytruncate
+
&DIR&/test.log {
renamecopy
weekly
--
2.30.2

View File

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

View File

@ -0,0 +1,556 @@
From 6db706b51af0a6f6ce28bceaefb4157347d2fa18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 20 Apr 2021 17:41:10 +0200
Subject: [PATCH 1/6] Log if keyword is not properly separated
The man page states
Values are separated from directives by whitespace and/or an
optional =.
But logrotate does accept no separator, like
rotate7
Log those occurrences with a normal severity, as this usage is not
intended.
Upstream-commit: 2b588b5ec2e5c27bee857c4abeddafa6a9602ebc
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/config.c b/config.c
index 1bca9e4..8049211 100644
--- a/config.c
+++ b/config.c
@@ -1088,6 +1088,11 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
key = isolateWord(&start, &buf, length);
if (key == NULL)
continue;
+ if (!isspace((unsigned char)*start)) {
+ message(MESS_NORMAL, "%s:%d keyword '%s' not properly"
+ " separated, found %#x\n",
+ configFile, lineNum, key, *start);
+ }
if (!strcmp(key, "compress")) {
newlog->flags |= LOG_FLAG_COMPRESS;
} else if (!strcmp(key, "nocompress")) {
--
2.38.1
From 2a22bf99b41e737fcd8c986be5c4fb761ab101c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 20 Apr 2021 17:41:12 +0200
Subject: [PATCH 2/6] Log error on keyword parse failure
isolateWord() only fails on OOM and EOF.
Upstream-commit: 326179a901b0a8d10e902cae0abab0c68d7abc98
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/config.c b/config.c
index 8049211..fd6e026 100644
--- a/config.c
+++ b/config.c
@@ -1086,8 +1086,11 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if (isalpha((unsigned char)*start)) {
free(key);
key = isolateWord(&start, &buf, length);
- if (key == NULL)
+ if (key == NULL) {
+ message(MESS_ERROR, "%s:%d failed to parse keyword\n",
+ configFile, lineNum);
continue;
+ }
if (!isspace((unsigned char)*start)) {
message(MESS_NORMAL, "%s:%d keyword '%s' not properly"
" separated, found %#x\n",
--
2.38.1
From d3b2d0d058d41dd7efccadff8506285af791711c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 20 Apr 2021 17:41:20 +0200
Subject: [PATCH 3/6] Fail on parse error of required option value
Fail on a parse error of a required option value of the directives
include, extension, addextension, rotate, start, minage, maxage,
shredcycles and su.
Failing is better than silently skipping a directive and running with an
undesired configuration.
Upstream-commit: 906ea11981cb1842538c4aaed395885fda693e47
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 49 ++++++++++++++++++++++++++++++-------------------
1 file changed, 30 insertions(+), 19 deletions(-)
diff --git a/config.c b/config.c
index fd6e026..227feec 100644
--- a/config.c
+++ b/config.c
@@ -1154,8 +1154,11 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
mode_t tmp_mode = NO_MODE;
free(key);
key = isolateLine(&start, &buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ message(MESS_ERROR, "%s:%d failed to parse su option value\n",
+ configFile, lineNum);
+ RAISE_ERROR();
+ }
rv = readModeUidGid(configFile, lineNum, key, "su",
&tmp_mode, &newlog->suUid,
@@ -1268,13 +1271,14 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(key);
key = isolateValue(configFile, lineNum, "shred cycles",
&start, &buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ RAISE_ERROR();
+ }
newlog->shred_cycles = (int)strtoul(key, &chptr, 0);
if (*chptr || newlog->shred_cycles < 0) {
message(MESS_ERROR, "%s:%d bad shred cycles '%s'\n",
configFile, lineNum, key);
- goto error;
+ RAISE_ERROR();
}
} else if (!strcmp(key, "hourly")) {
set_criterium(&newlog->criterium, ROT_HOURLY, &criterium_set);
@@ -1309,8 +1313,9 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(key);
key = isolateValue(configFile, lineNum, "rotate count", &start,
&buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ RAISE_ERROR();
+ }
newlog->rotateCount = (int)strtol(key, &chptr, 0);
if (*chptr || newlog->rotateCount < -1) {
message(MESS_ERROR,
@@ -1322,8 +1327,9 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(key);
key = isolateValue(configFile, lineNum, "start count", &start,
&buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ RAISE_ERROR();
+ }
newlog->logStart = (int)strtoul(key, &chptr, 0);
if (*chptr || newlog->logStart < 0) {
message(MESS_ERROR, "%s:%d bad start count '%s'\n",
@@ -1334,8 +1340,9 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(key);
key = isolateValue(configFile, lineNum, "minage count", &start,
&buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ RAISE_ERROR();
+ }
newlog->rotateMinAge = (int)strtoul(key, &chptr, 0);
if (*chptr || newlog->rotateMinAge < 0) {
message(MESS_ERROR, "%s:%d bad minimum age '%s'\n",
@@ -1346,8 +1353,9 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(key);
key = isolateValue(configFile, lineNum, "maxage count", &start,
&buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ RAISE_ERROR();
+ }
newlog->rotateAge = (int)strtoul(key, &chptr, 0);
if (*chptr || newlog->rotateAge < 0) {
message(MESS_ERROR, "%s:%d bad maximum age '%s'\n",
@@ -1519,8 +1527,9 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(key);
key = isolateValue(configFile, lineNum, "include", &start,
&buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ RAISE_ERROR();
+ }
if (key[0] == '~' && key[1] == '/') {
/* replace '~' with content of $HOME cause low-level functions
@@ -1582,8 +1591,9 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(key);
key = isolateValue(configFile, lineNum, "extension name", &start,
&buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ RAISE_ERROR();
+ }
freeLogItem (extension);
newlog->extension = key;
key = NULL;
@@ -1593,8 +1603,9 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
free(key);
key = isolateValue(configFile, lineNum, "addextension name", &start,
&buf, length);
- if (key == NULL)
- continue;
+ if (key == NULL) {
+ RAISE_ERROR();
+ }
freeLogItem (addextension);
newlog->addextension = key;
key = NULL;
--
2.38.1
From 69d2febc6e6e81e34d944b1652144df2e154965d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 26 Jul 2021 19:35:00 +0200
Subject: [PATCH 4/6] Do not warn on key value pair separated by only an equal
sign
Do not warn if a configuration directive is specified with the key and
value separated by just an equal sign, like:
size=+2048k
The warning is intended for the usage of:
size2048k
Fixes: 2b588b5e ("Log if keyword is not properly separated")
Fixes: #410
Upstream-commit: a98c38bc867ec59e00625b48262bb3334c8f5728
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config.c b/config.c
index 227feec..6eb94d4 100644
--- a/config.c
+++ b/config.c
@@ -1091,7 +1091,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
configFile, lineNum);
continue;
}
- if (!isspace((unsigned char)*start)) {
+ if (!isspace((unsigned char)*start) && *start != '=') {
message(MESS_NORMAL, "%s:%d keyword '%s' not properly"
" separated, found %#x\n",
configFile, lineNum, key, *start);
--
2.38.1
From 3a1f8e746b2753efe7472580b1db4395553b1d34 Mon Sep 17 00:00:00 2001
From: Felix Wilhelm <fwilhelm@google.com>
Date: Thu, 21 Oct 2021 09:47:57 +0000
Subject: [PATCH 5/6] config.c: enforce stricter parsing of config files
Abort parsing of config files that contain invalid lines.
This makes it harder to abuse logrotate for privilege escalation
attacks where an attacker can partially control a privileged file write.
Upstream-commit: 124e4ca6532b0fe823fa2ec145294547b3aaeb4b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 7 ++++---
test/Makefile.am | 4 +++-
test/test-0102.sh | 16 ++++++++++++++++
test/test-0103.sh | 16 ++++++++++++++++
test/test-config.102.in | 10 ++++++++++
test/test-config.103.in | 12 ++++++++++++
6 files changed, 61 insertions(+), 4 deletions(-)
create mode 100755 test/test-0102.sh
create mode 100755 test/test-0103.sh
create mode 100644 test/test-config.102.in
create mode 100644 test/test-config.103.in
diff --git a/config.c b/config.c
index 6eb94d4..c0fd4ff 100644
--- a/config.c
+++ b/config.c
@@ -1089,12 +1089,13 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if (key == NULL) {
message(MESS_ERROR, "%s:%d failed to parse keyword\n",
configFile, lineNum);
- continue;
+ RAISE_ERROR();
}
if (!isspace((unsigned char)*start) && *start != '=') {
- message(MESS_NORMAL, "%s:%d keyword '%s' not properly"
+ message(MESS_ERROR, "%s:%d keyword '%s' not properly"
" separated, found %#x\n",
configFile, lineNum, key, *start);
+ RAISE_ERROR();
}
if (!strcmp(key, "compress")) {
newlog->flags |= LOG_FLAG_COMPRESS;
@@ -1973,7 +1974,7 @@ duperror:
message(MESS_ERROR, "%s:%d lines must begin with a keyword "
"or a filename (possibly in double quotes)\n",
configFile, lineNum);
- state = STATE_SKIP_LINE;
+ RAISE_ERROR();
}
break;
case STATE_SKIP_LINE:
diff --git a/test/Makefile.am b/test/Makefile.am
index d6fb7c8..cd357e5 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -89,7 +89,9 @@ TEST_CASES = \
test-0088.sh \
test-0092.sh \
test-0100.sh \
- test-0101.sh
+ test-0101.sh \
+ test-0102.sh \
+ test-0103.sh
EXTRA_DIST = \
compress \
diff --git a/test/test-0102.sh b/test/test-0102.sh
new file mode 100755
index 0000000..d2550a5
--- /dev/null
+++ b/test/test-0102.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+. ./test-common.sh
+
+cleanup 102
+
+# ------------------------------- Test 102 ------------------------------------
+# test invalid config file with binary content
+preptest test.log 102 1
+
+$RLR test-config.102 --force
+
+if [ $? -eq 0 ]; then
+ echo "No error, but there should be one."
+ exit 3
+fi
diff --git a/test/test-0103.sh b/test/test-0103.sh
new file mode 100755
index 0000000..bccd8ed
--- /dev/null
+++ b/test/test-0103.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+. ./test-common.sh
+
+cleanup 103
+
+# ------------------------------- Test 103 ------------------------------------
+# test invalid config file with unknown keywords
+preptest test.log 103 1
+
+$RLR test-config.103 --force
+
+if [ $? -eq 0 ]; then
+ echo "No error, but there should be one."
+ exit 3
+fi
diff --git a/test/test-config.102.in b/test/test-config.102.in
new file mode 100644
index 0000000..cbca4c4
--- /dev/null
+++ b/test/test-config.102.in
@@ -0,0 +1,10 @@
+ELF
+
+&DIR&/test.log {
+ daily
+ size=0
+
+firstaction
+ /bin/sh -c "echo test123"
+ endscript
+}
diff --git a/test/test-config.103.in b/test/test-config.103.in
new file mode 100644
index 0000000..ef4d19c
--- /dev/null
+++ b/test/test-config.103.in
@@ -0,0 +1,12 @@
+random noise
+a b c d
+a::x
+
+&DIR&/test.log {
+ daily
+ size=0
+
+firstaction
+ /bin/sh -c "echo test123"
+ endscript
+}
--
2.38.1
From 2ad71221cd9e485e4d45df4f28b47072491df120 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Mon, 13 Dec 2021 21:47:16 +0100
Subject: [PATCH 6/6] Add more testcases for stricter configuration parsing
Upstream-commit: 9cbc22b91caff6cfbd1378737c62276bd9ffe3e7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
test/Makefile.am | 4 +++-
test/test-0102.sh | 5 +++++
test/test-0103.sh | 5 +++++
test/test-0104.sh | 19 +++++++++++++++++++
test/test-0105.sh | 25 +++++++++++++++++++++++++
test/test-config.104.in | 8 ++++++++
test/test-config.105.in | 8 ++++++++
7 files changed, 73 insertions(+), 1 deletion(-)
create mode 100755 test/test-0104.sh
create mode 100755 test/test-0105.sh
create mode 100644 test/test-config.104.in
create mode 100644 test/test-config.105.in
diff --git a/test/Makefile.am b/test/Makefile.am
index cd357e5..f1a0062 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -91,7 +91,9 @@ TEST_CASES = \
test-0100.sh \
test-0101.sh \
test-0102.sh \
- test-0103.sh
+ test-0103.sh \
+ test-0104.sh \
+ test-0105.sh
EXTRA_DIST = \
compress \
diff --git a/test/test-0102.sh b/test/test-0102.sh
index d2550a5..367bde9 100755
--- a/test/test-0102.sh
+++ b/test/test-0102.sh
@@ -14,3 +14,8 @@ if [ $? -eq 0 ]; then
echo "No error, but there should be one."
exit 3
fi
+
+checkoutput <<EOF
+test.log 0 zero
+test.log.1 0 first
+EOF
diff --git a/test/test-0103.sh b/test/test-0103.sh
index bccd8ed..32a3c19 100755
--- a/test/test-0103.sh
+++ b/test/test-0103.sh
@@ -14,3 +14,8 @@ if [ $? -eq 0 ]; then
echo "No error, but there should be one."
exit 3
fi
+
+checkoutput <<EOF
+test.log 0 zero
+test.log.1 0 first
+EOF
diff --git a/test/test-0104.sh b/test/test-0104.sh
new file mode 100755
index 0000000..e3c0009
--- /dev/null
+++ b/test/test-0104.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+. ./test-common.sh
+
+cleanup 104
+
+# ------------------------------- Test 104 ------------------------------------
+# test config with unknown (new?) keyword
+preptest test1.log 104 1
+preptest test2.log 104 1
+
+$RLR test-config.104 --force || exit 23
+
+checkoutput <<EOF
+test1.log 0
+test1.log.1 0 zero
+test2.log 0
+test2.log.1 0 zero
+EOF
diff --git a/test/test-0105.sh b/test/test-0105.sh
new file mode 100755
index 0000000..b51e9be
--- /dev/null
+++ b/test/test-0105.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. ./test-common.sh
+
+cleanup 105
+
+# ------------------------------- Test 105 ------------------------------------
+# test config with garbage keyword bails out
+preptest test1.log 105 1
+preptest test2.log 105 1
+
+$RLR test-config.105 --force
+
+if [ $? -eq 0 ]; then
+ echo "No error, but there should be one."
+ exit 3
+fi
+
+
+checkoutput <<EOF
+test1.log 0 zero
+test1.log.1 0 first
+test2.log 0
+test2.log.1 0 zero
+EOF
diff --git a/test/test-config.104.in b/test/test-config.104.in
new file mode 100644
index 0000000..988d902
--- /dev/null
+++ b/test/test-config.104.in
@@ -0,0 +1,8 @@
+&DIR&/test1.log {
+ newkeyword
+ rotate 1
+}
+
+&DIR&/test2.log {
+ rotate 1
+}
diff --git a/test/test-config.105.in b/test/test-config.105.in
new file mode 100644
index 0000000..bfab9b9
--- /dev/null
+++ b/test/test-config.105.in
@@ -0,0 +1,8 @@
+&DIR&/test1.log {
+ g@rbag€[]+#*
+ rotate 1
+}
+
+&DIR&/test2.log {
+ rotate 1
+}
--
2.38.1

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}

View File

@ -1,12 +1,27 @@
Summary: Rotates, compresses, removes and mails system log files
Name: logrotate
Version: 3.18.0
Release: 1%{?dist}
Release: 8%{?dist}
License: GPLv2+
Url: https://github.com/logrotate/logrotate
Source: https://github.com/logrotate/logrotate/releases/download/%{version}/logrotate-%{version}.tar.xz
URL: https://github.com/logrotate/logrotate
Source0: https://github.com/logrotate/logrotate/releases/download/%{version}/logrotate-%{version}.tar.xz
Source1: rwtab
# fix resource leaks reported by Coverity
Patch: 0001-logrotate-3.18.0-fix-resource-leaks.patch
# unify documentation of copy/copytruncate/renamecopy (#1934629)
Patch: 0002-logrotate-3.18.0-copytruncate-doc.patch
# make `renamecopy` and `copytruncate` override each other (#1934601)
Patch: 0003-logrotate-3.18.0-renamecopy-excl.patch
# fix potential DoS from unprivileged users via the state file (CVE-2022-1348)
Patch: 0004-logrotate-3.18.0-CVE-2022-1348.patch
# enforce stricter parsing of config files (#2148925)
Patch: 0005-logrotate-3.18.0-stricter-config-parser.patch
BuildRequires: acl
BuildRequires: automake
BuildRequires: gcc
@ -93,7 +108,6 @@ fi
%systemd_preun logrotate.{service,timer}
%files
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc ChangeLog.md
%{_sbindir}/logrotate
@ -104,10 +118,34 @@ fi
%dir %{_sysconfdir}/logrotate.d
%config(noreplace) %{_sysconfdir}/logrotate.d/{b,w}tmp
%dir %{_localstatedir}/lib/logrotate
%ghost %verify(not size md5 mtime) %attr(0644, root, root) %{_localstatedir}/lib/logrotate/logrotate.status
%ghost %verify(not size md5 mtime) %attr(0640, root, root) %{_localstatedir}/lib/logrotate/logrotate.status
%config(noreplace) %{_sysconfdir}/rwtab.d/logrotate
%changelog
* Tue Dec 20 2022 Kamil Dudka <kdudka@redhat.com> - 3.18.0-8
- enforce stricter parsing of config files (#2148925)
* Fri May 27 2022 Kamil Dudka <kdudka@redhat.com> - 3.18.0-7
- lockState: do not print `error:` when exit code is unaffected (#2090926)
* Wed May 25 2022 Kamil Dudka <kdudka@redhat.com> - 3.18.0-6
- fix potential DoS from unprivileged users via the state file (CVE-2022-1348)
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com>
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Tue May 04 2021 Kamil Dudka <kdudka@redhat.com> - 3.18.0-4
- make `renamecopy` and `copytruncate` override each other (#1934601)
- unify documentation of copy/copytruncate/renamecopy (#1934629)
- fix resource leaks reported by Coverity
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.18.0-3
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.18.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Jan 08 2021 Kamil Dudka <kdudka@redhat.com> - 3.18.0-1
- new upstream version 3.18.0