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,...@@ -1674,6 +1674,12 @@ tre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree,
1674 AST to TNFA compilation routines.1674 AST to TNFA compilation routines.
1675*/1675*/
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
1677typedef enum {1683typedef enum {
1678 COPY_RECURSE,1684 COPY_RECURSE,
1679 COPY_SET_RESULT_PTR1685 COPY_SET_RESULT_PTR
...@@ -1725,6 +1731,8 @@ tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,...@@ -1725,6 +1731,8 @@ tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
1725 /* XXX - e.g. [ab] has only one position but two1731 /* XXX - e.g. [ab] has only one position but two
1726 nodes, so we are creating holes in the state space1732 nodes, so we are creating holes in the state space
1727 here. Not fatal, just wastes memory. */1733 here. Not fatal, just wastes memory. */
1734 if (check_add(pos, *pos_add))
1735 return REG_ESPACE;
1728 pos += *pos_add;1736 pos += *pos_add;
1729 num_copied++;1737 num_copied++;
1730 }1738 }
...@@ -1820,6 +1828,8 @@ tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,...@@ -1820,6 +1828,8 @@ tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
1820 break;1828 break;
1821 }1829 }
1822 }1830 }
1831 if (check_add(*pos_add, num_copied))
1832 return REG_ESPACE;
1823 *pos_add += num_copied;1833 *pos_add += num_copied;
1824 return status;1834 return status;
1825}1835}
...@@ -1864,6 +1874,8 @@ tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,...@@ -1864,6 +1874,8 @@ tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
1864 tre_literal_t *lit= node->obj;1874 tre_literal_t *lit= node->obj;
1865 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))1875 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
1866 {1876 {
1877 if (check_add(lit->position, pos_add))
1878 return REG_ESPACE;
1867 lit->position += pos_add;1879 lit->position += pos_add;
1868 if (lit->position > max_pos)1880 if (lit->position > max_pos)
1869 max_pos = lit->position;1881 max_pos = lit->position;
...@@ -1992,6 +2004,8 @@ tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,...@@ -1992,6 +2004,8 @@ tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
1992 }2004 }
19932005
1994 iter_depth--;2006 iter_depth--;
2007 if (check_add(pos_add_total, pos_add - pos_add_last))
2008 return REG_ESPACE;
1995 pos_add_total += pos_add - pos_add_last;2009 pos_add_total += pos_add - pos_add_last;
1996 if (iter_depth == 0)2010 if (iter_depth == 0)
1997 pos_add = pos_add_total;2011 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,...@@ -2004,6 +2018,8 @@ tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
2004 }2018 }
2005 }2019 }
20062020
2021 if (check_add(*position, pos_add_total))
2022 return REG_ESPACE;
2007 *position += pos_add_total;2023 *position += pos_add_total;
20082024
2009 /* `max_pos' should never be larger than `*position' if the above2025 /* `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)...@@ -2705,9 +2721,19 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
2705 /* Parse context. */2721 /* Parse context. */
2706 tre_parse_ctx_t parse_ctx;2722 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
2708 /* Allocate a stack used throughout the compilation process for various2734 /* Allocate a stack used throughout the compilation process for various
2709 purposes. */2735 purposes. */
2710 stack = tre_stack_new(512, 1024000, 128);2736 stack = tre_stack_new(512, stack_limit, 128);
2711 if (!stack)2737 if (!stack)
2712 return REG_ESPACE;2738 return REG_ESPACE;
2713 /* Allocate a fast memory allocator. */2739 /* Allocate a fast memory allocator. */
...@@ -2795,9 +2821,12 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)...@@ -2795,9 +2821,12 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
2795 for example "a*" or "ab*". Figure out a simple way to detect2821 for example "a*" or "ab*". Figure out a simple way to detect
2796 this possibility. */2822 this possibility. */
2797 tmp_ast_l = tree;2823 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);
2799 if (tmp_ast_r == NULL)2825 if (tmp_ast_r == NULL)
2800 ERROR_EXIT(REG_ESPACE);2826 ERROR_EXIT(REG_ESPACE);
2827 if (check_add(parse_ctx.position, 1))
2828 ERROR_EXIT(REG_ESPACE);
2829 parse_ctx.position++;
28012830
2802 tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);2831 tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);
2803 if (tree == NULL)2832 if (tree == NULL)
...@@ -2807,22 +2836,22 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)...@@ -2807,22 +2836,22 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
2807 if (errcode != REG_OK)2836 if (errcode != REG_OK)
2808 ERROR_EXIT(errcode);2837 ERROR_EXIT(errcode);
28092838
2810 counts = xmalloc(sizeof(int) * parse_ctx.position);2839 counts = xcalloc(sizeof(int), parse_ctx.position);
2811 if (counts == NULL)2840 if (counts == NULL)
2812 ERROR_EXIT(REG_ESPACE);2841 ERROR_EXIT(REG_ESPACE);
28132842
2814 offs = xmalloc(sizeof(int) * parse_ctx.position);2843 offs = xcalloc(sizeof(int), parse_ctx.position);
2815 if (offs == NULL)2844 if (offs == NULL)
2816 ERROR_EXIT(REG_ESPACE);2845 ERROR_EXIT(REG_ESPACE);
28172846
2818 for (i = 0; i < parse_ctx.position; i++)
2819 counts[i] = 0;
2820 tre_ast_to_tnfa(tree, NULL, counts, NULL);2847 tre_ast_to_tnfa(tree, NULL, counts, NULL);
28212848
2822 add = 0;2849 add = 0;
2823 for (i = 0; i < parse_ctx.position; i++)2850 for (i = 0; i < parse_ctx.position; i++)
2824 {2851 {
2825 offs[i] = add;2852 offs[i] = add;
2853 if (check_add(add, counts[i] + 1))
2854 ERROR_EXIT(REG_ESPACE);
2826 add += counts[i] + 1;2855 add += counts[i] + 1;
2827 counts[i] = 0;2856 counts[i] = 0;
2828 }2857 }