diff options
Diffstat (limited to 'meta/recipes-core/busybox')
10 files changed, 751 insertions, 10 deletions
diff --git a/meta/recipes-core/busybox/busybox.inc b/meta/recipes-core/busybox/busybox.inc index e0522be729..f0c5666f47 100644 --- a/meta/recipes-core/busybox/busybox.inc +++ b/meta/recipes-core/busybox/busybox.inc | |||
@@ -139,6 +139,10 @@ do_configure () { | |||
139 | do_prepare_config | 139 | do_prepare_config |
140 | merge_config.sh -m .config ${@" ".join(find_cfgs(d))} | 140 | merge_config.sh -m .config ${@" ".join(find_cfgs(d))} |
141 | cml1_do_configure | 141 | cml1_do_configure |
142 | |||
143 | # Save a copy of .config and autoconf.h. | ||
144 | cp .config .config.orig | ||
145 | cp include/autoconf.h include/autoconf.h.orig | ||
142 | } | 146 | } |
143 | 147 | ||
144 | do_compile() { | 148 | do_compile() { |
@@ -146,13 +150,17 @@ do_compile() { | |||
146 | if [ "${BUILD_REPRODUCIBLE_BINARIES}" = "1" ]; then | 150 | if [ "${BUILD_REPRODUCIBLE_BINARIES}" = "1" ]; then |
147 | export KCONFIG_NOTIMESTAMP=1 | 151 | export KCONFIG_NOTIMESTAMP=1 |
148 | fi | 152 | fi |
153 | |||
154 | # Ensure we start do_compile with the original .config and autoconf.h. | ||
155 | # These files should always have matching timestamps. | ||
156 | cp .config.orig .config | ||
157 | cp include/autoconf.h.orig include/autoconf.h | ||
158 | |||
149 | if [ "${BUSYBOX_SPLIT_SUID}" = "1" -a x`grep "CONFIG_FEATURE_INDIVIDUAL=y" .config` = x ]; then | 159 | if [ "${BUSYBOX_SPLIT_SUID}" = "1" -a x`grep "CONFIG_FEATURE_INDIVIDUAL=y" .config` = x ]; then |
160 | # Guard againt interrupted do_compile: clean temporary files. | ||
161 | rm -f .config.app.suid .config.app.nosuid .config.disable.apps .config.nonapps | ||
162 | |||
150 | # split the .config into two parts, and make two busybox binaries | 163 | # split the .config into two parts, and make two busybox binaries |
151 | if [ -e .config.orig ]; then | ||
152 | # Need to guard again an interrupted do_compile - restore any backup | ||
153 | cp .config.orig .config | ||
154 | fi | ||
155 | cp .config .config.orig | ||
156 | oe_runmake busybox.cfg.suid | 164 | oe_runmake busybox.cfg.suid |
157 | oe_runmake busybox.cfg.nosuid | 165 | oe_runmake busybox.cfg.nosuid |
158 | 166 | ||
@@ -189,15 +197,18 @@ do_compile() { | |||
189 | bbfatal "busybox suid binary incorrectly provides /bin/sh" | 197 | bbfatal "busybox suid binary incorrectly provides /bin/sh" |
190 | fi | 198 | fi |
191 | 199 | ||
192 | # copy .config.orig back to .config, because the install process may check this file | ||
193 | cp .config.orig .config | ||
194 | # cleanup | 200 | # cleanup |
195 | rm .config.orig .config.app.suid .config.app.nosuid .config.disable.apps .config.nonapps | 201 | rm .config.app.suid .config.app.nosuid .config.disable.apps .config.nonapps |
196 | else | 202 | else |
197 | oe_runmake busybox_unstripped | 203 | oe_runmake busybox_unstripped |
198 | cp busybox_unstripped busybox | 204 | cp busybox_unstripped busybox |
199 | oe_runmake busybox.links | 205 | oe_runmake busybox.links |
200 | fi | 206 | fi |
207 | |||
208 | # restore original .config and autoconf.h, because the install process | ||
209 | # may check these files | ||
210 | cp .config.orig .config | ||
211 | cp include/autoconf.h.orig include/autoconf.h | ||
201 | } | 212 | } |
202 | 213 | ||
203 | do_install () { | 214 | do_install () { |
@@ -348,7 +359,7 @@ do_install_ptest () { | |||
348 | # These access the internet which is not guaranteed to work on machines running the tests | 359 | # These access the internet which is not guaranteed to work on machines running the tests |
349 | rm -rf ${D}${PTEST_PATH}/testsuite/wget | 360 | rm -rf ${D}${PTEST_PATH}/testsuite/wget |
350 | sort ${B}/.config > ${D}${PTEST_PATH}/.config | 361 | sort ${B}/.config > ${D}${PTEST_PATH}/.config |
351 | ln -s /bin/busybox ${D}${PTEST_PATH}/busybox | 362 | ln -s ${base_bindir}/busybox ${D}${PTEST_PATH}/busybox |
352 | } | 363 | } |
353 | 364 | ||
354 | inherit update-alternatives | 365 | inherit update-alternatives |
diff --git a/meta/recipes-core/busybox/busybox/0001-decompress_gunzip-Fix-DoS-if-gzip-is-corrupt.patch b/meta/recipes-core/busybox/busybox/0001-decompress_gunzip-Fix-DoS-if-gzip-is-corrupt.patch new file mode 100644 index 0000000000..b75f0907e7 --- /dev/null +++ b/meta/recipes-core/busybox/busybox/0001-decompress_gunzip-Fix-DoS-if-gzip-is-corrupt.patch | |||
@@ -0,0 +1,51 @@ | |||
1 | From fe791386ebc270219ca00406c9fdadc5130b64ee Mon Sep 17 00:00:00 2001 | ||
2 | From: Samuel Sapalski <samuel.sapalski@nokia.com> | ||
3 | Date: Wed, 3 Mar 2021 16:31:22 +0100 | ||
4 | Subject: [PATCH] decompress_gunzip: Fix DoS if gzip is corrupt | ||
5 | |||
6 | On certain corrupt gzip files, huft_build will set the error bit on | ||
7 | the result pointer. If afterwards abort_unzip is called huft_free | ||
8 | might run into a segmentation fault or an invalid pointer to | ||
9 | free(p). | ||
10 | |||
11 | In order to mitigate this, we check in huft_free if the error bit | ||
12 | is set and clear it before the linked list is freed. | ||
13 | |||
14 | Signed-off-by: Samuel Sapalski <samuel.sapalski@nokia.com> | ||
15 | Signed-off-by: Peter Kaestle <peter.kaestle@nokia.com> | ||
16 | Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> | ||
17 | |||
18 | Upstream-Status: Backport | ||
19 | CVE: CVE-2021-28831 | ||
20 | Comment: One hunk from this patch is removed as it was not relevant. | ||
21 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> | ||
22 | Signed-off-by: Akash Hadke <Akash.Hadke@kpit.com> | ||
23 | --- | ||
24 | archival/libarchive/decompress_gunzip.c | 12 ++++++++++-- | ||
25 | 1 file changed, 10 insertions(+), 2 deletions(-) | ||
26 | |||
27 | diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c | ||
28 | index eb3b64930..e93cd5005 100644 | ||
29 | --- a/archival/libarchive/decompress_gunzip.c | ||
30 | +++ b/archival/libarchive/decompress_gunzip.c | ||
31 | @@ -220,10 +220,20 @@ static const uint8_t border[] ALIGN1 = { | ||
32 | * each table. | ||
33 | * t: table to free | ||
34 | */ | ||
35 | +#define BAD_HUFT(p) ((uintptr_t)(p) & 1) | ||
36 | +#define ERR_RET ((huft_t*)(uintptr_t)1) | ||
37 | static void huft_free(huft_t *p) | ||
38 | { | ||
39 | huft_t *q; | ||
40 | |||
41 | + /* | ||
42 | + * If 'p' has the error bit set we have to clear it, otherwise we might run | ||
43 | + * into a segmentation fault or an invalid pointer to free(p) | ||
44 | + */ | ||
45 | + if (BAD_HUFT(p)) { | ||
46 | + p = (huft_t*)((uintptr_t)(p) ^ (uintptr_t)(ERR_RET)); | ||
47 | + } | ||
48 | + | ||
49 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ | ||
50 | while (p) { | ||
51 | q = (--p)->v.t; | ||
diff --git a/meta/recipes-core/busybox/busybox/0001-libbb-sockaddr2str-ensure-only-printable-characters-.patch b/meta/recipes-core/busybox/busybox/0001-libbb-sockaddr2str-ensure-only-printable-characters-.patch new file mode 100644 index 0000000000..18bf5f19e4 --- /dev/null +++ b/meta/recipes-core/busybox/busybox/0001-libbb-sockaddr2str-ensure-only-printable-characters-.patch | |||
@@ -0,0 +1,38 @@ | |||
1 | From c7e181fdf58c392e06ab805e2c044c3e57d5445a Mon Sep 17 00:00:00 2001 | ||
2 | From: Ariadne Conill <ariadne@dereferenced.org> | ||
3 | Date: Sun, 3 Apr 2022 12:14:33 +0000 | ||
4 | Subject: [PATCH] libbb: sockaddr2str: ensure only printable characters are | ||
5 | returned for the hostname part | ||
6 | |||
7 | CVE: CVE-2022-28391 | ||
8 | Upstream-Status: Pending | ||
9 | Signed-off-by: Ariadne Conill <ariadne@dereferenced.org> | ||
10 | Signed-off-by: Steve Sakoman <steve@sakoman.com> | ||
11 | --- | ||
12 | libbb/xconnect.c | 5 +++-- | ||
13 | 1 file changed, 3 insertions(+), 2 deletions(-) | ||
14 | |||
15 | diff --git a/libbb/xconnect.c b/libbb/xconnect.c | ||
16 | index eb2871cb1..b5520bb21 100644 | ||
17 | --- a/libbb/xconnect.c | ||
18 | +++ b/libbb/xconnect.c | ||
19 | @@ -501,8 +501,9 @@ static char* FAST_FUNC sockaddr2str(const struct sockaddr *sa, int flags) | ||
20 | ); | ||
21 | if (rc) | ||
22 | return NULL; | ||
23 | + /* ensure host contains only printable characters */ | ||
24 | if (flags & IGNORE_PORT) | ||
25 | - return xstrdup(host); | ||
26 | + return xstrdup(printable_string(host)); | ||
27 | #if ENABLE_FEATURE_IPV6 | ||
28 | if (sa->sa_family == AF_INET6) { | ||
29 | if (strchr(host, ':')) /* heh, it's not a resolved hostname */ | ||
30 | @@ -513,7 +514,7 @@ static char* FAST_FUNC sockaddr2str(const struct sockaddr *sa, int flags) | ||
31 | #endif | ||
32 | /* For now we don't support anything else, so it has to be INET */ | ||
33 | /*if (sa->sa_family == AF_INET)*/ | ||
34 | - return xasprintf("%s:%s", host, serv); | ||
35 | + return xasprintf("%s:%s", printable_string(host), serv); | ||
36 | /*return xstrdup(host);*/ | ||
37 | } | ||
38 | |||
diff --git a/meta/recipes-core/busybox/busybox/0001-mktemp-add-tmpdir-option.patch b/meta/recipes-core/busybox/busybox/0001-mktemp-add-tmpdir-option.patch new file mode 100644 index 0000000000..4a1960dff2 --- /dev/null +++ b/meta/recipes-core/busybox/busybox/0001-mktemp-add-tmpdir-option.patch | |||
@@ -0,0 +1,81 @@ | |||
1 | From ceb378209f953ea745ed93a8645567196380ce3c Mon Sep 17 00:00:00 2001 | ||
2 | From: Andrej Valek <andrej.valek@siemens.com> | ||
3 | Date: Thu, 24 Jun 2021 19:13:22 +0200 | ||
4 | Subject: [PATCH] mktemp: add tmpdir option | ||
5 | |||
6 | Make mktemp more compatible with coreutils. | ||
7 | - add "--tmpdir" option | ||
8 | - add long variants for "d,q,u" options | ||
9 | |||
10 | Upstream-Status: Submitted [http://lists.busybox.net/pipermail/busybox/2021-June/088932.html] | ||
11 | |||
12 | Signed-off-by: Andrej Valek <andrej.valek@siemens.com> | ||
13 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
14 | --- | ||
15 | coreutils/mktemp.c | 26 ++++++++++++++++++-------- | ||
16 | 1 file changed, 18 insertions(+), 8 deletions(-) | ||
17 | |||
18 | diff --git a/coreutils/mktemp.c b/coreutils/mktemp.c | ||
19 | index 5393320a5..05c6d98c6 100644 | ||
20 | --- a/coreutils/mktemp.c | ||
21 | +++ b/coreutils/mktemp.c | ||
22 | @@ -39,16 +39,17 @@ | ||
23 | //kbuild:lib-$(CONFIG_MKTEMP) += mktemp.o | ||
24 | |||
25 | //usage:#define mktemp_trivial_usage | ||
26 | -//usage: "[-dt] [-p DIR] [TEMPLATE]" | ||
27 | +//usage: "[-dt] [-p DIR, --tmpdir[=DIR]] [TEMPLATE]" | ||
28 | //usage:#define mktemp_full_usage "\n\n" | ||
29 | //usage: "Create a temporary file with name based on TEMPLATE and print its name.\n" | ||
30 | //usage: "TEMPLATE must end with XXXXXX (e.g. [/dir/]nameXXXXXX).\n" | ||
31 | //usage: "Without TEMPLATE, -t tmp.XXXXXX is assumed.\n" | ||
32 | -//usage: "\n -d Make directory, not file" | ||
33 | -//usage: "\n -q Fail silently on errors" | ||
34 | -//usage: "\n -t Prepend base directory name to TEMPLATE" | ||
35 | -//usage: "\n -p DIR Use DIR as a base directory (implies -t)" | ||
36 | -//usage: "\n -u Do not create anything; print a name" | ||
37 | +//usage: "\n -d Make directory, not file" | ||
38 | +//usage: "\n -q Fail silently on errors" | ||
39 | +//usage: "\n -t Prepend base directory name to TEMPLATE" | ||
40 | +//usage: "\n -p DIR, --tmpdir[=DIR] Use DIR as a base directory (implies -t)" | ||
41 | +//usage: "\n For --tmpdir is a optional one." | ||
42 | +//usage: "\n -u Do not create anything; print a name" | ||
43 | //usage: "\n" | ||
44 | //usage: "\nBase directory is: -p DIR, else $TMPDIR, else /tmp" | ||
45 | //usage: | ||
46 | @@ -72,13 +73,22 @@ int mktemp_main(int argc UNUSED_PARAM, char **argv) | ||
47 | OPT_t = 1 << 2, | ||
48 | OPT_p = 1 << 3, | ||
49 | OPT_u = 1 << 4, | ||
50 | + OPT_td = 1 << 5, | ||
51 | }; | ||
52 | |||
53 | path = getenv("TMPDIR"); | ||
54 | if (!path || path[0] == '\0') | ||
55 | path = "/tmp"; | ||
56 | |||
57 | - opts = getopt32(argv, "^" "dqtp:u" "\0" "?1"/*1 arg max*/, &path); | ||
58 | + opts = getopt32long(argv, "^" | ||
59 | + "dqtp:u\0" | ||
60 | + "?1" /* 1 arg max */, | ||
61 | + "directory\0" No_argument "d" | ||
62 | + "quiet\0" No_argument "q" | ||
63 | + "dry-run\0" No_argument "u" | ||
64 | + "tmpdir\0" Optional_argument "\xff" | ||
65 | + , &path, &path | ||
66 | + ); | ||
67 | |||
68 | chp = argv[optind]; | ||
69 | if (!chp) { | ||
70 | @@ -95,7 +105,7 @@ int mktemp_main(int argc UNUSED_PARAM, char **argv) | ||
71 | goto error; | ||
72 | } | ||
73 | #endif | ||
74 | - if (opts & (OPT_t|OPT_p)) | ||
75 | + if (opts & (OPT_t|OPT_p|OPT_td)) | ||
76 | chp = concat_path_file(path, chp); | ||
77 | |||
78 | if (opts & OPT_u) { | ||
79 | -- | ||
80 | 2.11.0 | ||
81 | |||
diff --git a/meta/recipes-core/busybox/busybox/0002-nslookup-sanitize-all-printed-strings-with-printable.patch b/meta/recipes-core/busybox/busybox/0002-nslookup-sanitize-all-printed-strings-with-printable.patch new file mode 100644 index 0000000000..2c9da33a51 --- /dev/null +++ b/meta/recipes-core/busybox/busybox/0002-nslookup-sanitize-all-printed-strings-with-printable.patch | |||
@@ -0,0 +1,64 @@ | |||
1 | From f8ad7c331b25ba90fd296b37c443b4114cb196e2 Mon Sep 17 00:00:00 2001 | ||
2 | From: Ariadne Conill <ariadne@dereferenced.org> | ||
3 | Date: Sun, 3 Apr 2022 12:16:45 +0000 | ||
4 | Subject: [PATCH] nslookup: sanitize all printed strings with printable_string | ||
5 | |||
6 | Otherwise, terminal sequences can be injected, which enables various terminal injection | ||
7 | attacks from DNS results. | ||
8 | |||
9 | MJ: One chunk wasn't applicable on 1.31.1 version, because parsing of | ||
10 | SRV records was added only in newer 1.32.0 with: | ||
11 | commit 6b4960155e94076bf25518e4e268a7a5f849308e | ||
12 | Author: Jo-Philipp Wich <jo@mein.io> | ||
13 | Date: Thu Jun 27 17:27:29 2019 +0200 | ||
14 | |||
15 | nslookup: implement support for SRV records | ||
16 | |||
17 | CVE: CVE-2022-28391 | ||
18 | Upstream-Status: Pending | ||
19 | Signed-off-by: Ariadne Conill <ariadne@dereferenced.org> | ||
20 | Signed-off-by: Steve Sakoman <steve@sakoman.com> | ||
21 | --- | ||
22 | networking/nslookup.c | 8 ++++---- | ||
23 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
24 | |||
25 | diff --git a/networking/nslookup.c b/networking/nslookup.c | ||
26 | index 24e09d4f0..89b9c8a13 100644 | ||
27 | --- a/networking/nslookup.c | ||
28 | +++ b/networking/nslookup.c | ||
29 | @@ -404,7 +404,7 @@ static int parse_reply(const unsigned char *msg, size_t len) | ||
30 | //printf("Unable to uncompress domain: %s\n", strerror(errno)); | ||
31 | return -1; | ||
32 | } | ||
33 | - printf(format, ns_rr_name(rr), dname); | ||
34 | + printf(format, ns_rr_name(rr), printable_string(dname)); | ||
35 | break; | ||
36 | |||
37 | case ns_t_mx: | ||
38 | @@ -419,7 +419,7 @@ static int parse_reply(const unsigned char *msg, size_t len) | ||
39 | //printf("Cannot uncompress MX domain: %s\n", strerror(errno)); | ||
40 | return -1; | ||
41 | } | ||
42 | - printf("%s\tmail exchanger = %d %s\n", ns_rr_name(rr), n, dname); | ||
43 | + printf("%s\tmail exchanger = %d %s\n", ns_rr_name(rr), n, printable_string(dname)); | ||
44 | break; | ||
45 | |||
46 | case ns_t_txt: | ||
47 | @@ -431,7 +431,7 @@ static int parse_reply(const unsigned char *msg, size_t len) | ||
48 | if (n > 0) { | ||
49 | memset(dname, 0, sizeof(dname)); | ||
50 | memcpy(dname, ns_rr_rdata(rr) + 1, n); | ||
51 | - printf("%s\ttext = \"%s\"\n", ns_rr_name(rr), dname); | ||
52 | + printf("%s\ttext = \"%s\"\n", ns_rr_name(rr), printable_string(dname)); | ||
53 | } | ||
54 | break; | ||
55 | |||
56 | @@ -461,7 +461,7 @@ static int parse_reply(const unsigned char *msg, size_t len) | ||
57 | return -1; | ||
58 | } | ||
59 | |||
60 | - printf("\tmail addr = %s\n", dname); | ||
61 | + printf("\tmail addr = %s\n", printable_string(dname)); | ||
62 | cp += n; | ||
63 | |||
64 | printf("\tserial = %lu\n", ns_get32(cp)); | ||
diff --git a/meta/recipes-core/busybox/busybox/CVE-2021-42374.patch b/meta/recipes-core/busybox/busybox/CVE-2021-42374.patch new file mode 100644 index 0000000000..aef8a3db85 --- /dev/null +++ b/meta/recipes-core/busybox/busybox/CVE-2021-42374.patch | |||
@@ -0,0 +1,53 @@ | |||
1 | From 04f052c56ded5ab6a904e3a264a73dc0412b2e78 Mon Sep 17 00:00:00 2001 | ||
2 | From: Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | Date: Tue, 15 Jun 2021 15:07:57 +0200 | ||
4 | Subject: [PATCH] unlzma: fix a case where we could read before beginning of | ||
5 | buffer | ||
6 | Cc: pavel@zhukoff.net | ||
7 | |||
8 | Testcase: | ||
9 | |||
10 | 21 01 01 00 00 00 00 00 e7 01 01 01 ef 00 df b6 | ||
11 | 00 17 02 10 11 0f ff 00 16 00 00 | ||
12 | |||
13 | Unfortunately, the bug is not reliably causing a segfault, | ||
14 | the behavior depends on what's in memory before the buffer. | ||
15 | |||
16 | function old new delta | ||
17 | unpack_lzma_stream 2762 2768 +6 | ||
18 | |||
19 | Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> | ||
20 | |||
21 | Signed-off-by: Pavel Zhukov <pavel.zhukov@huawei.com> | ||
22 | |||
23 | CVE: CVE-2021-42374 | ||
24 | Upstream-Status: Backport [https://git.busybox.net/busybox/commit/?h=1_33_stable&id=d326be2850ea2bd78fe2c22d6c45c3b861d82937] | ||
25 | Comment: testdata dropped because of binary format | ||
26 | |||
27 | --- | ||
28 | archival/libarchive/decompress_unlzma.c | 5 ++++- | ||
29 | testsuite/unlzma.tests | 17 +++++++++++++---- | ||
30 | testsuite/unlzma_issue_3.lzma | Bin 0 -> 27 bytes | ||
31 | 3 files changed, 17 insertions(+), 5 deletions(-) | ||
32 | create mode 100644 testsuite/unlzma_issue_3.lzma | ||
33 | |||
34 | diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c | ||
35 | index 0744f231a1d64d92676b0cada2342f88f3b39b31..fb5aac8fe9ea0c53e0c2d7a7cbd05a753e39bc9d 100644 | ||
36 | --- a/archival/libarchive/decompress_unlzma.c | ||
37 | +++ b/archival/libarchive/decompress_unlzma.c | ||
38 | @@ -290,8 +290,11 @@ unpack_lzma_stream(transformer_state_t *xstate) | ||
39 | uint32_t pos; | ||
40 | |||
41 | pos = buffer_pos - rep0; | ||
42 | - if ((int32_t)pos < 0) | ||
43 | + if ((int32_t)pos < 0) { | ||
44 | pos += header.dict_size; | ||
45 | + if ((int32_t)pos < 0) | ||
46 | + goto bad; | ||
47 | + } | ||
48 | match_byte = buffer[pos]; | ||
49 | do { | ||
50 | int bit; | ||
51 | -- | ||
52 | 2.34.0 | ||
53 | |||
diff --git a/meta/recipes-core/busybox/busybox/CVE-2021-42376.patch b/meta/recipes-core/busybox/busybox/CVE-2021-42376.patch new file mode 100644 index 0000000000..c913eaee9c --- /dev/null +++ b/meta/recipes-core/busybox/busybox/CVE-2021-42376.patch | |||
@@ -0,0 +1,138 @@ | |||
1 | From 56a335378ac100d51c30b21eee499a2effa37fba Mon Sep 17 00:00:00 2001 | ||
2 | From: Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | Date: Tue, 15 Jun 2021 16:05:57 +0200 | ||
4 | Subject: hush: fix handling of \^C and "^C" | ||
5 | |||
6 | function old new delta | ||
7 | parse_stream 2238 2252 +14 | ||
8 | encode_string 243 256 +13 | ||
9 | ------------------------------------------------------------------------------ | ||
10 | (add/remove: 0/0 grow/shrink: 2/0 up/down: 27/0) Total: 27 bytes | ||
11 | |||
12 | Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> | ||
13 | (cherry picked from commit 1b7a9b68d0e9aa19147d7fda16eb9a6b54156985) | ||
14 | |||
15 | Signed-off-by: Pavel Zhukov <pavel.zhukov@huawei.com> | ||
16 | |||
17 | CVE: CVE-2021-42376 | ||
18 | Upstream-Status: Backport [https://git.busybox.net/busybox/patch/?id=56a335378ac100d51c30b21eee499a2effa37fba] | ||
19 | Comment: No changes in any hunk | ||
20 | --- | ||
21 | shell/ash_test/ash-misc/control_char3.right | 1 + | ||
22 | shell/ash_test/ash-misc/control_char3.tests | 2 ++ | ||
23 | shell/ash_test/ash-misc/control_char4.right | 1 + | ||
24 | shell/ash_test/ash-misc/control_char4.tests | 2 ++ | ||
25 | shell/hush.c | 11 +++++++++++ | ||
26 | shell/hush_test/hush-misc/control_char3.right | 1 + | ||
27 | shell/hush_test/hush-misc/control_char3.tests | 2 ++ | ||
28 | shell/hush_test/hush-misc/control_char4.right | 1 + | ||
29 | shell/hush_test/hush-misc/control_char4.tests | 2 ++ | ||
30 | 9 files changed, 23 insertions(+) | ||
31 | create mode 100644 shell/ash_test/ash-misc/control_char3.right | ||
32 | create mode 100755 shell/ash_test/ash-misc/control_char3.tests | ||
33 | create mode 100644 shell/ash_test/ash-misc/control_char4.right | ||
34 | create mode 100755 shell/ash_test/ash-misc/control_char4.tests | ||
35 | create mode 100644 shell/hush_test/hush-misc/control_char3.right | ||
36 | create mode 100755 shell/hush_test/hush-misc/control_char3.tests | ||
37 | create mode 100644 shell/hush_test/hush-misc/control_char4.right | ||
38 | create mode 100755 shell/hush_test/hush-misc/control_char4.tests | ||
39 | |||
40 | diff --git a/shell/ash_test/ash-misc/control_char3.right b/shell/ash_test/ash-misc/control_char3.right | ||
41 | new file mode 100644 | ||
42 | index 000000000..283e02cbb | ||
43 | --- /dev/null | ||
44 | +++ b/shell/ash_test/ash-misc/control_char3.right | ||
45 | @@ -0,0 +1 @@ | ||
46 | +SHELL: line 1: : not found | ||
47 | diff --git a/shell/ash_test/ash-misc/control_char3.tests b/shell/ash_test/ash-misc/control_char3.tests | ||
48 | new file mode 100755 | ||
49 | index 000000000..4359db3f3 | ||
50 | --- /dev/null | ||
51 | +++ b/shell/ash_test/ash-misc/control_char3.tests | ||
52 | @@ -0,0 +1,2 @@ | ||
53 | +# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) | ||
54 | +$THIS_SH -c '\' SHELL | ||
55 | diff --git a/shell/ash_test/ash-misc/control_char4.right b/shell/ash_test/ash-misc/control_char4.right | ||
56 | new file mode 100644 | ||
57 | index 000000000..2bf18e684 | ||
58 | --- /dev/null | ||
59 | +++ b/shell/ash_test/ash-misc/control_char4.right | ||
60 | @@ -0,0 +1 @@ | ||
61 | +SHELL: line 1: -: not found | ||
62 | diff --git a/shell/ash_test/ash-misc/control_char4.tests b/shell/ash_test/ash-misc/control_char4.tests | ||
63 | new file mode 100755 | ||
64 | index 000000000..48010f154 | ||
65 | --- /dev/null | ||
66 | +++ b/shell/ash_test/ash-misc/control_char4.tests | ||
67 | @@ -0,0 +1,2 @@ | ||
68 | +# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) | ||
69 | +$THIS_SH -c '"-"' SHELL | ||
70 | diff --git a/shell/hush.c b/shell/hush.c | ||
71 | index 9fead37da..249728b9d 100644 | ||
72 | --- a/shell/hush.c | ||
73 | +++ b/shell/hush.c | ||
74 | @@ -5235,6 +5235,11 @@ static int encode_string(o_string *as_string, | ||
75 | } | ||
76 | #endif | ||
77 | o_addQchr(dest, ch); | ||
78 | + if (ch == SPECIAL_VAR_SYMBOL) { | ||
79 | + /* Convert "^C" to corresponding special variable reference */ | ||
80 | + o_addchr(dest, SPECIAL_VAR_QUOTED_SVS); | ||
81 | + o_addchr(dest, SPECIAL_VAR_SYMBOL); | ||
82 | + } | ||
83 | goto again; | ||
84 | #undef as_string | ||
85 | } | ||
86 | @@ -5346,6 +5351,11 @@ static struct pipe *parse_stream(char **pstring, | ||
87 | if (ch == '\n') | ||
88 | continue; /* drop \<newline>, get next char */ | ||
89 | nommu_addchr(&ctx.as_string, '\\'); | ||
90 | + if (ch == SPECIAL_VAR_SYMBOL) { | ||
91 | + nommu_addchr(&ctx.as_string, ch); | ||
92 | + /* Convert \^C to corresponding special variable reference */ | ||
93 | + goto case_SPECIAL_VAR_SYMBOL; | ||
94 | + } | ||
95 | o_addchr(&ctx.word, '\\'); | ||
96 | if (ch == EOF) { | ||
97 | /* Testcase: eval 'echo Ok\' */ | ||
98 | @@ -5670,6 +5680,7 @@ static struct pipe *parse_stream(char **pstring, | ||
99 | /* Note: nommu_addchr(&ctx.as_string, ch) is already done */ | ||
100 | |||
101 | switch (ch) { | ||
102 | + case_SPECIAL_VAR_SYMBOL: | ||
103 | case SPECIAL_VAR_SYMBOL: | ||
104 | /* Convert raw ^C to corresponding special variable reference */ | ||
105 | o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); | ||
106 | diff --git a/shell/hush_test/hush-misc/control_char3.right b/shell/hush_test/hush-misc/control_char3.right | ||
107 | new file mode 100644 | ||
108 | index 000000000..94b4f8699 | ||
109 | --- /dev/null | ||
110 | +++ b/shell/hush_test/hush-misc/control_char3.right | ||
111 | @@ -0,0 +1 @@ | ||
112 | +hush: can't execute '': No such file or directory | ||
113 | diff --git a/shell/hush_test/hush-misc/control_char3.tests b/shell/hush_test/hush-misc/control_char3.tests | ||
114 | new file mode 100755 | ||
115 | index 000000000..4359db3f3 | ||
116 | --- /dev/null | ||
117 | +++ b/shell/hush_test/hush-misc/control_char3.tests | ||
118 | @@ -0,0 +1,2 @@ | ||
119 | +# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) | ||
120 | +$THIS_SH -c '\' SHELL | ||
121 | diff --git a/shell/hush_test/hush-misc/control_char4.right b/shell/hush_test/hush-misc/control_char4.right | ||
122 | new file mode 100644 | ||
123 | index 000000000..698e21427 | ||
124 | --- /dev/null | ||
125 | +++ b/shell/hush_test/hush-misc/control_char4.right | ||
126 | @@ -0,0 +1 @@ | ||
127 | +hush: can't execute '-': No such file or directory | ||
128 | diff --git a/shell/hush_test/hush-misc/control_char4.tests b/shell/hush_test/hush-misc/control_char4.tests | ||
129 | new file mode 100755 | ||
130 | index 000000000..48010f154 | ||
131 | --- /dev/null | ||
132 | +++ b/shell/hush_test/hush-misc/control_char4.tests | ||
133 | @@ -0,0 +1,2 @@ | ||
134 | +# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages) | ||
135 | +$THIS_SH -c '"-"' SHELL | ||
136 | -- | ||
137 | cgit v1.2.3 | ||
138 | |||
diff --git a/meta/recipes-core/busybox/busybox/CVE-2022-48174.patch b/meta/recipes-core/busybox/busybox/CVE-2022-48174.patch new file mode 100644 index 0000000000..dfba2a7e0f --- /dev/null +++ b/meta/recipes-core/busybox/busybox/CVE-2022-48174.patch | |||
@@ -0,0 +1,82 @@ | |||
1 | From c18ebf861528ef24958dd99a146482d2a40014c7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | Date: Mon, 12 Jun 2023 17:48:47 +0200 | ||
4 | Subject: [PATCH] shell: avoid segfault on ${0::0/0~09J}. Closes 15216 | ||
5 | |||
6 | function old new delta | ||
7 | evaluate_string 1011 1053 +42 | ||
8 | |||
9 | CVE: CVE-2022-48174 | ||
10 | Upstream-Status: Backport [d417193cf37ca1005830d7e16f5fa7e1d8a44209] | ||
11 | Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> | ||
12 | --- | ||
13 | shell/math.c | 39 +++++++++++++++++++++++++++++++++++---- | ||
14 | 1 file changed, 35 insertions(+), 4 deletions(-) | ||
15 | |||
16 | diff --git a/shell/math.c b/shell/math.c | ||
17 | index af1ab55c0..79824e81f 100644 | ||
18 | --- a/shell/math.c | ||
19 | +++ b/shell/math.c | ||
20 | @@ -578,6 +578,28 @@ static arith_t strto_arith_t(const char *nptr, char **endptr) | ||
21 | # endif | ||
22 | #endif | ||
23 | |||
24 | +//TODO: much better estimation than expr_len/2? Such as: | ||
25 | +//static unsigned estimate_nums_and_names(const char *expr) | ||
26 | +//{ | ||
27 | +// unsigned count = 0; | ||
28 | +// while (*(expr = skip_whitespace(expr)) != '\0') { | ||
29 | +// const char *p; | ||
30 | +// if (isdigit(*expr)) { | ||
31 | +// while (isdigit(*++expr)) | ||
32 | +// continue; | ||
33 | +// count++; | ||
34 | +// continue; | ||
35 | +// } | ||
36 | +// p = endofname(expr); | ||
37 | +// if (p != expr) { | ||
38 | +// expr = p; | ||
39 | +// count++; | ||
40 | +// continue; | ||
41 | +// } | ||
42 | +// } | ||
43 | +// return count; | ||
44 | +//} | ||
45 | + | ||
46 | static arith_t FAST_FUNC | ||
47 | evaluate_string(arith_state_t *math_state, const char *expr) | ||
48 | { | ||
49 | @@ -585,10 +607,12 @@ evaluate_string(arith_state_t *math_state, const char *expr) | ||
50 | const char *errmsg; | ||
51 | const char *start_expr = expr = skip_whitespace(expr); | ||
52 | unsigned expr_len = strlen(expr) + 2; | ||
53 | - /* Stack of integers */ | ||
54 | - /* The proof that there can be no more than strlen(startbuf)/2+1 | ||
55 | - * integers in any given correct or incorrect expression | ||
56 | - * is left as an exercise to the reader. */ | ||
57 | + /* Stack of integers/names */ | ||
58 | + /* There can be no more than strlen(startbuf)/2+1 | ||
59 | + * integers/names in any given correct or incorrect expression. | ||
60 | + * (modulo "09v09v09v09v09v" case, | ||
61 | + * but we have code to detect that early) | ||
62 | + */ | ||
63 | var_or_num_t *const numstack = alloca((expr_len / 2) * sizeof(numstack[0])); | ||
64 | var_or_num_t *numstackptr = numstack; | ||
65 | /* Stack of operator tokens */ | ||
66 | @@ -657,6 +681,13 @@ evaluate_string(arith_state_t *math_state, const char *expr) | ||
67 | numstackptr->var = NULL; | ||
68 | errno = 0; | ||
69 | numstackptr->val = strto_arith_t(expr, (char**) &expr); | ||
70 | + /* A number can't be followed by another number, or a variable name. | ||
71 | + * We'd catch this later anyway, but this would require numstack[] | ||
72 | + * to be twice as deep to handle strings where _every_ char is | ||
73 | + * a new number or name. Example: 09v09v09v09v09v09v09v09v09v | ||
74 | + */ | ||
75 | + if (isalnum(*expr) || *expr == '_') | ||
76 | + goto err; | ||
77 | if (errno) | ||
78 | numstackptr->val = 0; /* bash compat */ | ||
79 | goto num; | ||
80 | -- | ||
81 | 2.40.1 | ||
82 | |||
diff --git a/meta/recipes-core/busybox/busybox_1.31.1.bb b/meta/recipes-core/busybox/busybox_1.31.1.bb index 7563368287..94aa1467df 100644 --- a/meta/recipes-core/busybox/busybox_1.31.1.bb +++ b/meta/recipes-core/busybox/busybox_1.31.1.bb | |||
@@ -50,7 +50,15 @@ SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \ | |||
50 | file://0001-sysctl-ignore-EIO-of-stable_secret-below-proc-sys-ne.patch \ | 50 | file://0001-sysctl-ignore-EIO-of-stable_secret-below-proc-sys-ne.patch \ |
51 | file://busybox-CVE-2018-1000500.patch \ | 51 | file://busybox-CVE-2018-1000500.patch \ |
52 | file://0001-hwclock-make-glibc-2.31-compatible.patch \ | 52 | file://0001-hwclock-make-glibc-2.31-compatible.patch \ |
53 | " | 53 | file://0001-decompress_gunzip-Fix-DoS-if-gzip-is-corrupt.patch \ |
54 | file://0001-mktemp-add-tmpdir-option.patch \ | ||
55 | file://CVE-2021-42374.patch \ | ||
56 | file://CVE-2021-42376.patch \ | ||
57 | file://CVE-2021-423xx-awk.patch \ | ||
58 | file://CVE-2022-48174.patch \ | ||
59 | file://0001-libbb-sockaddr2str-ensure-only-printable-characters-.patch \ | ||
60 | file://0002-nslookup-sanitize-all-printed-strings-with-printable.patch \ | ||
61 | " | ||
54 | SRC_URI_append_libc-musl = " file://musl.cfg " | 62 | SRC_URI_append_libc-musl = " file://musl.cfg " |
55 | 63 | ||
56 | SRC_URI[tarball.md5sum] = "70913edaf2263a157393af07565c17f0" | 64 | SRC_URI[tarball.md5sum] = "70913edaf2263a157393af07565c17f0" |
diff --git a/meta/recipes-core/busybox/files/CVE-2021-423xx-awk.patch b/meta/recipes-core/busybox/files/CVE-2021-423xx-awk.patch new file mode 100644 index 0000000000..7e3d47b88c --- /dev/null +++ b/meta/recipes-core/busybox/files/CVE-2021-423xx-awk.patch | |||
@@ -0,0 +1,215 @@ | |||
1 | From a21708eb8d07b4a6dbc1d3e4ace4c5721515a84c Mon Sep 17 00:00:00 2001 | ||
2 | From: Sana Kazi <Sana.Kazi@kpit.com> | ||
3 | Date: Wed, 8 Dec 2021 12:25:34 +0530 | ||
4 | Subject: [PATCH] busybox: Fix multiple security issues in awk | ||
5 | |||
6 | Description: fix multiple security issues in awk | ||
7 | Origin: backported awk.c from busybox 1.34.1 | ||
8 | |||
9 | CVE: CVE-2021-42378 | ||
10 | CVE: CVE-2021-42379 | ||
11 | CVE: CVE-2021-42380 | ||
12 | CVE: CVE-2021-42381 | ||
13 | CVE: CVE-2021-42382 | ||
14 | CVE: CVE-2021-42384 | ||
15 | CVE: CVE-2021-42385 | ||
16 | CVE: CVE-2021-42386 | ||
17 | |||
18 | Upstream-Status: Backport [https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/busybox/1:1.30.1-6ubuntu3.1/busybox_1.30.1-6ubuntu3.1.debian.tar.xz] | ||
19 | |||
20 | Comment: Refreshed first hunk and removed few hunks as they are already present in source. | ||
21 | |||
22 | Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com> | ||
23 | Signed-off-by: Ranjitsinh Rathod <Ranjitsinh.Rathod@kpit.com> | ||
24 | |||
25 | --- | ||
26 | editors/awk.c | 80 ++++++++++++++++++++++++++++++++++++++------------- | ||
27 | 1 file changed, 60 insertions(+), 20 deletions(-) | ||
28 | |||
29 | diff --git a/editors/awk.c b/editors/awk.c | ||
30 | index d25508e..4e4f282 100644 | ||
31 | --- a/editors/awk.c | ||
32 | +++ b/editors/awk.c | ||
33 | @@ -272,7 +272,8 @@ typedef struct tsplitter_s { | ||
34 | /* if previous token class is CONCAT1 and next is CONCAT2, concatenation */ | ||
35 | /* operator is inserted between them */ | ||
36 | #define TC_CONCAT1 (TC_VARIABLE | TC_ARRTERM | TC_SEQTERM \ | ||
37 | - | TC_STRING | TC_NUMBER | TC_UOPPOST) | ||
38 | + | TC_STRING | TC_NUMBER | TC_UOPPOST \ | ||
39 | + | TC_LENGTH) | ||
40 | #define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE) | ||
41 | |||
42 | #define OF_RES1 0x010000 | ||
43 | @@ -404,7 +405,7 @@ static const char tokenlist[] ALIGN1 = | ||
44 | |||
45 | #define OC_B OC_BUILTIN | ||
46 | |||
47 | -static const uint32_t tokeninfo[] = { | ||
48 | +static const uint32_t tokeninfo[] ALIGN4 = { | ||
49 | 0, | ||
50 | 0, | ||
51 | OC_REGEXP, | ||
52 | @@ -1070,8 +1071,10 @@ static uint32_t next_token(uint32_t expected) | ||
53 | const uint32_t *ti; | ||
54 | |||
55 | if (t_rollback) { | ||
56 | + debug_printf_parse("%s: using rolled-back token\n", __func__); | ||
57 | t_rollback = FALSE; | ||
58 | } else if (concat_inserted) { | ||
59 | + debug_printf_parse("%s: using concat-inserted token\n", __func__); | ||
60 | concat_inserted = FALSE; | ||
61 | t_tclass = save_tclass; | ||
62 | t_info = save_info; | ||
63 | @@ -1200,7 +1203,11 @@ static uint32_t next_token(uint32_t expected) | ||
64 | goto readnext; | ||
65 | |||
66 | /* insert concatenation operator when needed */ | ||
67 | - if ((ltclass & TC_CONCAT1) && (tc & TC_CONCAT2) && (expected & TC_BINOP)) { | ||
68 | + debug_printf_parse("%s: %x %x %x concat_inserted?\n", __func__, | ||
69 | + (ltclass & TC_CONCAT1), (tc & TC_CONCAT2), (expected & TC_BINOP)); | ||
70 | + if ((ltclass & TC_CONCAT1) && (tc & TC_CONCAT2) && (expected & TC_BINOP) | ||
71 | + && !(ltclass == TC_LENGTH && tc == TC_SEQSTART) /* but not for "length(..." */ | ||
72 | + ) { | ||
73 | concat_inserted = TRUE; | ||
74 | save_tclass = tc; | ||
75 | save_info = t_info; | ||
76 | @@ -1208,6 +1215,7 @@ static uint32_t next_token(uint32_t expected) | ||
77 | t_info = OC_CONCAT | SS | P(35); | ||
78 | } | ||
79 | |||
80 | + debug_printf_parse("%s: t_tclass=tc=%x\n", __func__, t_tclass); | ||
81 | t_tclass = tc; | ||
82 | } | ||
83 | ltclass = t_tclass; | ||
84 | @@ -1218,6 +1226,7 @@ static uint32_t next_token(uint32_t expected) | ||
85 | EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN); | ||
86 | } | ||
87 | |||
88 | + debug_printf_parse("%s: returning, ltclass:%x t_double:%f\n", __func__, ltclass, t_double); | ||
89 | return ltclass; | ||
90 | #undef concat_inserted | ||
91 | #undef save_tclass | ||
92 | @@ -1282,7 +1291,7 @@ static node *parse_expr(uint32_t iexp) | ||
93 | glptr = NULL; | ||
94 | |||
95 | } else if (tc & (TC_BINOP | TC_UOPPOST)) { | ||
96 | - debug_printf_parse("%s: TC_BINOP | TC_UOPPOST\n", __func__); | ||
97 | + debug_printf_parse("%s: TC_BINOP | TC_UOPPOST tc:%x\n", __func__, tc); | ||
98 | /* for binary and postfix-unary operators, jump back over | ||
99 | * previous operators with higher priority */ | ||
100 | vn = cn; | ||
101 | @@ -1350,8 +1359,10 @@ static node *parse_expr(uint32_t iexp) | ||
102 | v = cn->l.v = xzalloc(sizeof(var)); | ||
103 | if (tc & TC_NUMBER) | ||
104 | setvar_i(v, t_double); | ||
105 | - else | ||
106 | + else { | ||
107 | setvar_s(v, t_string); | ||
108 | + xtc &= ~TC_UOPPOST; /* "str"++ is not allowed */ | ||
109 | + } | ||
110 | break; | ||
111 | |||
112 | case TC_REGEXP: | ||
113 | @@ -1387,7 +1398,12 @@ static node *parse_expr(uint32_t iexp) | ||
114 | |||
115 | case TC_LENGTH: | ||
116 | debug_printf_parse("%s: TC_LENGTH\n", __func__); | ||
117 | - next_token(TC_SEQSTART | TC_OPTERM | TC_GRPTERM); | ||
118 | + next_token(TC_SEQSTART /* length(...) */ | ||
119 | + | TC_OPTERM /* length; (or newline)*/ | ||
120 | + | TC_GRPTERM /* length } */ | ||
121 | + | TC_BINOPX /* length <op> NUM */ | ||
122 | + | TC_COMMA /* print length, 1 */ | ||
123 | + ); | ||
124 | rollback_token(); | ||
125 | if (t_tclass & TC_SEQSTART) { | ||
126 | /* It was a "(" token. Handle just like TC_BUILTIN */ | ||
127 | @@ -1747,12 +1763,34 @@ static void fsrealloc(int size) | ||
128 | nfields = size; | ||
129 | } | ||
130 | |||
131 | +static int regexec1_nonempty(const regex_t *preg, const char *s, regmatch_t pmatch[]) | ||
132 | +{ | ||
133 | + int r = regexec(preg, s, 1, pmatch, 0); | ||
134 | + if (r == 0 && pmatch[0].rm_eo == 0) { | ||
135 | + /* For example, happens when FS can match | ||
136 | + * an empty string (awk -F ' *'). Logically, | ||
137 | + * this should split into one-char fields. | ||
138 | + * However, gawk 5.0.1 searches for first | ||
139 | + * _non-empty_ separator string match: | ||
140 | + */ | ||
141 | + size_t ofs = 0; | ||
142 | + do { | ||
143 | + ofs++; | ||
144 | + if (!s[ofs]) | ||
145 | + return REG_NOMATCH; | ||
146 | + regexec(preg, s + ofs, 1, pmatch, 0); | ||
147 | + } while (pmatch[0].rm_eo == 0); | ||
148 | + pmatch[0].rm_so += ofs; | ||
149 | + pmatch[0].rm_eo += ofs; | ||
150 | + } | ||
151 | + return r; | ||
152 | +} | ||
153 | + | ||
154 | static int awk_split(const char *s, node *spl, char **slist) | ||
155 | { | ||
156 | - int l, n; | ||
157 | + int n; | ||
158 | char c[4]; | ||
159 | char *s1; | ||
160 | - regmatch_t pmatch[2]; // TODO: why [2]? [1] is enough... | ||
161 | |||
162 | /* in worst case, each char would be a separate field */ | ||
163 | *slist = s1 = xzalloc(strlen(s) * 2 + 3); | ||
164 | @@ -1769,29 +1807,31 @@ static int awk_split(const char *s, node *spl, char **slist) | ||
165 | return n; /* "": zero fields */ | ||
166 | n++; /* at least one field will be there */ | ||
167 | do { | ||
168 | + int l; | ||
169 | + regmatch_t pmatch[2]; // TODO: why [2]? [1] is enough... | ||
170 | + | ||
171 | l = strcspn(s, c+2); /* len till next NUL or \n */ | ||
172 | - if (regexec(icase ? spl->r.ire : spl->l.re, s, 1, pmatch, 0) == 0 | ||
173 | + if (regexec1_nonempty(icase ? spl->r.ire : spl->l.re, s, pmatch) == 0 | ||
174 | && pmatch[0].rm_so <= l | ||
175 | ) { | ||
176 | + /* if (pmatch[0].rm_eo == 0) ... - impossible */ | ||
177 | l = pmatch[0].rm_so; | ||
178 | - if (pmatch[0].rm_eo == 0) { | ||
179 | - l++; | ||
180 | - pmatch[0].rm_eo++; | ||
181 | - } | ||
182 | n++; /* we saw yet another delimiter */ | ||
183 | } else { | ||
184 | pmatch[0].rm_eo = l; | ||
185 | if (s[l]) | ||
186 | pmatch[0].rm_eo++; | ||
187 | } | ||
188 | - memcpy(s1, s, l); | ||
189 | - /* make sure we remove *all* of the separator chars */ | ||
190 | - do { | ||
191 | - s1[l] = '\0'; | ||
192 | - } while (++l < pmatch[0].rm_eo); | ||
193 | - nextword(&s1); | ||
194 | + s1 = mempcpy(s1, s, l); | ||
195 | + *s1++ = '\0'; | ||
196 | s += pmatch[0].rm_eo; | ||
197 | } while (*s); | ||
198 | + | ||
199 | + /* echo a-- | awk -F-- '{ print NF, length($NF), $NF }' | ||
200 | + * should print "2 0 ": | ||
201 | + */ | ||
202 | + *s1 = '\0'; | ||
203 | + | ||
204 | return n; | ||
205 | } | ||
206 | if (c[0] == '\0') { /* null split */ | ||
207 | @@ -1995,7 +2035,7 @@ static int ptest(node *pattern) | ||
208 | static int awk_getline(rstream *rsm, var *v) | ||
209 | { | ||
210 | char *b; | ||
211 | - regmatch_t pmatch[2]; | ||
212 | + regmatch_t pmatch[2]; // TODO: why [2]? [1] is enough... | ||
213 | int size, a, p, pp = 0; | ||
214 | int fd, so, eo, r, rp; | ||
215 | char c, *m, *s; | ||