logrotate/SOURCES/0015-logrotate-3.18.0-Avoid-date-format-overflow-issues.patch

111 lines
4.4 KiB
Diff

From 153ab5af4e48e4cf29a26eec8d0a3fe478c1cc43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Wed, 12 Jul 2023 21:47:59 +0200
Subject: [PATCH 5/6] Avoid date format overflow issues
Prevent overflows on the date format string array.
Exit early on date format string conversion failures to avoid operating
on wrong files or missing some out.
Reported-by: blu3sh0rk
(cherry picked from commit 1b45002788b2838fdff32da34a2370f519f7eb51)
---
logrotate.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/logrotate.c b/logrotate.c
index 1bb95b2..b0f8332 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -1542,6 +1542,8 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
char dext_str[DATEEXT_LEN];
char dformat[PATTERN_LEN] = "";
char dext_pattern[PATTERN_LEN];
+ const char *final_dformat;
+ size_t ret;
if (!state->doRotate)
return 0;
@@ -1661,19 +1663,19 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
/* Construct the glob pattern corresponding to the date format */
dext_str[0] = '\0';
if (log->dateformat) {
- char *dext;
+ const char *dext = log->dateformat;
size_t i = 0, j = 0;
+
memset(dext_pattern, 0, sizeof(dext_pattern));
- dext = log->dateformat;
while (*dext == ' ')
dext++;
- while ((*dext != '\0') && (!hasErrors)) {
+ while (*dext != '\0') {
/* Will there be a space for a char and '\0'? */
- if (j >= (sizeof(dext_pattern) - 1)) {
+ if (j >= (sizeof(dext_pattern) - 1) ||
+ i >= (sizeof(dformat) - 1)) {
message(MESS_ERROR, "Date format %s is too long\n",
log->dateformat);
- hasErrors = 1;
- break;
+ return 1;
}
if (*dext == '%') {
switch (*(dext + 1)) {
@@ -1694,8 +1696,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
if (j >= (sizeof(dext_pattern) - 1)) {
message(MESS_ERROR, "Date format %s is too long\n",
log->dateformat);
- hasErrors = 1;
- break;
+ return 1;
}
dformat[i++] = *(dext++);
dformat[i] = *dext;
@@ -1709,8 +1710,7 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
if (j >= (sizeof(dext_pattern) - 1)) {
message(MESS_ERROR, "Date format %s is too long\n",
log->dateformat);
- hasErrors = 1;
- break;
+ return 1;
}
dformat[i++] = *(dext++);
dformat[i] = *dext;
@@ -1730,21 +1730,28 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
}
dformat[i] = '\0';
message(MESS_DEBUG, "Converted '%s' -> '%s'\n", log->dateformat, dformat);
- strftime(dext_str, sizeof(dext_str), dformat, &now);
+ final_dformat = dformat;
} else {
if (log->criterium == ROT_HOURLY) {
/* hourly adds another two digits */
- strftime(dext_str, sizeof(dext_str), "-%Y%m%d%H", &now);
+ final_dformat = "-%Y%m%d%H";
strncpy(dext_pattern, "-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]",
sizeof(dext_pattern));
} else {
/* The default dateformat and glob pattern */
- strftime(dext_str, sizeof(dext_str), "-%Y%m%d", &now);
+ final_dformat = "-%Y%m%d";
strncpy(dext_pattern, "-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]",
sizeof(dext_pattern));
}
dext_pattern[PATTERN_LEN - 1] = '\0';
}
+
+ ret = strftime(dext_str, sizeof(dext_str), final_dformat, &now);
+ if (ret == 0) {
+ message(MESS_ERROR, "failed to apply date format '%s'\n", final_dformat);
+ return 1;
+ }
+
message(MESS_DEBUG, "dateext suffix '%s'\n", dext_str);
message(MESS_DEBUG, "glob pattern '%s'\n", dext_pattern);
--
2.49.0