diff --git a/backport-CVE-2023-42364-CVE-2023-42365.patch b/backport-CVE-2023-42364-CVE-2023-42365.patch new file mode 100644 index 0000000000000000000000000000000000000000..083495361e62fbaeedce99c5ecd0db7e796fab04 --- /dev/null +++ b/backport-CVE-2023-42364-CVE-2023-42365.patch @@ -0,0 +1,197 @@ +From 36738cfb66629b94f1594857d50cd57411a61a72 Mon Sep 17 00:00:00 2001 +From: liuxu +Date: Thu, 14 Nov 2024 16:00:16 +0800 +Subject: [PATCH] awk: fix precedence of = relative to == Discovered while + adding code to disallow assignments to non-lvalues + +Conflict:Yes +Reference:https://git.busybox.net/busybox/diff/?id=0256e00a9d077588bd3a39f5a1ef7e2eaa2911e4 + +function old new delta +parse_expr 936 991 +55 +.rodata 105243 105247 +4 +------------------------------------------------------------------------------ +(add/remove: 0/0 grow/shrink: 2/0 up/down: 59/0) Total: 59 bytes + +Signed-off-by: Denys Vlasenko +--- + editors/awk.c | 66 ++++++++++++++++++++++++++++++--------------- + testsuite/awk.tests | 5 ++++ + 2 files changed, 50 insertions(+), 21 deletions(-) + +diff --git a/editors/awk.c b/editors/awk.c +index d65352e..3f6ad97 100644 +--- a/editors/awk.c ++++ b/editors/awk.c +@@ -337,7 +337,9 @@ static void debug_parse_print_tc(uint32_t n) + #undef P + #undef PRIMASK + #undef PRIMASK2 +-#define P(x) (x << 24) ++/* Smaller 'x' means _higher_ operator precedence */ ++#define PRECEDENCE(x) (x << 24) ++#define P(x) PRECEDENCE(x) + #define PRIMASK 0x7F000000 + #define PRIMASK2 0x7E000000 + +@@ -360,7 +362,7 @@ enum { + OC_MOVE = 0x1f00, OC_PGETLINE = 0x2000, OC_REGEXP = 0x2100, + OC_REPLACE = 0x2200, OC_RETURN = 0x2300, OC_SPRINTF = 0x2400, + OC_TERNARY = 0x2500, OC_UNARY = 0x2600, OC_VAR = 0x2700, +- OC_DONE = 0x2800, ++ OC_CONST = 0x2800, OC_DONE = 0x2900, + + ST_IF = 0x3000, ST_DO = 0x3100, ST_FOR = 0x3200, + ST_WHILE = 0x3300 +@@ -440,9 +442,9 @@ static const uint32_t tokeninfo[] ALIGN4 = { + #define TI_PREINC (OC_UNARY|xV|P(9)|'P') + #define TI_PREDEC (OC_UNARY|xV|P(9)|'M') + TI_PREINC, TI_PREDEC, OC_FIELD|xV|P(5), +- OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(74), OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-', +- OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/', OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&', +- OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&', ++ OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(38), OC_REPLACE|NV|P(38)|'+', OC_REPLACE|NV|P(38)|'-', ++ OC_REPLACE|NV|P(38)|'*', OC_REPLACE|NV|P(38)|'/', OC_REPLACE|NV|P(38)|'%', OC_REPLACE|NV|P(38)|'&', ++ OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(38)|'&', OC_BINARY|NV|P(15)|'&', + OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*', + OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, + #define TI_LESS (OC_COMPARE|VV|P(39)|2) +@@ -1290,7 +1292,7 @@ static uint32_t next_token(uint32_t expected) + save_tclass = tc; + save_info = t_info; + tc = TC_BINOPX; +- t_info = OC_CONCAT | SS | P(35); ++ t_info = OC_CONCAT | SS | PRECEDENCE(35); + } + + t_tclass = tc; +@@ -1350,9 +1352,8 @@ static node *parse_expr(uint32_t term_tc) + { + node sn; + node *cn = &sn; +- node *vn, *glptr; ++ node *glptr; + uint32_t tc, expected_tc; +- var *v; + + debug_printf_parse("%s() term_tc(%x):", __func__, term_tc); + debug_parse_print_tc(term_tc); +@@ -1363,11 +1364,12 @@ static node *parse_expr(uint32_t term_tc) + expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP | term_tc; + + while (!((tc = next_token(expected_tc)) & term_tc)) { ++ node *vn; + + if (glptr && (t_info == TI_LESS)) { + /* input redirection (<) attached to glptr node */ + debug_printf_parse("%s: input redir\n", __func__); +- cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37)); ++ cn = glptr->l.n = new_node(OC_CONCAT | SS | PRECEDENCE(37)); + cn->a.n = glptr; + expected_tc = TS_OPERAND | TS_UOPPRE; + glptr = NULL; +@@ -1379,24 +1381,42 @@ static node *parse_expr(uint32_t term_tc) + * previous operators with higher priority */ + vn = cn; + while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2)) +- || ((t_info == vn->info) && t_info == TI_COLON) ++ || (t_info == vn->info && t_info == TI_COLON) + ) { + vn = vn->a.n; + if (!vn->a.n) syntax_error(EMSG_UNEXP_TOKEN); + } + if (t_info == TI_TERNARY) + //TODO: why? +- t_info += P(6); ++ t_info += PRECEDENCE(6); + cn = vn->a.n->r.n = new_node(t_info); + cn->a.n = vn->a.n; + if (tc & TS_BINOP) { + cn->l.n = vn; +-//FIXME: this is the place to detect and reject assignments to non-lvalues. +-//Currently we allow "assignments" to consts and temporaries, nonsense like this: +-// awk 'BEGIN { "qwe" = 1 }' +-// awk 'BEGIN { 7 *= 7 }' +-// awk 'BEGIN { length("qwe") = 1 }' +-// awk 'BEGIN { (1+1) += 3 }' ++ ++ /* Prevent: ++ * awk 'BEGIN { "qwe" = 1 }' ++ * awk 'BEGIN { 7 *= 7 }' ++ * awk 'BEGIN { length("qwe") = 1 }' ++ * awk 'BEGIN { (1+1) += 3 }' ++ */ ++ /* Assignment? (including *= and friends) */ ++ if (((t_info & OPCLSMASK) == OC_MOVE) ++ || ((t_info & OPCLSMASK) == OC_REPLACE) ++ ) { ++ debug_printf_parse("%s: MOVE/REPLACE vn->info:%08x\n", __func__, vn->info); ++ /* Left side is a (variable or array element) ++ * or function argument ++ * or $FIELD ? ++ */ ++ if ((vn->info & OPCLSMASK) != OC_VAR ++ && (vn->info & OPCLSMASK) != OC_FNARG ++ && (vn->info & OPCLSMASK) != OC_FIELD ++ ) { ++ syntax_error(EMSG_UNEXP_TOKEN); /* no. bad */ ++ } ++ } ++ + expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP; + if (t_info == TI_PGETLINE) { + /* it's a pipe */ +@@ -1432,6 +1452,8 @@ static node *parse_expr(uint32_t term_tc) + /* one should be very careful with switch on tclass - + * only simple tclasses should be used (TC_xyz, not TS_xyz) */ + switch (tc) { ++ var *v; ++ + case TC_VARIABLE: + case TC_ARRAY: + debug_printf_parse("%s: TC_VARIABLE | TC_ARRAY\n", __func__); +@@ -1452,14 +1474,14 @@ static node *parse_expr(uint32_t term_tc) + case TC_NUMBER: + case TC_STRING: + debug_printf_parse("%s: TC_NUMBER | TC_STRING\n", __func__); +- cn->info = OC_VAR; ++ cn->info = OC_CONST; + v = cn->l.v = xzalloc(sizeof(var)); +- if (tc & TC_NUMBER) ++ if (tc & TC_NUMBER) { + setvar_i(v, t_double); +- else { ++ } else { + setvar_s(v, t_string); +- expected_tc &= ~TC_UOPPOST; /* "str"++ is not allowed */ + } ++ expected_tc &= ~TC_UOPPOST; /* NUM++, "str"++ not allowed */ + break; + + case TC_REGEXP: +@@ -3093,6 +3115,8 @@ static var *evaluate(node *op, var *res) + + /* -- recursive node type -- */ + ++ case XC( OC_CONST ): ++ debug_printf_eval("CONST "); + case XC( OC_VAR ): + debug_printf_eval("VAR\n"); + L.v = op->l.v; +diff --git a/testsuite/awk.tests b/testsuite/awk.tests +index bbf0fbf..a71ef3b 100755 +--- a/testsuite/awk.tests ++++ b/testsuite/awk.tests +@@ -485,4 +485,9 @@ testing 'awk assign while test' \ + "" \ + "foo" + ++testing "awk = has higher precedence than == (despite what gawk manpage claims)" \ ++ "awk 'BEGIN { v=1; print 2==v; print 2==v=2; print v; print v=3==3; print v}'" \ ++ '0\n1\n2\n1\n3\n' \ ++ '' '' ++ + exit $FAILCOUNT +-- +2.43.0 + diff --git a/backport-CVE-2023-42366.patch b/backport-CVE-2023-42366.patch new file mode 100644 index 0000000000000000000000000000000000000000..d8d4b9de3fac444d0d25091e7ccaf20459e5196c --- /dev/null +++ b/backport-CVE-2023-42366.patch @@ -0,0 +1,34 @@ +From c55dcbb77bb0bd7e61ce5c7a074013be06b32629 Mon Sep 17 00:00:00 2001 +From: Valery Ushakov +Date: Wed, 24 Jan 2024 22:24:41 +0300 +Subject: [PATCH] awk.c: fix CVE-2023-42366 (bug #15874) + +Make sure we don't read past the end of the string in next_token() +when backslash is the last character in an (invalid) regexp. + +Conflict:No +Reference:https://git.alpinelinux.org/aports/plain/main/busybox/0026-awk.c-fix-CVE-2023-42366-bug-15874.patch + +https://bugs.busybox.net/show_bug.cgi?id=15874 +--- + editors/awk.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/editors/awk.c b/editors/awk.c +index 64e752f4b..222e6298d 100644 +--- a/editors/awk.c ++++ b/editors/awk.c +@@ -1234,9 +1234,11 @@ static uint32_t next_token(uint32_t expected) + s[-1] = bb_process_escape_sequence((const char **)&pp); + if (*p == '\\') + *s++ = '\\'; +- if (pp == p) ++ if (pp == p) { ++ if (*p == '\0') ++ syntax_error(EMSG_UNEXP_EOS); + *s++ = *p++; +- else ++ } else + p = pp; + } + } diff --git a/busybox.spec b/busybox.spec index af8779956e16b6fd696ff9447c2eadd2f787cecd..aa34f54fe1954ab2e0e0278240e9714ebd2084f2 100644 --- a/busybox.spec +++ b/busybox.spec @@ -4,7 +4,7 @@ %endif %if "%{!?RELEASE:1}" -%define RELEASE 7 +%define RELEASE 8 %endif Epoch: 1 @@ -23,6 +23,8 @@ Source3: busybox-dynamic.config Patch6000: backport-CVE-2022-28391.patch Patch6001: backport-CVE-2022-48174.patch Patch6002: backport-CVE-2023-42363.patch +Patch6003: backport-CVE-2023-42364-CVE-2023-42365.patch +Patch6004: backport-CVE-2023-42366.patch BuildRoot: %_topdir/BUILDROOT #Dependency @@ -98,6 +100,12 @@ install -m 644 docs/busybox.dynamic.1 $RPM_BUILD_ROOT/%{_mandir}/man1/busybox.1 %{_mandir}/man1/busybox.petitboot.1.gz %changelog +* Fri Nov 15 2024 liuxu - 1:1.36.1-8 +- Type:CVE +- Id:NA +- SUG:NA +- DESC:fix CVE-2023-42364 CVE-2023-42365 CVE-2023-42366 + * Mon Jul 22 2024 liuxu - 1:1.36.1-7 - Type:CVE - Id:NA