Compare commits

...

No commits in common. "c10s" and "c8" have entirely different histories.
c10s ... c8

17 changed files with 1512 additions and 534 deletions

View File

@ -1 +0,0 @@
1

4
.gitignore vendored
View File

@ -1,3 +1 @@
/logrotate-[0-9.]*/
/logrotate-[0-9.]*.tar.xz
/logrotate-[0-9.]*.tar.xz.asc
SOURCES/logrotate-3.14.0.tar.xz

1
.logrotate.metadata Normal file
View File

@ -0,0 +1 @@
10416a3aaea4fbf6c1a01858f2fb994e132c4127 SOURCES/logrotate-3.14.0.tar.xz

View File

@ -1,184 +0,0 @@
From 5f3274417c0cfa54841f2817eb9a3c5168846ec1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Sat, 3 Aug 2024 19:07:38 +0200
Subject: [PATCH] Avoid opening log file for getting SELinux context
Currently setSecCtxByName() uses open_logfile() to get a file descriptor
to the current log file to retrieve its security context.
open_logfile() performs additional checks, like whether the file is a
regular file, which alter the control flow between systems with SELinux
enabled and disabled. This can be observed in the reported issue #632.
Use lgetfilecon_raw() instead to have the same behavior for SELinux
enabled and disabled systems and delay the checks for invalid log files
to code executed in both cases.
Closes: #632
(cherry picked from commit e4a833015eb5590cf86a6a78895ff399174ade4f)
---
logrotate.c | 89 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 51 insertions(+), 38 deletions(-)
diff --git a/logrotate.c b/logrotate.c
index 1292b46..40b5295 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -360,27 +360,9 @@ static int movefd(int oldfd, int newfd)
return rc;
}
-static int setSecCtx(int fdSrc, const char *src, char **pPrevCtx)
-{
#ifdef WITH_SELINUX
- char *srcCtx;
- *pPrevCtx = NULL;
-
- if (!selinux_enabled)
- /* pretend success */
- return 0;
-
- /* read security context of fdSrc */
- if (fgetfilecon_raw(fdSrc, &srcCtx) < 0) {
- if (errno == ENOTSUP)
- /* pretend success */
- return 0;
-
- message(MESS_ERROR, "getting file context %s: %s\n", src,
- strerror(errno));
- return selinux_enforce;
- }
-
+static int setSecCtx(char *srcCtx, char **pPrevCtx)
+{
/* save default security context for restoreSecCtx() */
if (getfscreatecon_raw(pPrevCtx) < 0) {
message(MESS_ERROR, "getting default context: %s\n", strerror(errno));
@@ -400,37 +382,68 @@ static int setSecCtx(int fdSrc, const char *src, char **pPrevCtx)
message(MESS_DEBUG, "set default create context to %s\n", srcCtx);
freecon(srcCtx);
+
+ return 0;
+}
+#endif /* WITH_SELINUX */
+
+static int setSecCtxByFd(int fdSrc, const char *src, char **pPrevCtx)
+{
+#ifdef WITH_SELINUX
+ char *srcCtx;
+ *pPrevCtx = NULL;
+
+ if (!selinux_enabled)
+ /* pretend success */
+ return 0;
+
+ /* read security context of fdSrc */
+ if (fgetfilecon_raw(fdSrc, &srcCtx) < 0) {
+ if (errno == ENOTSUP)
+ /* pretend success */
+ return 0;
+
+ message(MESS_ERROR, "getting file context %s: %s\n", src,
+ strerror(errno));
+ return selinux_enforce;
+ }
+
+ return setSecCtx(srcCtx, pPrevCtx);
#else
(void) fdSrc;
(void) src;
(void) pPrevCtx;
-#endif
return 0;
+#endif /* WITH_SELINUX */
}
-static int setSecCtxByName(const char *src, const struct logInfo *log, char **pPrevCtx)
+static int setSecCtxByName(const char *src, char **pPrevCtx)
{
- int hasErrors = 0;
#ifdef WITH_SELINUX
- int fd;
+ char *srcCtx;
+ *pPrevCtx = NULL;
if (!selinux_enabled)
/* pretend success */
return 0;
- fd = open_logfile(src, log, 0);
- if (fd < 0) {
- message(MESS_ERROR, "error opening %s: %s\n", src, strerror(errno));
- return 1;
+ /* read security context of src */
+ if (lgetfilecon_raw(src, &srcCtx) < 0) {
+ if (errno == ENOTSUP)
+ /* pretend success */
+ return 0;
+
+ message(MESS_ERROR, "getting file context %s: %s\n", src,
+ strerror(errno));
+ return selinux_enforce;
}
- hasErrors = setSecCtx(fd, src, pPrevCtx);
- close(fd);
+
+ return setSecCtx(srcCtx, pPrevCtx);
#else
(void) src;
- (void) log;
(void) pPrevCtx;
-#endif
- return hasErrors;
+ return 0;
+#endif /* WITH_SELINUX */
}
static void restoreSecCtx(char **pPrevCtx)
@@ -853,7 +866,7 @@ static int compressLogFile(const char *name, const struct logInfo *log, const st
return 1;
}
- if (setSecCtx(inFile, name, &prevCtx) != 0) {
+ if (setSecCtxByFd(inFile, name, &prevCtx) != 0) {
/* error msg already printed */
close(inFile);
return 1;
@@ -1290,7 +1303,7 @@ static int copyTruncate(const char *currLog, const char *saveLog, const struct s
if (!skip_copy) {
char *prevCtx;
- if (setSecCtx(fdcurr, currLog, &prevCtx) != 0) {
+ if (setSecCtxByFd(fdcurr, currLog, &prevCtx) != 0) {
/* error msg already printed */
goto fail;
}
@@ -1888,7 +1901,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
message(MESS_DEBUG, "dateext suffix '%s'\n", dext_str);
message(MESS_DEBUG, "glob pattern '%s'\n", dext_pattern);
- if (setSecCtxByName(log->files[logNum], log, &prev_context) != 0) {
+ if (setSecCtxByName(log->files[logNum], &prev_context) != 0) {
/* error msg already printed */
return 1;
}
@@ -2169,7 +2182,7 @@ static int rotateSingleLog(const struct logInfo *log, unsigned logNum,
if (!hasErrors) {
if (!(log->flags & (LOG_FLAG_COPYTRUNCATE | LOG_FLAG_COPY))) {
- if (setSecCtxByName(log->files[logNum], log, &savedContext) != 0) {
+ if (setSecCtxByName(log->files[logNum], &savedContext) != 0) {
/* error msg already printed */
return 1;
}
@@ -2711,7 +2724,7 @@ static int writeState(const char *stateFilename)
/* get attributes, to assign them to the new state file */
- if (setSecCtx(fdcurr, stateFilename, &prevCtx) != 0) {
+ if (setSecCtxByFd(fdcurr, stateFilename, &prevCtx) != 0) {
/* error msg already printed */
free(tmpFilename);
close(fdcurr);
--
2.46.2

View File

@ -0,0 +1,34 @@
From b0d067cfba64956893fc095bb37f8c767f5a910e Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 6 Aug 2018 17:13:31 +0200
Subject: [PATCH] logrotate.8: document the --version option
The man page now covers all the options that are listed
by `logrotate --help`.
Bug: https://bugzilla.redhat.com/1611498
Upstream-commit: 4088ef987df2ec48cc3d968eb87ad27c840fa2d8
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
logrotate.8.in | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/logrotate.8.in b/logrotate.8.in
index 004229e..5ef09c5 100644
--- a/logrotate.8.in
+++ b/logrotate.8.in
@@ -87,6 +87,10 @@ Prints a short usage message.
\fB\-v\fR, \fB\-\-verbose\fR
Turns on verbose mode, for example to display messages during rotation.
+.TP
+\fB\-\-version\fR
+Display version information.
+
.SH CONFIGURATION FILE
\fBlogrotate\fR reads everything about the log files it should be handling
--
2.17.1

View File

@ -0,0 +1,630 @@
From a4ac21e9a8cfe8a73471a195308a742e07d7fe8d Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 1 Aug 2018 15:32:38 +0200
Subject: [PATCH 1/3] readConfigFile: assign and check 'key' separately
... to make the code readable. No changes in behavior intended
by this commit.
---
config.c | 312 +++++++++++++++++++++++++++----------------------------
1 file changed, 152 insertions(+), 160 deletions(-)
diff --git a/config.c b/config.c
index 84db36f..d2fba10 100644
--- a/config.c
+++ b/config.c
@@ -1037,7 +1037,8 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
}
if (isalpha((unsigned char)*start)) {
- if ((key = isolateWord(&start, &buf, length)) == NULL)
+ key = isolateWord(&start, &buf, length);
+ if (key == NULL)
continue;
if (!strcmp(key, "compress")) {
newlog->flags |= LOG_FLAG_COMPRESS;
@@ -1191,16 +1192,16 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
}
} else if (!strcmp(key, "shredcycles")) {
free(key);
- if ((key = isolateValue(configFile, lineNum, "shred cycles",
- &start, &buf, length)) != NULL) {
- newlog->shred_cycles = 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;
- }
+ key = isolateValue(configFile, lineNum, "shred cycles",
+ &start, &buf, length);
+ if (key == NULL)
+ continue;
+ newlog->shred_cycles = 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;
}
- else continue;
} else if (!strcmp(key, "hourly")) {
newlog->criterium = ROT_HOURLY;
} else if (!strcmp(key, "daily")) {
@@ -1232,59 +1233,53 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
newlog->criterium = ROT_YEARLY;
} else if (!strcmp(key, "rotate")) {
free(key);
- if ((key = isolateValue
- (configFile, lineNum, "rotate count", &start,
- &buf, length)) != NULL) {
-
- newlog->rotateCount = strtoul(key, &chptr, 0);
- if (*chptr || newlog->rotateCount < 0) {
- message(MESS_ERROR,
- "%s:%d bad rotation count '%s'\n",
- configFile, lineNum, key);
- RAISE_ERROR();
- }
+ key = isolateValue(configFile, lineNum, "rotate count", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+ newlog->rotateCount = strtoul(key, &chptr, 0);
+ if (*chptr || newlog->rotateCount < 0) {
+ message(MESS_ERROR,
+ "%s:%d bad rotation count '%s'\n",
+ configFile, lineNum, key);
+ RAISE_ERROR();
}
- else continue;
} else if (!strcmp(key, "start")) {
free(key);
- if ((key = isolateValue
- (configFile, lineNum, "start count", &start,
- &buf, length)) != NULL) {
-
- newlog->logStart = strtoul(key, &chptr, 0);
- if (*chptr || newlog->logStart < 0) {
- message(MESS_ERROR, "%s:%d bad start count '%s'\n",
- configFile, lineNum, key);
- RAISE_ERROR();
- }
+ key = isolateValue(configFile, lineNum, "start count", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+ newlog->logStart = strtoul(key, &chptr, 0);
+ if (*chptr || newlog->logStart < 0) {
+ message(MESS_ERROR, "%s:%d bad start count '%s'\n",
+ configFile, lineNum, key);
+ RAISE_ERROR();
}
- else continue;
} else if (!strcmp(key, "minage")) {
free(key);
- if ((key = isolateValue
- (configFile, lineNum, "minage count", &start,
- &buf, length)) != NULL) {
- newlog->rotateMinAge = strtoul(key, &chptr, 0);
- if (*chptr || newlog->rotateMinAge < 0) {
- message(MESS_ERROR, "%s:%d bad minimum age '%s'\n",
- configFile, lineNum, start);
- RAISE_ERROR();
- }
+ key = isolateValue(configFile, lineNum, "minage count", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+ newlog->rotateMinAge = strtoul(key, &chptr, 0);
+ if (*chptr || newlog->rotateMinAge < 0) {
+ message(MESS_ERROR, "%s:%d bad minimum age '%s'\n",
+ configFile, lineNum, start);
+ RAISE_ERROR();
}
- else continue;
} else if (!strcmp(key, "maxage")) {
free(key);
- if ((key = isolateValue
- (configFile, lineNum, "maxage count", &start,
- &buf, length)) != NULL) {
- newlog->rotateAge = strtoul(key, &chptr, 0);
- if (*chptr || newlog->rotateAge < 0) {
- message(MESS_ERROR, "%s:%d bad maximum age '%s'\n",
- configFile, lineNum, start);
- RAISE_ERROR();
- }
+ key = isolateValue(configFile, lineNum, "maxage count", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+ newlog->rotateAge = strtoul(key, &chptr, 0);
+ if (*chptr || newlog->rotateAge < 0) {
+ message(MESS_ERROR, "%s:%d bad maximum age '%s'\n",
+ configFile, lineNum, start);
+ RAISE_ERROR();
}
- else continue;
} else if (!strcmp(key, "errors")) {
message(MESS_DEBUG,
"%s: %d: the errors directive is deprecated and no longer used.\n",
@@ -1337,48 +1332,48 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
continue;
}
free(key);
- if ((key = isolateValue(configFile, lineNum, "tabooext", &start,
- &buf, length)) != NULL) {
- endtag = key;
- if (*endtag == '+') {
+ key = isolateValue(configFile, lineNum, "tabooext", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+ endtag = key;
+ if (*endtag == '+') {
+ endtag++;
+ while (isspace((unsigned char)*endtag) && *endtag)
endtag++;
- while (isspace((unsigned char)*endtag) && *endtag)
- endtag++;
- } else {
- free_2d_array(tabooPatterns, tabooCount);
- tabooCount = 0;
- /* realloc of NULL is safe by definition */
- tabooPatterns = NULL;
- }
-
- while (*endtag) {
- int bytes;
- char *pattern = NULL;
+ } else {
+ free_2d_array(tabooPatterns, tabooCount);
+ tabooCount = 0;
+ /* realloc of NULL is safe by definition */
+ tabooPatterns = NULL;
+ }
- chptr = endtag;
- while (!isspace((unsigned char)*chptr) && *chptr != ',' && *chptr)
- chptr++;
+ while (*endtag) {
+ int bytes;
+ char *pattern = NULL;
- /* accept only non-empty patterns to avoid exclusion of everything */
- if (endtag < chptr) {
- tabooPatterns = realloc(tabooPatterns, sizeof(*tabooPatterns) *
- (tabooCount + 1));
- bytes = asprintf(&pattern, "*%.*s", (int)(chptr - endtag), endtag);
+ chptr = endtag;
+ while (!isspace((unsigned char)*chptr) && *chptr != ',' && *chptr)
+ chptr++;
- /* should test for malloc() failure */
- assert(bytes != -1);
- tabooPatterns[tabooCount] = pattern;
- tabooCount++;
- }
+ /* accept only non-empty patterns to avoid exclusion of everything */
+ if (endtag < chptr) {
+ tabooPatterns = realloc(tabooPatterns, sizeof(*tabooPatterns) *
+ (tabooCount + 1));
+ bytes = asprintf(&pattern, "*%.*s", (int)(chptr - endtag), endtag);
- endtag = chptr;
- if (*endtag == ',')
- endtag++;
- while (*endtag && isspace((unsigned char)*endtag))
- endtag++;
+ /* should test for malloc() failure */
+ assert(bytes != -1);
+ tabooPatterns[tabooCount] = pattern;
+ tabooCount++;
}
+
+ endtag = chptr;
+ if (*endtag == ',')
+ endtag++;
+ while (*endtag && isspace((unsigned char)*endtag))
+ endtag++;
}
- else continue;
} else if (!strcmp(key, "taboopat")) {
if (newlog != defConfig) {
message(MESS_ERROR,
@@ -1389,68 +1384,68 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
continue;
}
free(key);
- if ((key = isolateValue(configFile, lineNum, "taboopat", &start,
- &buf, length)) != NULL) {
- endtag = key;
- if (*endtag == '+') {
+ key = isolateValue(configFile, lineNum, "taboopat", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+
+ endtag = key;
+ if (*endtag == '+') {
+ endtag++;
+ while (isspace((unsigned char)*endtag) && *endtag)
endtag++;
- while (isspace((unsigned char)*endtag) && *endtag)
- endtag++;
- } else {
- free_2d_array(tabooPatterns, tabooCount);
- tabooCount = 0;
- /* realloc of NULL is safe by definition */
- tabooPatterns = NULL;
- }
+ } else {
+ free_2d_array(tabooPatterns, tabooCount);
+ tabooCount = 0;
+ /* realloc of NULL is safe by definition */
+ tabooPatterns = NULL;
+ }
- while (*endtag) {
- int bytes;
- char *pattern = NULL;
+ while (*endtag) {
+ int bytes;
+ char *pattern = NULL;
- chptr = endtag;
- while (!isspace((unsigned char)*chptr) && *chptr != ',' && *chptr)
- chptr++;
+ chptr = endtag;
+ while (!isspace((unsigned char)*chptr) && *chptr != ',' && *chptr)
+ chptr++;
- tabooPatterns = realloc(tabooPatterns, sizeof(*tabooPatterns) *
- (tabooCount + 1));
- bytes = asprintf(&pattern, "%.*s", (int)(chptr - endtag), endtag);
+ tabooPatterns = realloc(tabooPatterns, sizeof(*tabooPatterns) *
+ (tabooCount + 1));
+ bytes = asprintf(&pattern, "%.*s", (int)(chptr - endtag), endtag);
- /* should test for malloc() failure */
- assert(bytes != -1);
- tabooPatterns[tabooCount] = pattern;
- tabooCount++;
+ /* should test for malloc() failure */
+ assert(bytes != -1);
+ tabooPatterns[tabooCount] = pattern;
+ tabooCount++;
- endtag = chptr;
- if (*endtag == ',')
- endtag++;
- while (*endtag && isspace((unsigned char)*endtag))
- endtag++;
- }
+ endtag = chptr;
+ if (*endtag == ',')
+ endtag++;
+ while (*endtag && isspace((unsigned char)*endtag))
+ endtag++;
}
- else continue;
} else if (!strcmp(key, "include")) {
free(key);
- if ((key = isolateValue(configFile, lineNum, "include", &start,
- &buf, length)) != NULL) {
-
- message(MESS_DEBUG, "including %s\n", key);
- if (recursion_depth >= MAX_NESTING) {
- message(MESS_ERROR, "%s:%d include nesting too deep\n",
- configFile, lineNum);
- logerror = 1;
- continue;
- }
+ key = isolateValue(configFile, lineNum, "include", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+ message(MESS_DEBUG, "including %s\n", key);
+ if (recursion_depth >= MAX_NESTING) {
+ message(MESS_ERROR, "%s:%d include nesting too deep\n",
+ configFile, lineNum);
+ logerror = 1;
+ continue;
+ }
- ++recursion_depth;
- rv = readConfigPath(key, newlog);
- --recursion_depth;
+ ++recursion_depth;
+ rv = readConfigPath(key, newlog);
+ --recursion_depth;
- if (rv) {
- logerror = 1;
- continue;
- }
+ if (rv) {
+ logerror = 1;
+ continue;
}
- else continue;
} else if (!strcmp(key, "olddir")) {
freeLogItem (oldDir);
@@ -1460,28 +1455,23 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
}
message(MESS_DEBUG, "olddir is now %s\n", newlog->oldDir);
} else if (!strcmp(key, "extension")) {
- if ((key = isolateValue
- (configFile, lineNum, "extension name", &start,
- &buf, length)) != NULL) {
- freeLogItem (extension);
- newlog->extension = key;
- key = NULL;
- }
- else continue;
-
- message(MESS_DEBUG, "extension is now %s\n",
- newlog->extension);
+ key = isolateValue(configFile, lineNum, "extension name", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+ freeLogItem (extension);
+ newlog->extension = key;
+ key = NULL;
+ message(MESS_DEBUG, "extension is now %s\n", newlog->extension);
} else if (!strcmp(key, "addextension")) {
- if ((key = isolateValue
- (configFile, lineNum, "addextension name", &start,
- &buf, length)) != NULL) {
- freeLogItem (addextension);
- newlog->addextension = key;
- key = NULL;
- }
- else continue;
-
+ key = isolateValue(configFile, lineNum, "addextension name", &start,
+ &buf, length);
+ if (key == NULL)
+ continue;
+ freeLogItem (addextension);
+ newlog->addextension = key;
+ key = NULL;
message(MESS_DEBUG, "addextension is now %s\n",
newlog->addextension);
@@ -1827,7 +1817,8 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
break;
case STATE_LOAD_SCRIPT:
case STATE_LOAD_SCRIPT | STATE_SKIP_CONFIG:
- if ((key = isolateWord(&start, &buf, length)) == NULL)
+ key = isolateWord(&start, &buf, length);
+ if (key == NULL)
continue;
if (strcmp(key, "endscript") == 0) {
@@ -1862,7 +1853,8 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
newlog = defConfig;
}
else {
- if ((key = isolateWord(&start, &buf, length)) == NULL)
+ key = isolateWord(&start, &buf, length);
+ if (key == NULL)
continue;
if (
(strcmp(key, "postrotate") == 0) ||
--
2.17.1
From a3a955494999bd4861f14b846c345cbc96715262 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 1 Aug 2018 15:09:40 +0200
Subject: [PATCH 2/3] readConfigFile: assign and free 'key' consistently
This commit fixes the following memory leaks (detected by Coverity):
Error: RESOURCE_LEAK:
config.c:1466: overwrite_var: Overwriting "key" in "key = isolateValue(configFile, lineNum, "extension name", &start, &buf, length)" leaks the storage that "key" points to.
Error: RESOURCE_LEAK:
config.c:1479: overwrite_var: Overwriting "key" in "key = isolateValue(configFile, lineNum, "addextension name", &start, &buf, length)" leaks the storage that "key" points to.
Error: RESOURCE_LEAK:
config.c:1043: alloc_fn: Storage is returned from allocation function "isolateWord".
config.c:219:2: alloc_fn: Storage is returned from allocation function "strndup".
config.c:219:2: assign: Assigning: "key" = "strndup(start, endtag - start)".
config.c:221:2: return_alloc: Returning allocated memory "key".
config.c:1043: var_assign: Assigning: "key" = storage returned from "isolateWord(&start, &buf, length)".
config.c:1928: leaked_storage: Variable "key" going out of scope leaks the storage it points to.
Error: RESOURCE_LEAK:
config.c:1153: alloc_fn: Storage is returned from allocation function "isolateValue".
config.c:204:2: alloc_fn: Storage is returned from allocation function "isolateLine".
config.c:178:2: alloc_fn: Storage is returned from allocation function "strndup".
config.c:178:2: assign: Assigning: "key" = "strndup(start, endtag - start + 1L)".
config.c:180:2: return_alloc: Returning allocated memory "key".
config.c:204:2: return_alloc_fn: Directly returning storage allocated by "isolateLine".
config.c:1153: var_assign: Assigning: "key" = storage returned from "isolateValue(configFile, lineNum, opt, &start, &buf, length)".
config.c:1928: leaked_storage: Variable "key" going out of scope leaks the storage it points to.
Error: RESOURCE_LEAK:
config.c:1219: alloc_fn: Storage is returned from allocation function "isolateLine".
config.c:178:2: alloc_fn: Storage is returned from allocation function "strndup".
config.c:178:2: assign: Assigning: "key" = "strndup(start, endtag - start + 1L)".
config.c:180:2: return_alloc: Returning allocated memory "key".
config.c:1219: var_assign: Assigning: "key" = storage returned from "isolateLine(&start, &buf, length)".
config.c:1928: leaked_storage: Variable "key" going out of scope leaks the storage it points to.
Closes #208
---
config.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/config.c b/config.c
index d2fba10..39c9bc7 100644
--- a/config.c
+++ b/config.c
@@ -1022,10 +1022,6 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
start = buf;
for (start = buf; start - buf < length; start++) {
- if (key) {
- free(key);
- key = NULL;
- }
switch (state) {
case STATE_DEFAULT:
if (isblank((unsigned char)*start))
@@ -1037,6 +1033,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
}
if (isalpha((unsigned char)*start)) {
+ free(key);
key = isolateWord(&start, &buf, length);
if (key == NULL)
continue;
@@ -1455,6 +1452,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
}
message(MESS_DEBUG, "olddir is now %s\n", newlog->oldDir);
} else if (!strcmp(key, "extension")) {
+ free(key);
key = isolateValue(configFile, lineNum, "extension name", &start,
&buf, length);
if (key == NULL)
@@ -1465,6 +1463,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
message(MESS_DEBUG, "extension is now %s\n", newlog->extension);
} else if (!strcmp(key, "addextension")) {
+ free(key);
key = isolateValue(configFile, lineNum, "addextension name", &start,
&buf, length);
if (key == NULL)
@@ -1557,8 +1556,6 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
if (*start != '\n')
state = STATE_SKIP_LINE;
}
- free(key);
- key = NULL;
} else if (*start == '/' || *start == '"' || *start == '\''
#ifdef GLOB_TILDE
|| *start == '~'
@@ -1817,6 +1814,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
break;
case STATE_LOAD_SCRIPT:
case STATE_LOAD_SCRIPT | STATE_SKIP_CONFIG:
+ free(key);
key = isolateWord(&start, &buf, length);
if (key == NULL)
continue;
@@ -1853,6 +1851,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
newlog = defConfig;
}
else {
+ free(key);
key = isolateWord(&start, &buf, length);
if (key == NULL)
continue;
@@ -1884,8 +1883,6 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
state = STATE_SKIP_LINE | STATE_SKIP_CONFIG;
}
}
- free(key);
- key = NULL;
}
break;
default:
@@ -1893,10 +1890,6 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
"%s: %d: readConfigFile() unknown state\n",
configFile, lineNum);
}
- if (key) {
- free(key);
- key = NULL;
- }
if (*start == '\n') {
lineNum++;
}
@@ -1910,6 +1903,8 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
goto error;
}
+ free(key);
+
munmap(buf, (size_t) length);
close(fd);
return logerror;
--
2.17.1
From 771af94fd6c6299a7cb3d20c8b247591775653d3 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 1 Aug 2018 16:06:27 +0200
Subject: [PATCH 3/3] simplify code of prerotateSingleLog()
... to eliminate a use-after-free false positive reported by Coverity:
Error: USE_AFTER_FREE:
logrotate.c:1800: freed_arg: "free" frees "oldName".
logrotate.c:1779: use_after_free: Using freed pointer "oldName".
Closes #209
---
logrotate.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/logrotate.c b/logrotate.c
index 02d45e9..95fd70b 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -1353,7 +1353,7 @@ static int prerotateSingleLog(struct logInfo *log, int logNum,
struct logState *state, struct logNames *rotNames)
{
struct tm now = *localtime(&nowSecs);
- char *oldName, *newName = NULL;
+ char *oldName = NULL;
const char *compext = "";
const char *fileext = "";
int hasErrors = 0;
@@ -1670,6 +1670,7 @@ static int prerotateSingleLog(struct logInfo *log, int logNum,
free(glob_pattern);
} else {
int i;
+ char *newName = NULL;
if (log->rotateAge) {
struct stat fst_buf;
for (i = 1; i <= rotateCount + 1; i++) {
@@ -1697,7 +1698,6 @@ static int prerotateSingleLog(struct logInfo *log, int logNum,
compext) < 0) {
message(MESS_FATAL, "could not allocate disposeName memory\n");
}
- newName = strdup(oldName);
rotNames->disposeName = strdup(oldName);
@@ -1711,6 +1711,8 @@ static int prerotateSingleLog(struct logInfo *log, int logNum,
if (asprintf(&oldName, "%s/%s.%d%s%s", rotNames->dirName,
rotNames->baseName, i, fileext, compext) < 0) {
message(MESS_FATAL, "could not allocate oldName memory\n");
+ oldName = NULL;
+ break;
}
message(MESS_DEBUG,
@@ -1727,11 +1729,9 @@ static int prerotateSingleLog(struct logInfo *log, int logNum,
hasErrors = 1;
}
}
- if (hasErrors || i - 1 < 0)
- free(oldName);
-
}
free(newName);
+ free(oldName);
} /* !LOG_FLAG_DATEEXT */
if (log->flags & LOG_FLAG_DATEEXT) {
--
2.17.1

View File

@ -0,0 +1,89 @@
From b98dd1933b1ebf5c86041bf135af421fe1ce4fc9 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 28 Jun 2019 18:22:39 +0200
Subject: [PATCH] globerr: do not abort globbing on broken symlink
Fixes #251
Upstream-commit: 4297f01103915f4ee356d37bdb35e8c41bbbdb28
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 16 +++++++++++++---
test/Makefile.am | 1 +
test/test-0084.sh | 14 ++++++++++++++
test/test-config.84.in | 3 +++
4 files changed, 31 insertions(+), 3 deletions(-)
create mode 100755 test/test-0084.sh
create mode 100644 test/test-config.84.in
diff --git a/config.c b/config.c
index e4807c9..1805a16 100644
--- a/config.c
+++ b/config.c
@@ -834,9 +834,19 @@ static int globerr(const char *pathname, int theerr)
{
(void) pathname;
- /* A missing directory is not an error, so return 0 */
- if (theerr == ENOTDIR)
- return 0;
+ /* prevent glob() from being aborted in certain cases */
+ switch (theerr) {
+ case ENOTDIR:
+ /* non-directory where directory was expected by the glob */
+ return 0;
+
+ case ENOENT:
+ /* most likely symlink with non-existent target */
+ return 0;
+
+ default:
+ break;
+ }
glob_errno = theerr;
diff --git a/test/Makefile.am b/test/Makefile.am
index 5e838d1..35ba2b9 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -76,6 +76,7 @@ TEST_CASES = \
test-0075.sh \
test-0076.sh \
test-0077.sh \
+ test-0084.sh \
test-0100.sh \
test-0101.sh
diff --git a/test/test-0084.sh b/test/test-0084.sh
new file mode 100755
index 0000000..1389331
--- /dev/null
+++ b/test/test-0084.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+. ./test-common.sh
+
+cleanup 84
+
+# ------------------------------- Test 84 ------------------------------------
+preptest test.log 84 1
+
+mkdir -p log/dir
+ln -s XXX log/sym
+touch log/dir/file
+
+$RLR test-config.84 -v --force
diff --git a/test/test-config.84.in b/test/test-config.84.in
new file mode 100644
index 0000000..1a79bfe
--- /dev/null
+++ b/test/test-config.84.in
@@ -0,0 +1,3 @@
+&DIR&/log/*/* {
+ rotate 1
+}
--
2.21.3

View File

@ -0,0 +1,37 @@
From 893ab396daffebfe5bb97e9fcf0adbd7fda1b828 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 18 Jan 2019 16:10:56 +0100
Subject: [PATCH] logrotate.8: encourage admins to use the `su` directive
... to rotate files in directories that are directly or indirectly in
control of non-privileged users. Originally reported in the following
pull request:
https://github.com/logrotate/logrotate/pull/235
Closes #236
Upstream-commit: 3e170c0609a18e0bb5fd7f647cb877221d576456
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
logrotate.8.in | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/logrotate.8.in b/logrotate.8.in
index 56c4a32..ee26821 100644
--- a/logrotate.8.in
+++ b/logrotate.8.in
@@ -575,7 +575,9 @@ user/group (usually root). \fIuser\fR specifies the user name used for
rotation and \fIgroup\fR specifies the group used for rotation. If the
user/group you specify here does not have sufficient privilege to make
files with the ownership you've specified in a \fIcreate\fR instruction,
-it will cause an error.
+it will cause an error. If logrotate runs with root privileges, it is
+recommended to use the \fBsu\fR directive to rotate files in directories
+that are directly or indirectly in control of non-privileged users.
.TP
\fBtabooext\fR [+] \fIlist\fR
--
2.21.3

View File

@ -0,0 +1,33 @@
From a045dbad7370109a8ddf16a24090b8357a9b73fd Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 26 Aug 2019 15:13:16 +0200
Subject: [PATCH] examples/btmp: use create mode 0660
... to make the created file accessible by the utmp group.
Bug: https://bugzilla.redhat.com/1745330
Suggested-by: Steve Grubb
Closes #257
Upstream-commit: b1bddec3e73bff4282bcd4845f27ab7b375469da
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
examples/btmp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/btmp b/examples/btmp
index 393ead5..0aa1ae1 100644
--- a/examples/btmp
+++ b/examples/btmp
@@ -2,6 +2,6 @@
/var/log/btmp {
missingok
monthly
- create 0600 root utmp
+ create 0660 root utmp
rotate 1
}
--
2.37.3

View File

@ -0,0 +1,635 @@
From 92067ac8e75b3d1f431982d8156da5ffb18df249 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 7 Jun 2018 14:49:07 +0200
Subject: [PATCH 1/7] return non-zero exit status if a config file contains an
error
... which causes the config file to be skipped
Closes #199
Closes #204
Upstream-commit: e547b942ebdf58026f0b28a74b3d02a7674e38dc
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
config.c | 1 +
test/Makefile.am | 1 +
test/test-0083.sh | 14 ++++++++++++++
test/test-config.83.in | 3 +++
4 files changed, 19 insertions(+)
create mode 100755 test/test-0083.sh
create mode 100644 test/test-config.83.in
diff --git a/config.c b/config.c
index 1805a16..ec4c5fb 100644
--- a/config.c
+++ b/config.c
@@ -1820,6 +1820,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
message(MESS_ERROR, "found error in %s, skipping\n",
newlog->pattern ? newlog->pattern : "log config");
+ logerror = 1;
state = STATE_SKIP_CONFIG;
break;
case STATE_LOAD_SCRIPT:
diff --git a/test/Makefile.am b/test/Makefile.am
index 35ba2b9..cfe09c4 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -76,6 +76,7 @@ TEST_CASES = \
test-0075.sh \
test-0076.sh \
test-0077.sh \
+ test-0083.sh \
test-0084.sh \
test-0100.sh \
test-0101.sh
diff --git a/test/test-0083.sh b/test/test-0083.sh
new file mode 100755
index 0000000..f6cf26c
--- /dev/null
+++ b/test/test-0083.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+. ./test-common.sh
+
+cleanup 83
+
+# ------------------------------- Test 83 ------------------------------------
+preptest test.log 83 1
+
+if $RLR test-config.83 -v --force; then
+ exit 1
+else
+ exit 0
+fi
diff --git a/test/test-config.83.in b/test/test-config.83.in
new file mode 100644
index 0000000..f8a36f8
--- /dev/null
+++ b/test/test-config.83.in
@@ -0,0 +1,3 @@
+&DIR&/test.log {
+ rotate 1 # invalid comment
+}
--
2.38.1
From d6b10a7dd5946a6bce400ab87fd1adbde832c046 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 2/7] 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 ec4c5fb..cfbb3d1 100644
--- a/config.c
+++ b/config.c
@@ -1047,6 +1047,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 0881276c62ac95d803371f3f5c6cf11ffb552211 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 3/7] 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 cfbb3d1..5a774ac 100644
--- a/config.c
+++ b/config.c
@@ -1045,8 +1045,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 539b863fbd211b61614493447040cb340b53f0c0 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 4/7] 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 5a774ac..ae7bf4b 100644
--- a/config.c
+++ b/config.c
@@ -1110,8 +1110,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,
@@ -1209,13 +1212,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 = 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")) {
newlog->criterium = ROT_HOURLY;
@@ -1250,8 +1254,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 = strtoul(key, &chptr, 0);
if (*chptr || newlog->rotateCount < 0) {
message(MESS_ERROR,
@@ -1263,8 +1268,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 = strtoul(key, &chptr, 0);
if (*chptr || newlog->logStart < 0) {
message(MESS_ERROR, "%s:%d bad start count '%s'\n",
@@ -1275,8 +1281,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 = strtoul(key, &chptr, 0);
if (*chptr || newlog->rotateMinAge < 0) {
message(MESS_ERROR, "%s:%d bad minimum age '%s'\n",
@@ -1287,8 +1294,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 = strtoul(key, &chptr, 0);
if (*chptr || newlog->rotateAge < 0) {
message(MESS_ERROR, "%s:%d bad maximum age '%s'\n",
@@ -1443,8 +1451,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();
+ }
message(MESS_DEBUG, "including %s\n", key);
if (recursion_depth >= MAX_NESTING) {
message(MESS_ERROR, "%s:%d include nesting too deep\n",
@@ -1473,8 +1482,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;
@@ -1484,8 +1494,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 bf20b227b45b232eec9b659839d7ae20604f5de3 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 5/7] 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 ae7bf4b..569104d 100644
--- a/config.c
+++ b/config.c
@@ -1050,7 +1050,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 07faa84dc2e31002b0212c0b57669595ef9be99d Mon Sep 17 00:00:00 2001
From: Felix Wilhelm <fwilhelm@google.com>
Date: Thu, 21 Oct 2021 09:47:57 +0000
Subject: [PATCH 6/7] 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 569104d..36765be 100644
--- a/config.c
+++ b/config.c
@@ -1048,12 +1048,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;
@@ -1805,7 +1806,7 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
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 cfe09c4..255c1f7 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -79,7 +79,9 @@ TEST_CASES = \
test-0083.sh \
test-0084.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 88870bf2d84f65d0f2633bb32b7dc696be51d202 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 7/7] 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 255c1f7..a489a76 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -81,7 +81,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

View File

@ -1,47 +1,51 @@
Summary: Rotates, compresses, removes and mails system log files
Name: logrotate
Version: 3.22.0
Release: 4%{?dist}
License: GPL-2.0-or-later
URL: https://github.com/logrotate/logrotate
Source0: https://github.com/logrotate/logrotate/releases/download/%{version}/logrotate-%{version}.tar.xz
Source1: https://github.com/logrotate/logrotate/releases/download/%{version}/logrotate-%{version}.tar.xz.asc
# gpg --keyserver pgp.mit.edu --recv-key 8ECCDF12100AD84DA2EE7EBFC78CE737A3C3E28E
# gpg --output cgzones.pgp --armor --export cgzones@googlemail.com
Source2: cgzones.pgp
Source3: rwtab
# https://github.com/logrotate/logrotate/pull/633
Patch001: 001-Avoid-opening-log-file-for-getting-SELinux-context.patch
Version: 3.14.0
Release: 6%{?dist}
License: GPLv2+
Url: https://github.com/logrotate/logrotate
Source: https://github.com/logrotate/logrotate/releases/download/%{version}/logrotate-%{version}.tar.xz
Source1: rwtab
BuildRequires: acl
BuildRequires: automake
BuildRequires: gcc
BuildRequires: git
BuildRequires: gnupg2
BuildRequires: libacl-devel
BuildRequires: libselinux-devel
BuildRequires: make
BuildRequires: popt-devel
BuildRequires: systemd-rpm-macros
Requires: coreutils
Requires(post): systemd
Requires(preun): systemd
# document the --version option in the logrotate(8) man page (#1611498)
Patch1: 0001-logrotate-3.14.0-man-version.patch
# fix programming mistakes detected by Coverity Analysis
Patch2: 0002-logrotate-3.14.0-coverity.patch
# do not abort globbing on broken symlink (#1723265)
Patch3: 0003-logrotate-3.14.0-broken-symlink.patch
# logrotate.8: encourage admins to use the `su` directive (#1759770)
Patch4: 0004-logrotate-3.14.0-man-page-su.patch
# create /var/log/btmp with mode 0660 (#2061561)
Patch5: 0005-logrotate-3.14.0-btmp-create-mode.patch
# enforce stricter parsing of config files (#2148925)
Patch6: 0006-logrotate-3.14.0-stricter-config-parser.patch
%description
The logrotate utility is designed to simplify the administration of
log files on a system which generates a lot of log files. Logrotate
allows for the automatic rotation compression, removal and mailing of
log files. Logrotate can be set to handle a log file daily, weekly,
monthly or when the log file gets to a certain size.
monthly or when the log file gets to a certain size. Normally,
logrotate runs as a daily cron job.
Install the logrotate package if you need a utility to deal with the
log files on your system.
%prep
%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
%autosetup -S git
cat >> .gitignore << EOF
@ -52,6 +56,14 @@ EOF
git add .gitignore
git commit -m "update .gitignore"
%if 0%{?fedora} == 0 && 0%{?rhel} < 7
sed -e 's/^AM_EXTRA_RECURSIVE_TARGETS/dnl AM_EXTRA_RECURSIVE_TARGETS/' \
-e 's/ serial-tests//' \
-i configure.ac
git add configure.ac
git commit -m "configure.ac: compatibility fixes for RHEL-6"
%endif
autoreconf -fiv
git add --all
git commit -m "force autoreconf" --allow-empty
@ -60,25 +72,25 @@ git commit -m "force autoreconf" --allow-empty
mkdir build && cd build
%global _configure ../configure
%configure --with-state-file-path=%{_localstatedir}/lib/logrotate/logrotate.status
%make_build
make %{?_smp_mflags} V=1
%check
%make_build -C build -s check
make %{?_smp_mflags} -C build check
%install
%make_install -C build
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d
mkdir -p $RPM_BUILD_ROOT%{_unitdir}
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/cron.daily
mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/logrotate
install -p -m 644 examples/logrotate.conf $RPM_BUILD_ROOT%{_sysconfdir}/
install -p -m 644 examples/logrotate-default $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.conf
install -p -m 644 examples/{b,w}tmp $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/
install -p -m 644 examples/logrotate.{service,timer} $RPM_BUILD_ROOT%{_unitdir}/
install -p -m 755 examples/logrotate.cron $RPM_BUILD_ROOT%{_sysconfdir}/cron.daily/logrotate
# Make sure logrotate is able to run on read-only root
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/rwtab.d
install -m644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/rwtab.d/logrotate
install -m644 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/rwtab.d/logrotate
%pre
# If /var/lib/logrotate/logrotate.status does not exist, create it and copy
@ -90,144 +102,37 @@ if [ ! -d %{_localstatedir}/lib/logrotate/ -a -f %{_localstatedir}/lib/logrotate
cp -a %{_localstatedir}/lib/logrotate.status %{_localstatedir}/lib/logrotate
fi
%post
%systemd_post logrotate.{service,timer}
# If there is any cron daemon configured, enable the systemd timer to avoid
# breaking the configuration silently when upgrading from 3.14.0-4 or
# earlier versions
%triggerin -- logrotate < 3.14.0-5
[ -e %{_sysconfdir}/crontab -o -e %{_sysconfdir}/anacrontab -o -e %{_sysconfdir}/fcrontab ] \
&& %{_bindir}/systemctl enable --now logrotate.timer &>/dev/null || :
%preun
%systemd_preun logrotate.{service,timer}
%files
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc ChangeLog.md
%{_sbindir}/logrotate
%{_unitdir}/logrotate.{service,timer}
%{_mandir}/man8/logrotate.8*
%{_mandir}/man5/logrotate.conf.5*
%dir %{_sysconfdir}/cron.daily
%config(noreplace) %{_sysconfdir}/cron.daily/logrotate
%config(noreplace) %{_sysconfdir}/logrotate.conf
%dir %{_sysconfdir}/logrotate.d
%config(noreplace) %{_sysconfdir}/logrotate.d/{b,w}tmp
%dir %{_localstatedir}/lib/logrotate
%ghost %verify(not size md5 mtime) %attr(0640, root, root) %{_localstatedir}/lib/logrotate/logrotate.status
%ghost %verify(not size md5 mtime) %attr(0644, root, root) %{_localstatedir}/lib/logrotate/logrotate.status
%config(noreplace) %{_sysconfdir}/rwtab.d/logrotate
%changelog
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 3.22.0-4
- Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018
* Tue Dec 20 2022 Kamil Dudka <kdudka@redhat.com> - 3.14.0-6
- enforce stricter parsing of config files (#2148925)
* Tue Oct 01 2024 Jan Macku <jamacku@redhat.com> - 3.22.0-3
- Fix test_0112.sh fails on SELinux-enabled systems (RHEL-61155)
* Mon Nov 14 2022 Kamil Dudka <kdudka@redhat.com> - 3.14.0-5
- create /var/log/btmp with mode 0660 (#2061561)
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 3.22.0-2
- Bump release for June 2024 mass rebuild
* Wed May 06 2020 Kamil Dudka <kdudka@redhat.com> - 3.14.0-4
- logrotate.8: encourage admins to use the `su` directive (#1759770)
- do not abort globbing on broken symlink (#1723265)
* Mon Jun 10 2024 Jan Macku <jamacku@redhat.com> - 3.22.0-1
- new upstream version 3.22.0
- release signed with new key (cgzones.pgp)
* Thu Jan 25 2024 Fedora Release Engineering <releng@fedoraproject.org> - 3.21.0-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 3.21.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 3.21.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Wed Mar 22 2023 Lukáš Zaoral <lzaoral@redhat.com> - 3.21.0-3
- migrated to SPDX license
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 3.21.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Tue Dec 13 2022 Kamil Dudka <kdudka@redhat.com> - 3.21.0-1
- new upstream version 3.21.0
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 3.20.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Fri May 27 2022 Kamil Dudka <kdudka@redhat.com> - 3.20.1-2
- lockState: do not print `error:` when exit code is unaffected (#2090926)
* Wed May 25 2022 Kamil Dudka <kdudka@redhat.com> - 3.20.1-1
- new upstream version 3.20.1, which fixes the following security issue:
CVE-2022-1348 - potential DoS from unprivileged users via the state file
* Tue Mar 15 2022 Kamil Dudka <kdudka@redhat.com> - 3.19.0-3
- verify GPG signature of upstream tarball when building the package
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 3.19.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Fri Jan 07 2022 Kamil Dudka <kdudka@redhat.com> - 3.19.0-1
- new upstream version 3.19.0
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.18.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Fri May 21 2021 Kamil Dudka <kdudka@redhat.com> - 3.18.1-1
- new upstream version 3.18.1
* Tue May 04 2021 Kamil Dudka <kdudka@redhat.com> - 3.18.0-3
- make `renamecopy` and `copytruncate` override each other (#1934601)
- unify documentation of copy/copytruncate/renamecopy (#1934629)
- fix resource leaks reported by Coverity
* 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
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.17.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon Jul 13 2020 Tom Stellard <tstellar@redhat.com> - 3.17.0-2
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Fri Jul 10 2020 Kamil Dudka <kdudka@redhat.com> - 3.17.0-1
- new upstream version 3.17.0
* Fri Feb 28 2020 Kamil Dudka <kdudka@redhat.com> - 3.16.0-1
- new upstream version 3.16.0
* Thu Jan 30 2020 Kamil Dudka <kdudka@redhat.com> - 3.15.1-3
- make the code compile with gcc-10
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.15.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Fri Aug 30 2019 Kamil Dudka <kdudka@redhat.com> - 3.15.1-1
- new upstream version 3.15.1
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.15.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.15.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Tue Dec 04 2018 Kamil Dudka <kdudka@redhat.com> - 3.15.0-1
- new upstream version 3.15.0
* Wed Nov 21 2018 Alejandro Domínguez Muñoz <adomu@net-c.com> - 3.14.0-5
- add make as a build dependency
- replace cron job with a systemd timer unit (#1502085, #1655153)
* Fri Aug 10 2018 Kamil Dudka <kdudka@redhat.com> - 3.14.0-4
* Fri Aug 10 2018 Kamil Dudka <kdudka@redhat.com> - 3.14.0-3
- fix programming mistakes detected by Coverity Analysis
- document the --version option in the logrotate(8) man page (#1611498)
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.14.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Wed Jul 11 2018 Kamil Dudka <kdudka@redhat.com> - 3.14.0-2
- fix license tag to match the source code license

View File

@ -1,179 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: SKS 1.1.6
Comment: Hostname: pgp.mit.edu
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
=JFa+
-----END PGP PUBLIC KEY BLOCK-----

1
ci.fmf
View File

@ -1 +0,0 @@
resultsdb-testcase: separate

View File

@ -1,6 +0,0 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-internal.functional}

View File

@ -1,11 +0,0 @@
summary: Internal gating tests plan
discover:
- name: Internal gating tests
how: fmf
url: https://pkgs.devel.redhat.com/git/tests/logrotate
filter: 'tier: 1 | tag: CI-Tier-1'
execute:
how: tmt
adjust:
enabled: false
when: distro == centos-stream or distro == fedora

View File

@ -1,2 +0,0 @@
SHA512 (logrotate-3.22.0.tar.xz) = 16fd95b4daef779212008c4a968c7a7130be8d550f58531d24fc04599cb9adff6323a745725b3b14d7312ad36cb6646fe33a3defdb5b70cda2cec9646aab066a
SHA512 (logrotate-3.22.0.tar.xz.asc) = 93664c45bfe9ea20aedc54fe216825db38eaf81d43b238cd7bf8ea3e03f7d282f53743fb6d914766a9ed0cb5b33376435d253db5b9ec7039facd66e25d349dd4