summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-core/busybox/busybox/0001-awk-fix-precedence-of-relative-to.patch197
-rw-r--r--meta/recipes-core/busybox/busybox/0002-awk-fix-ternary-operator-and-precedence-of.patch96
-rw-r--r--meta/recipes-core/busybox/busybox_1.36.1.bb2
3 files changed, 295 insertions, 0 deletions
diff --git a/meta/recipes-core/busybox/busybox/0001-awk-fix-precedence-of-relative-to.patch b/meta/recipes-core/busybox/busybox/0001-awk-fix-precedence-of-relative-to.patch
new file mode 100644
index 0000000000..5836cf8a00
--- /dev/null
+++ b/meta/recipes-core/busybox/busybox/0001-awk-fix-precedence-of-relative-to.patch
@@ -0,0 +1,197 @@
1From dedc9380c76834ba64c8b526aef6f461ea4e7f2e Mon Sep 17 00:00:00 2001
2From: Denys Vlasenko <vda.linux@googlemail.com>
3Date: Tue, 30 May 2023 16:42:18 +0200
4Subject: [PATCH 1/2] awk: fix precedence of = relative to ==
5
6Discovered while adding code to disallow assignments to non-lvalues
7
8function old new delta
9parse_expr 936 991 +55
10.rodata 105243 105247 +4
11------------------------------------------------------------------------------
12(add/remove: 0/0 grow/shrink: 2/0 up/down: 59/0) Total: 59 bytes
13
14CVE: CVE-2023-42364 CVE-2023-42365
15
16Upstream-Status: Backport [https://git.busybox.net/busybox/commit/?id=0256e00a9d077588bd3a39f5a1ef7e2eaa2911e4]
17Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
18(cherry picked from commit 0256e00a9d077588bd3a39f5a1ef7e2eaa2911e4)
19Signed-off-by: Khem Raj <raj.khem@gmail.com>
20---
21 editors/awk.c | 66 ++++++++++++++++++++++++++++++---------------
22 testsuite/awk.tests | 5 ++++
23 2 files changed, 50 insertions(+), 21 deletions(-)
24
25diff --git a/editors/awk.c b/editors/awk.c
26index ec9301e..aff86fe 100644
27--- a/editors/awk.c
28+++ b/editors/awk.c
29@@ -337,7 +337,9 @@ static void debug_parse_print_tc(uint32_t n)
30 #undef P
31 #undef PRIMASK
32 #undef PRIMASK2
33-#define P(x) (x << 24)
34+/* Smaller 'x' means _higher_ operator precedence */
35+#define PRECEDENCE(x) (x << 24)
36+#define P(x) PRECEDENCE(x)
37 #define PRIMASK 0x7F000000
38 #define PRIMASK2 0x7E000000
39
40@@ -360,7 +362,7 @@ enum {
41 OC_MOVE = 0x1f00, OC_PGETLINE = 0x2000, OC_REGEXP = 0x2100,
42 OC_REPLACE = 0x2200, OC_RETURN = 0x2300, OC_SPRINTF = 0x2400,
43 OC_TERNARY = 0x2500, OC_UNARY = 0x2600, OC_VAR = 0x2700,
44- OC_DONE = 0x2800,
45+ OC_CONST = 0x2800, OC_DONE = 0x2900,
46
47 ST_IF = 0x3000, ST_DO = 0x3100, ST_FOR = 0x3200,
48 ST_WHILE = 0x3300
49@@ -440,9 +442,9 @@ static const uint32_t tokeninfo[] ALIGN4 = {
50 #define TI_PREINC (OC_UNARY|xV|P(9)|'P')
51 #define TI_PREDEC (OC_UNARY|xV|P(9)|'M')
52 TI_PREINC, TI_PREDEC, OC_FIELD|xV|P(5),
53- OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(74), OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-',
54- OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/', OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&',
55- OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&',
56+ OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(38), OC_REPLACE|NV|P(38)|'+', OC_REPLACE|NV|P(38)|'-',
57+ OC_REPLACE|NV|P(38)|'*', OC_REPLACE|NV|P(38)|'/', OC_REPLACE|NV|P(38)|'%', OC_REPLACE|NV|P(38)|'&',
58+ OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(38)|'&', OC_BINARY|NV|P(15)|'&',
59 OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*',
60 OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1,
61 #define TI_LESS (OC_COMPARE|VV|P(39)|2)
62@@ -1290,7 +1292,7 @@ static uint32_t next_token(uint32_t expected)
63 save_tclass = tc;
64 save_info = t_info;
65 tc = TC_BINOPX;
66- t_info = OC_CONCAT | SS | P(35);
67+ t_info = OC_CONCAT | SS | PRECEDENCE(35);
68 }
69
70 t_tclass = tc;
71@@ -1350,9 +1352,8 @@ static node *parse_expr(uint32_t term_tc)
72 {
73 node sn;
74 node *cn = &sn;
75- node *vn, *glptr;
76+ node *glptr;
77 uint32_t tc, expected_tc;
78- var *v;
79
80 debug_printf_parse("%s() term_tc(%x):", __func__, term_tc);
81 debug_parse_print_tc(term_tc);
82@@ -1363,11 +1364,12 @@ static node *parse_expr(uint32_t term_tc)
83 expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP | term_tc;
84
85 while (!((tc = next_token(expected_tc)) & term_tc)) {
86+ node *vn;
87
88 if (glptr && (t_info == TI_LESS)) {
89 /* input redirection (<) attached to glptr node */
90 debug_printf_parse("%s: input redir\n", __func__);
91- cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37));
92+ cn = glptr->l.n = new_node(OC_CONCAT | SS | PRECEDENCE(37));
93 cn->a.n = glptr;
94 expected_tc = TS_OPERAND | TS_UOPPRE;
95 glptr = NULL;
96@@ -1379,24 +1381,42 @@ static node *parse_expr(uint32_t term_tc)
97 * previous operators with higher priority */
98 vn = cn;
99 while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2))
100- || ((t_info == vn->info) && t_info == TI_COLON)
101+ || (t_info == vn->info && t_info == TI_COLON)
102 ) {
103 vn = vn->a.n;
104 if (!vn->a.n) syntax_error(EMSG_UNEXP_TOKEN);
105 }
106 if (t_info == TI_TERNARY)
107 //TODO: why?
108- t_info += P(6);
109+ t_info += PRECEDENCE(6);
110 cn = vn->a.n->r.n = new_node(t_info);
111 cn->a.n = vn->a.n;
112 if (tc & TS_BINOP) {
113 cn->l.n = vn;
114-//FIXME: this is the place to detect and reject assignments to non-lvalues.
115-//Currently we allow "assignments" to consts and temporaries, nonsense like this:
116-// awk 'BEGIN { "qwe" = 1 }'
117-// awk 'BEGIN { 7 *= 7 }'
118-// awk 'BEGIN { length("qwe") = 1 }'
119-// awk 'BEGIN { (1+1) += 3 }'
120+
121+ /* Prevent:
122+ * awk 'BEGIN { "qwe" = 1 }'
123+ * awk 'BEGIN { 7 *= 7 }'
124+ * awk 'BEGIN { length("qwe") = 1 }'
125+ * awk 'BEGIN { (1+1) += 3 }'
126+ */
127+ /* Assignment? (including *= and friends) */
128+ if (((t_info & OPCLSMASK) == OC_MOVE)
129+ || ((t_info & OPCLSMASK) == OC_REPLACE)
130+ ) {
131+ debug_printf_parse("%s: MOVE/REPLACE vn->info:%08x\n", __func__, vn->info);
132+ /* Left side is a (variable or array element)
133+ * or function argument
134+ * or $FIELD ?
135+ */
136+ if ((vn->info & OPCLSMASK) != OC_VAR
137+ && (vn->info & OPCLSMASK) != OC_FNARG
138+ && (vn->info & OPCLSMASK) != OC_FIELD
139+ ) {
140+ syntax_error(EMSG_UNEXP_TOKEN); /* no. bad */
141+ }
142+ }
143+
144 expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP;
145 if (t_info == TI_PGETLINE) {
146 /* it's a pipe */
147@@ -1432,6 +1452,8 @@ static node *parse_expr(uint32_t term_tc)
148 /* one should be very careful with switch on tclass -
149 * only simple tclasses should be used (TC_xyz, not TS_xyz) */
150 switch (tc) {
151+ var *v;
152+
153 case TC_VARIABLE:
154 case TC_ARRAY:
155 debug_printf_parse("%s: TC_VARIABLE | TC_ARRAY\n", __func__);
156@@ -1452,14 +1474,14 @@ static node *parse_expr(uint32_t term_tc)
157 case TC_NUMBER:
158 case TC_STRING:
159 debug_printf_parse("%s: TC_NUMBER | TC_STRING\n", __func__);
160- cn->info = OC_VAR;
161+ cn->info = OC_CONST;
162 v = cn->l.v = xzalloc(sizeof(var));
163- if (tc & TC_NUMBER)
164+ if (tc & TC_NUMBER) {
165 setvar_i(v, t_double);
166- else {
167+ } else {
168 setvar_s(v, t_string);
169- expected_tc &= ~TC_UOPPOST; /* "str"++ is not allowed */
170 }
171+ expected_tc &= ~TC_UOPPOST; /* NUM++, "str"++ not allowed */
172 break;
173
174 case TC_REGEXP:
175@@ -3107,6 +3129,8 @@ static var *evaluate(node *op, var *res)
176
177 /* -- recursive node type -- */
178
179+ case XC( OC_CONST ):
180+ debug_printf_eval("CONST ");
181 case XC( OC_VAR ):
182 debug_printf_eval("VAR\n");
183 L.v = op->l.v;
184diff --git a/testsuite/awk.tests b/testsuite/awk.tests
185index ddc5104..a78fdcd 100755
186--- a/testsuite/awk.tests
187+++ b/testsuite/awk.tests
188@@ -540,4 +540,9 @@ testing 'awk assign while assign' \
189 │ trim/eff : 57.02%/26, 0.00% │ [cpu000:100%]
190 └────────────────────────────────────────────────────┘^C"
191
192+testing "awk = has higher precedence than == (despite what gawk manpage claims)" \
193+ "awk 'BEGIN { v=1; print 2==v; print 2==v=2; print v; print v=3==3; print v}'" \
194+ '0\n1\n2\n1\n3\n' \
195+ '' ''
196+
197 exit $FAILCOUNT
diff --git a/meta/recipes-core/busybox/busybox/0002-awk-fix-ternary-operator-and-precedence-of.patch b/meta/recipes-core/busybox/busybox/0002-awk-fix-ternary-operator-and-precedence-of.patch
new file mode 100644
index 0000000000..ea3c84897b
--- /dev/null
+++ b/meta/recipes-core/busybox/busybox/0002-awk-fix-ternary-operator-and-precedence-of.patch
@@ -0,0 +1,96 @@
1From c3bfdac8e0e9a21d524ad72036953f68d2193e52 Mon Sep 17 00:00:00 2001
2From: Natanael Copa <ncopa@alpinelinux.org>
3Date: Tue, 21 May 2024 14:46:08 +0200
4Subject: [PATCH 2/2] awk: fix ternary operator and precedence of =
5
6Adjust the = precedence test to match behavior of gawk, mawk and
7FreeBSD. awk 'BEGIN {print v=3==3; print v}' should print two '1'.
8
9To fix this, and to unbreak the ternary conditional operator, we restore
10the precedence of = in the token list, but override this with a lower
11priority when the assignment is on the right side of a compare.
12
13This fixes commit 0256e00a9d07 (awk: fix precedence of = relative to ==) [1]
14
15CVE: CVE-2023-42364 CVE-2023-42365
16
17Upstream-Status: Submitted [http://lists.busybox.net/pipermail/busybox/2024-May/090766.html]
18
19[1] https://bugs.busybox.net/show_bug.cgi?id=15871#c6
20
21Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
22(cherry picked from commit 1714301c405ef03b39605c85c23f22a190cddd95)
23Signed-off-by: Khem Raj <raj.khem@gmail.com>
24---
25 editors/awk.c | 18 ++++++++++++++----
26 testsuite/awk.tests | 9 +++++++--
27 2 files changed, 21 insertions(+), 6 deletions(-)
28
29diff --git a/editors/awk.c b/editors/awk.c
30index aff86fe..f320d8c 100644
31--- a/editors/awk.c
32+++ b/editors/awk.c
33@@ -442,9 +442,10 @@ static const uint32_t tokeninfo[] ALIGN4 = {
34 #define TI_PREINC (OC_UNARY|xV|P(9)|'P')
35 #define TI_PREDEC (OC_UNARY|xV|P(9)|'M')
36 TI_PREINC, TI_PREDEC, OC_FIELD|xV|P(5),
37- OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(38), OC_REPLACE|NV|P(38)|'+', OC_REPLACE|NV|P(38)|'-',
38- OC_REPLACE|NV|P(38)|'*', OC_REPLACE|NV|P(38)|'/', OC_REPLACE|NV|P(38)|'%', OC_REPLACE|NV|P(38)|'&',
39- OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(38)|'&', OC_BINARY|NV|P(15)|'&',
40+#define TI_ASSIGN (OC_MOVE|VV|P(74))
41+ OC_COMPARE|VV|P(39)|5, TI_ASSIGN, OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-',
42+ OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/', OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&',
43+ OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&',
44 OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*',
45 OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1,
46 #define TI_LESS (OC_COMPARE|VV|P(39)|2)
47@@ -1376,11 +1377,19 @@ static node *parse_expr(uint32_t term_tc)
48 continue;
49 }
50 if (tc & (TS_BINOP | TC_UOPPOST)) {
51+ int prio;
52 debug_printf_parse("%s: TS_BINOP | TC_UOPPOST tc:%x\n", __func__, tc);
53 /* for binary and postfix-unary operators, jump back over
54 * previous operators with higher priority */
55 vn = cn;
56- while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2))
57+ /* Let assignment get higher priority when used on right
58+ * side in compare. i.e: 2==v=3 */
59+ if (t_info == TI_ASSIGN && (vn->a.n->info & OPCLSMASK) == OC_COMPARE) {
60+ prio = PRECEDENCE(38);
61+ } else {
62+ prio = (t_info & PRIMASK);
63+ }
64+ while ((prio > (vn->a.n->info & PRIMASK2))
65 || (t_info == vn->info && t_info == TI_COLON)
66 ) {
67 vn = vn->a.n;
68@@ -1412,6 +1421,7 @@ static node *parse_expr(uint32_t term_tc)
69 if ((vn->info & OPCLSMASK) != OC_VAR
70 && (vn->info & OPCLSMASK) != OC_FNARG
71 && (vn->info & OPCLSMASK) != OC_FIELD
72+ && (vn->info & OPCLSMASK) != OC_COMPARE
73 ) {
74 syntax_error(EMSG_UNEXP_TOKEN); /* no. bad */
75 }
76diff --git a/testsuite/awk.tests b/testsuite/awk.tests
77index a78fdcd..d2706de 100755
78--- a/testsuite/awk.tests
79+++ b/testsuite/awk.tests
80@@ -540,9 +540,14 @@ testing 'awk assign while assign' \
81 │ trim/eff : 57.02%/26, 0.00% │ [cpu000:100%]
82 └────────────────────────────────────────────────────┘^C"
83
84-testing "awk = has higher precedence than == (despite what gawk manpage claims)" \
85+testing "awk = has higher precedence than == on right side" \
86 "awk 'BEGIN { v=1; print 2==v; print 2==v=2; print v; print v=3==3; print v}'" \
87- '0\n1\n2\n1\n3\n' \
88+ '0\n1\n2\n1\n1\n' \
89+ '' ''
90+
91+testing 'awk ternary precedence' \
92+ "awk 'BEGIN { a = 0 ? \"yes\": \"no\"; print a }'" \
93+ 'no\n' \
94 '' ''
95
96 exit $FAILCOUNT
diff --git a/meta/recipes-core/busybox/busybox_1.36.1.bb b/meta/recipes-core/busybox/busybox_1.36.1.bb
index 67bc5c0cad..6972eef81f 100644
--- a/meta/recipes-core/busybox/busybox_1.36.1.bb
+++ b/meta/recipes-core/busybox/busybox_1.36.1.bb
@@ -53,6 +53,8 @@ SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \
53 file://0001-awk-fix-segfault-when-compiled-by-clang.patch \ 53 file://0001-awk-fix-segfault-when-compiled-by-clang.patch \
54 file://CVE-2023-42363.patch \ 54 file://CVE-2023-42363.patch \
55 file://busybox-1.36.1-no-cbq.patch \ 55 file://busybox-1.36.1-no-cbq.patch \
56 file://0001-awk-fix-precedence-of-relative-to.patch \
57 file://0002-awk-fix-ternary-operator-and-precedence-of.patch \
56 " 58 "
57SRC_URI:append:libc-musl = " file://musl.cfg " 59SRC_URI:append:libc-musl = " file://musl.cfg "
58# TODO http://lists.busybox.net/pipermail/busybox/2023-January/090078.html 60# TODO http://lists.busybox.net/pipermail/busybox/2023-January/090078.html