File editorconfig-core-c-CVE-2024-53849.patch of Package editorconfig-core-c.36635
From a8dd5312e08abeab95ff5656d32ed3cb85fba70b Mon Sep 17 00:00:00 2001
From: Christopher Wellons <wellons@nullprogram.com>
Date: Sat, 17 Feb 2024 15:32:25 -0500
Subject: [PATCH 1/2] Fix a few more stack buffer overflows
Several overflows may occur in switch case '[' when the input pattern
contains many escaped characters. The added backslashes leave too little
space in the output pattern when processing nested brackets such that
the remaining input length exceeds the output capacity. Therefore all
these concatenations must also be checked.
The ADD_CHAR was missed in 41281ea (#87). The switch can exit exactly at
capacity, leaving no room for the finishing '$', causing an overflow.
These overflows were discovered through fuzz testing with afl.
---
src/lib/ec_glob.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/lib/ec_glob.c b/src/lib/ec_glob.c
index ea62aee..e62af1f 100644
--- a/src/lib/ec_glob.c
+++ b/src/lib/ec_glob.c
@@ -192,10 +192,14 @@ int ec_glob(const char *pattern, const char *string)
if (!right_bracket) /* The right bracket may not exist */
right_bracket = c + strlen(c);
- strcat(p_pcre, "\\");
+ STRING_CAT(p_pcre, "\\", pcre_str_end);
+ /* Boundary check for strncat below. */
+ if (pcre_str_end - p_pcre <= right_bracket - c) {
+ return -1;
+ }
strncat(p_pcre, c, right_bracket - c);
if (*right_bracket) /* right_bracket is a bracket */
- strcat(p_pcre, "\\]");
+ STRING_CAT(p_pcre, "\\]", pcre_str_end);
p_pcre += strlen(p_pcre);
c = right_bracket;
if (!*c)
@@ -339,7 +343,7 @@ int ec_glob(const char *pattern, const char *string)
}
}
- *(p_pcre ++) = '$';
+ ADD_CHAR(p_pcre, '$', pcre_str_end);
pcre2_code_free(re); /* ^\\d+\\.\\.\\d+$ */
From 3f936674395da9d1182617e2ad578c7508d5b4a9 Mon Sep 17 00:00:00 2001
From: Christopher Wellons <wellons@nullprogram.com>
Date: Sat, 17 Feb 2024 16:01:57 -0500
Subject: [PATCH 2/2] Fix pointer overflow in STRING_CAT
The end pointer is positioned one past the end of the destination, and
it is undefined behavior to compute an address beyond the end pointer,
including for comparisons, even temporarily. The UB occurs exactly when
buffer overflow would have occurred, so the buffer overflow check could
be optimized away by compilers. Even if this wasn't the case, the check
could produce a false negative if the computed address overflowed the
address space, which is, after all, why the C standard doesn't define
behavior in the first place.
The fix is simple: Check using sizes, not addresses. The explicit cast
suppresses warnings about signed-unsigned comparisons, and the assertion
checks the cast.
---
src/lib/ec_glob.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/lib/ec_glob.c b/src/lib/ec_glob.c
index e62af1f..c2b83cf 100644
--- a/src/lib/ec_glob.c
+++ b/src/lib/ec_glob.c
@@ -27,6 +27,7 @@
#include "global.h"
+#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <pcre2.h>
@@ -51,7 +52,8 @@ static const UT_icd ut_int_pair_icd = {sizeof(int_pair),NULL,NULL,NULL};
/* concatenate the string then move the pointer to the end */
#define STRING_CAT(p, string, end) do { \
size_t string_len = strlen(string); \
- if (p + string_len >= end) \
+ assert(end > p); \
+ if (string_len >= (size_t)(end - p)) \
return -1; \
strcat(p, string); \
p += string_len; \