Skip to content

Commit f9baae0

Browse files
committed
libsmartcols: reject large interval repetition bounds in filter regex
ERE interval expressions like {,32232} cause glibc regcomp() to allocate gigabytes for the NFA, triggering OOM even on tiny inputs. The existing consecutive-quantifier and nested-group checks do not catch this pattern. Scan numbers inside {...} and reject any bound exceeding SCOLS_FILTER_MAX_REPCNT (1024). Document the new limit in scols-filter(5). Addresses: https://oss-fuzz.com/testcase-detail/6017673394454528 Signed-off-by: Karel Zak <kzak@redhat.com>
1 parent 6123c15 commit f9baae0

3 files changed

Lines changed: 26 additions & 4 deletions

File tree

libsmartcols/scols-filter.5.adoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,9 @@ The filter expression string is limited to 1024 bytes. The number of nodes
115115
(parameters and operators) in a single expression is limited to 256.
116116

117117
Regular expression patterns used with the `=~` and `!~` operators are limited to
118-
256 bytes. Patterns with consecutive quantifiers (e.g., `a++`, `a**`) or nested
119-
group repetitions (e.g., `(a+)+`) are rejected because they can cause excessive
118+
256 bytes. Patterns with consecutive quantifiers (e.g., `a++`, `a**`), nested
119+
group repetitions (e.g., `(a+)+`), or interval repetitions with bounds larger
120+
than 1024 (e.g., `{,9999}`) are rejected because they can cause excessive
120121
memory consumption in the POSIX regex compiler.
121122

122123
== AUTHORS

libsmartcols/src/filter-param.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ struct filter_node *filter_new_param(
131131
return (struct filter_node *) n;
132132
}
133133

134-
/* Consecutive ERE quantifiers (a++, a**) and nested group repetitions
135-
* ((a+)+, (a*)*) cause glibc regcomp() to allocate gigabytes for the NFA. */
134+
/* Consecutive ERE quantifiers (a++, a**), nested group repetitions
135+
* ((a+)+, (a*)*), and large interval bounds ({,N} where N is huge)
136+
* cause glibc regcomp() to allocate gigabytes for the NFA. */
136137
static int is_unsafe_regex(const char *pattern)
137138
{
138139
size_t i, len = strlen(pattern);
@@ -153,6 +154,25 @@ static int is_unsafe_regex(const char *pattern)
153154
return 1;
154155
}
155156
}
157+
158+
/* reject large ERE interval bounds like {,32232} or {1,9999} */
159+
if (pattern[i] == '{') {
160+
const char *p = &pattern[i + 1];
161+
162+
while (*p && *p != '}') {
163+
if (*p >= '0' && *p <= '9') {
164+
unsigned long val;
165+
char *end = NULL;
166+
167+
errno = 0;
168+
val = strtoul(p, &end, 10);
169+
if (errno || val > SCOLS_FILTER_MAX_REPCNT)
170+
return 1;
171+
p = end;
172+
} else
173+
p++;
174+
}
175+
}
156176
}
157177
return 0;
158178
}

libsmartcols/src/smartcolsP.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ struct libscols_filter {
567567
#define SCOLS_FILTER_MAX_EXPRSZ 1024
568568
#define SCOLS_FILTER_MAX_NODES 256
569569
#define SCOLS_FILTER_MAX_REGSZ 256
570+
#define SCOLS_FILTER_MAX_REPCNT 1024
570571

571572
struct filter_node *__filter_new_node(enum filter_ntype type, size_t sz);
572573
void filter_ref_node(struct filter_node *n);

0 commit comments

Comments
 (0)