authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-22 20:34:10+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-22 20:34:10+02:00
logb9c3d39bd7aa0a4224c71b2a89d5162e36944a35
tree1feafb1ae842390c7713385bd18d387ff17b9eff
parent8d6eb13c725f409270fc34c104da4c206b70c376
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

musl: apply Rich Felker's CVE-2026-107891 patch

https://www.openwall.com/lists/musl/2026/10/21/1

1 files changed, 35 insertions(+), 6 deletions(-)

lib/libc/musl/src/regex/regcomp.c+35-6
......@@ -1674,6 +1674,12 @@ tre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree,
16741674 AST to TNFA compilation routines.
16751675*/
16761676
1677/* check if a+b overflows for a,b in [0,INT_MAX] */
1678static int check_add(unsigned a, unsigned b)
1679{
1680 return a + b > INT_MAX;
1681}
1682
16771683typedef enum {
16781684 COPY_RECURSE,
16791685 COPY_SET_RESULT_PTR
......@@ -1725,6 +1731,8 @@ tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
17251731 /* XXX - e.g. [ab] has only one position but two
17261732 nodes, so we are creating holes in the state space
17271733 here. Not fatal, just wastes memory. */
1734 if (check_add(pos, *pos_add))
1735 return REG_ESPACE;
17281736 pos += *pos_add;
17291737 num_copied++;
17301738 }
......@@ -1820,6 +1828,8 @@ tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
18201828 break;
18211829 }
18221830 }
1831 if (check_add(*pos_add, num_copied))
1832 return REG_ESPACE;
18231833 *pos_add += num_copied;
18241834 return status;
18251835}
......@@ -1864,6 +1874,8 @@ tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
18641874 tre_literal_t *lit= node->obj;
18651875 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
18661876 {
1877 if (check_add(lit->position, pos_add))
1878 return REG_ESPACE;
18671879 lit->position += pos_add;
18681880 if (lit->position > max_pos)
18691881 max_pos = lit->position;
......@@ -1992,6 +2004,8 @@ tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
19922004 }
19932005
19942006 iter_depth--;
2007 if (check_add(pos_add_total, pos_add - pos_add_last))
2008 return REG_ESPACE;
19952009 pos_add_total += pos_add - pos_add_last;
19962010 if (iter_depth == 0)
19972011 pos_add = pos_add_total;
......@@ -2004,6 +2018,8 @@ tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
20042018 }
20052019 }
20062020
2021 if (check_add(*position, pos_add_total))
2022 return REG_ESPACE;
20072023 *position += pos_add_total;
20082024
20092025 /* `max_pos' should never be larger than `*position' if the above
......@@ -2705,9 +2721,19 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
27052721 /* Parse context. */
27062722 tre_parse_ctx_t parse_ctx;
27072723
2724 /* Limits: before tre_expand_ast, int values like position, subid or
2725 * num_tags are bounded by 2x input length, used stack entries are
2726 * bounded by 16x input length. input length is checked upfront to
2727 * avoid overflows before expand. later, values that can grow big are
2728 * bounds checked via check_add and xcalloc. */
2729 const int input_limit = 1024000;
2730 const int stack_limit = 8*input_limit;
2731 if (strnlen(regex, input_limit) >= input_limit)
2732 return REG_ESPACE;
2733
27082734 /* Allocate a stack used throughout the compilation process for various
27092735 purposes. */
2710 stack = tre_stack_new(512, 1024000, 128);
2736 stack = tre_stack_new(512, stack_limit, 128);
27112737 if (!stack)
27122738 return REG_ESPACE;
27132739 /* Allocate a fast memory allocator. */
......@@ -2795,9 +2821,12 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
27952821 for example "a*" or "ab*". Figure out a simple way to detect
27962822 this possibility. */
27972823 tmp_ast_l = tree;
2798 tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position++);
2824 tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position);
27992825 if (tmp_ast_r == NULL)
28002826 ERROR_EXIT(REG_ESPACE);
2827 if (check_add(parse_ctx.position, 1))
2828 ERROR_EXIT(REG_ESPACE);
2829 parse_ctx.position++;
28012830
28022831 tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);
28032832 if (tree == NULL)
......@@ -2807,22 +2836,22 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
28072836 if (errcode != REG_OK)
28082837 ERROR_EXIT(errcode);
28092838
2810 counts = xmalloc(sizeof(int) * parse_ctx.position);
2839 counts = xcalloc(sizeof(int), parse_ctx.position);
28112840 if (counts == NULL)
28122841 ERROR_EXIT(REG_ESPACE);
28132842
2814 offs = xmalloc(sizeof(int) * parse_ctx.position);
2843 offs = xcalloc(sizeof(int), parse_ctx.position);
28152844 if (offs == NULL)
28162845 ERROR_EXIT(REG_ESPACE);
28172846
2818 for (i = 0; i < parse_ctx.position; i++)
2819 counts[i] = 0;
28202847 tre_ast_to_tnfa(tree, NULL, counts, NULL);
28212848
28222849 add = 0;
28232850 for (i = 0; i < parse_ctx.position; i++)
28242851 {
28252852 offs[i] = add;
2853 if (check_add(add, counts[i] + 1))
2854 ERROR_EXIT(REG_ESPACE);
28262855 add += counts[i] + 1;
28272856 counts[i] = 0;
28282857 }