mirror of
https://git.yoctoproject.org/poky
synced 2026-06-02 13:29:49 +00:00
busybox: Fix multiple security issues in awk
CVE-2021-423xx-awk.patch fixes below listed CVEs for busybox: CVE-2021-42378, CVE-2021-42379, CVE-2021-42380, CVE-2021-42381, CVE-2021-42382, CVE-2021-42384, CVE-2021-42385, CVE-2021-42386 (From OE-Core rev: 37a92e6d4399cdb36d24b988d77aa41b1e205a90) Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com> Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> Signed-off-by: Ranjitsinh Rathod <ranjitsinhrathod1991@gmail.com> Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
22767ef398
commit
8967fcbcc4
@@ -54,6 +54,7 @@ SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \
|
|||||||
file://0001-mktemp-add-tmpdir-option.patch \
|
file://0001-mktemp-add-tmpdir-option.patch \
|
||||||
file://CVE-2021-42374.patch \
|
file://CVE-2021-42374.patch \
|
||||||
file://CVE-2021-42376.patch \
|
file://CVE-2021-42376.patch \
|
||||||
|
file://CVE-2021-423xx-awk.patch \
|
||||||
"
|
"
|
||||||
SRC_URI_append_libc-musl = " file://musl.cfg "
|
SRC_URI_append_libc-musl = " file://musl.cfg "
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,215 @@
|
|||||||
|
From a21708eb8d07b4a6dbc1d3e4ace4c5721515a84c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sana Kazi <Sana.Kazi@kpit.com>
|
||||||
|
Date: Wed, 8 Dec 2021 12:25:34 +0530
|
||||||
|
Subject: [PATCH] busybox: Fix multiple security issues in awk
|
||||||
|
|
||||||
|
Description: fix multiple security issues in awk
|
||||||
|
Origin: backported awk.c from busybox 1.34.1
|
||||||
|
|
||||||
|
CVE: CVE-2021-42378
|
||||||
|
CVE: CVE-2021-42379
|
||||||
|
CVE: CVE-2021-42380
|
||||||
|
CVE: CVE-2021-42381
|
||||||
|
CVE: CVE-2021-42382
|
||||||
|
CVE: CVE-2021-42384
|
||||||
|
CVE: CVE-2021-42385
|
||||||
|
CVE: CVE-2021-42386
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
Comment: Refreshed first hunk and removed few hunks as they are already present in source.
|
||||||
|
|
||||||
|
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
|
||||||
|
Signed-off-by: Ranjitsinh Rathod <Ranjitsinh.Rathod@kpit.com>
|
||||||
|
|
||||||
|
---
|
||||||
|
editors/awk.c | 80 ++++++++++++++++++++++++++++++++++++++-------------
|
||||||
|
1 file changed, 60 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/editors/awk.c b/editors/awk.c
|
||||||
|
index d25508e..4e4f282 100644
|
||||||
|
--- a/editors/awk.c
|
||||||
|
+++ b/editors/awk.c
|
||||||
|
@@ -272,7 +272,8 @@ typedef struct tsplitter_s {
|
||||||
|
/* if previous token class is CONCAT1 and next is CONCAT2, concatenation */
|
||||||
|
/* operator is inserted between them */
|
||||||
|
#define TC_CONCAT1 (TC_VARIABLE | TC_ARRTERM | TC_SEQTERM \
|
||||||
|
- | TC_STRING | TC_NUMBER | TC_UOPPOST)
|
||||||
|
+ | TC_STRING | TC_NUMBER | TC_UOPPOST \
|
||||||
|
+ | TC_LENGTH)
|
||||||
|
#define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE)
|
||||||
|
|
||||||
|
#define OF_RES1 0x010000
|
||||||
|
@@ -404,7 +405,7 @@ static const char tokenlist[] ALIGN1 =
|
||||||
|
|
||||||
|
#define OC_B OC_BUILTIN
|
||||||
|
|
||||||
|
-static const uint32_t tokeninfo[] = {
|
||||||
|
+static const uint32_t tokeninfo[] ALIGN4 = {
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
OC_REGEXP,
|
||||||
|
@@ -1070,8 +1071,10 @@ static uint32_t next_token(uint32_t expected)
|
||||||
|
const uint32_t *ti;
|
||||||
|
|
||||||
|
if (t_rollback) {
|
||||||
|
+ debug_printf_parse("%s: using rolled-back token\n", __func__);
|
||||||
|
t_rollback = FALSE;
|
||||||
|
} else if (concat_inserted) {
|
||||||
|
+ debug_printf_parse("%s: using concat-inserted token\n", __func__);
|
||||||
|
concat_inserted = FALSE;
|
||||||
|
t_tclass = save_tclass;
|
||||||
|
t_info = save_info;
|
||||||
|
@@ -1200,7 +1203,11 @@ static uint32_t next_token(uint32_t expected)
|
||||||
|
goto readnext;
|
||||||
|
|
||||||
|
/* insert concatenation operator when needed */
|
||||||
|
- if ((ltclass & TC_CONCAT1) && (tc & TC_CONCAT2) && (expected & TC_BINOP)) {
|
||||||
|
+ debug_printf_parse("%s: %x %x %x concat_inserted?\n", __func__,
|
||||||
|
+ (ltclass & TC_CONCAT1), (tc & TC_CONCAT2), (expected & TC_BINOP));
|
||||||
|
+ if ((ltclass & TC_CONCAT1) && (tc & TC_CONCAT2) && (expected & TC_BINOP)
|
||||||
|
+ && !(ltclass == TC_LENGTH && tc == TC_SEQSTART) /* but not for "length(..." */
|
||||||
|
+ ) {
|
||||||
|
concat_inserted = TRUE;
|
||||||
|
save_tclass = tc;
|
||||||
|
save_info = t_info;
|
||||||
|
@@ -1208,6 +1215,7 @@ static uint32_t next_token(uint32_t expected)
|
||||||
|
t_info = OC_CONCAT | SS | P(35);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ debug_printf_parse("%s: t_tclass=tc=%x\n", __func__, t_tclass);
|
||||||
|
t_tclass = tc;
|
||||||
|
}
|
||||||
|
ltclass = t_tclass;
|
||||||
|
@@ -1218,6 +1226,7 @@ static uint32_t next_token(uint32_t expected)
|
||||||
|
EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ debug_printf_parse("%s: returning, ltclass:%x t_double:%f\n", __func__, ltclass, t_double);
|
||||||
|
return ltclass;
|
||||||
|
#undef concat_inserted
|
||||||
|
#undef save_tclass
|
||||||
|
@@ -1282,7 +1291,7 @@ static node *parse_expr(uint32_t iexp)
|
||||||
|
glptr = NULL;
|
||||||
|
|
||||||
|
} else if (tc & (TC_BINOP | TC_UOPPOST)) {
|
||||||
|
- debug_printf_parse("%s: TC_BINOP | TC_UOPPOST\n", __func__);
|
||||||
|
+ debug_printf_parse("%s: TC_BINOP | TC_UOPPOST tc:%x\n", __func__, tc);
|
||||||
|
/* for binary and postfix-unary operators, jump back over
|
||||||
|
* previous operators with higher priority */
|
||||||
|
vn = cn;
|
||||||
|
@@ -1350,8 +1359,10 @@ static node *parse_expr(uint32_t iexp)
|
||||||
|
v = cn->l.v = xzalloc(sizeof(var));
|
||||||
|
if (tc & TC_NUMBER)
|
||||||
|
setvar_i(v, t_double);
|
||||||
|
- else
|
||||||
|
+ else {
|
||||||
|
setvar_s(v, t_string);
|
||||||
|
+ xtc &= ~TC_UOPPOST; /* "str"++ is not allowed */
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TC_REGEXP:
|
||||||
|
@@ -1387,7 +1398,12 @@ static node *parse_expr(uint32_t iexp)
|
||||||
|
|
||||||
|
case TC_LENGTH:
|
||||||
|
debug_printf_parse("%s: TC_LENGTH\n", __func__);
|
||||||
|
- next_token(TC_SEQSTART | TC_OPTERM | TC_GRPTERM);
|
||||||
|
+ next_token(TC_SEQSTART /* length(...) */
|
||||||
|
+ | TC_OPTERM /* length; (or newline)*/
|
||||||
|
+ | TC_GRPTERM /* length } */
|
||||||
|
+ | TC_BINOPX /* length <op> NUM */
|
||||||
|
+ | TC_COMMA /* print length, 1 */
|
||||||
|
+ );
|
||||||
|
rollback_token();
|
||||||
|
if (t_tclass & TC_SEQSTART) {
|
||||||
|
/* It was a "(" token. Handle just like TC_BUILTIN */
|
||||||
|
@@ -1747,12 +1763,34 @@ static void fsrealloc(int size)
|
||||||
|
nfields = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int regexec1_nonempty(const regex_t *preg, const char *s, regmatch_t pmatch[])
|
||||||
|
+{
|
||||||
|
+ int r = regexec(preg, s, 1, pmatch, 0);
|
||||||
|
+ if (r == 0 && pmatch[0].rm_eo == 0) {
|
||||||
|
+ /* For example, happens when FS can match
|
||||||
|
+ * an empty string (awk -F ' *'). Logically,
|
||||||
|
+ * this should split into one-char fields.
|
||||||
|
+ * However, gawk 5.0.1 searches for first
|
||||||
|
+ * _non-empty_ separator string match:
|
||||||
|
+ */
|
||||||
|
+ size_t ofs = 0;
|
||||||
|
+ do {
|
||||||
|
+ ofs++;
|
||||||
|
+ if (!s[ofs])
|
||||||
|
+ return REG_NOMATCH;
|
||||||
|
+ regexec(preg, s + ofs, 1, pmatch, 0);
|
||||||
|
+ } while (pmatch[0].rm_eo == 0);
|
||||||
|
+ pmatch[0].rm_so += ofs;
|
||||||
|
+ pmatch[0].rm_eo += ofs;
|
||||||
|
+ }
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int awk_split(const char *s, node *spl, char **slist)
|
||||||
|
{
|
||||||
|
- int l, n;
|
||||||
|
+ int n;
|
||||||
|
char c[4];
|
||||||
|
char *s1;
|
||||||
|
- regmatch_t pmatch[2]; // TODO: why [2]? [1] is enough...
|
||||||
|
|
||||||
|
/* in worst case, each char would be a separate field */
|
||||||
|
*slist = s1 = xzalloc(strlen(s) * 2 + 3);
|
||||||
|
@@ -1769,29 +1807,31 @@ static int awk_split(const char *s, node *spl, char **slist)
|
||||||
|
return n; /* "": zero fields */
|
||||||
|
n++; /* at least one field will be there */
|
||||||
|
do {
|
||||||
|
+ int l;
|
||||||
|
+ regmatch_t pmatch[2]; // TODO: why [2]? [1] is enough...
|
||||||
|
+
|
||||||
|
l = strcspn(s, c+2); /* len till next NUL or \n */
|
||||||
|
- if (regexec(icase ? spl->r.ire : spl->l.re, s, 1, pmatch, 0) == 0
|
||||||
|
+ if (regexec1_nonempty(icase ? spl->r.ire : spl->l.re, s, pmatch) == 0
|
||||||
|
&& pmatch[0].rm_so <= l
|
||||||
|
) {
|
||||||
|
+ /* if (pmatch[0].rm_eo == 0) ... - impossible */
|
||||||
|
l = pmatch[0].rm_so;
|
||||||
|
- if (pmatch[0].rm_eo == 0) {
|
||||||
|
- l++;
|
||||||
|
- pmatch[0].rm_eo++;
|
||||||
|
- }
|
||||||
|
n++; /* we saw yet another delimiter */
|
||||||
|
} else {
|
||||||
|
pmatch[0].rm_eo = l;
|
||||||
|
if (s[l])
|
||||||
|
pmatch[0].rm_eo++;
|
||||||
|
}
|
||||||
|
- memcpy(s1, s, l);
|
||||||
|
- /* make sure we remove *all* of the separator chars */
|
||||||
|
- do {
|
||||||
|
- s1[l] = '\0';
|
||||||
|
- } while (++l < pmatch[0].rm_eo);
|
||||||
|
- nextword(&s1);
|
||||||
|
+ s1 = mempcpy(s1, s, l);
|
||||||
|
+ *s1++ = '\0';
|
||||||
|
s += pmatch[0].rm_eo;
|
||||||
|
} while (*s);
|
||||||
|
+
|
||||||
|
+ /* echo a-- | awk -F-- '{ print NF, length($NF), $NF }'
|
||||||
|
+ * should print "2 0 ":
|
||||||
|
+ */
|
||||||
|
+ *s1 = '\0';
|
||||||
|
+
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
if (c[0] == '\0') { /* null split */
|
||||||
|
@@ -1995,7 +2035,7 @@ static int ptest(node *pattern)
|
||||||
|
static int awk_getline(rstream *rsm, var *v)
|
||||||
|
{
|
||||||
|
char *b;
|
||||||
|
- regmatch_t pmatch[2];
|
||||||
|
+ regmatch_t pmatch[2]; // TODO: why [2]? [1] is enough...
|
||||||
|
int size, a, p, pp = 0;
|
||||||
|
int fd, so, eo, r, rp;
|
||||||
|
char c, *m, *s;
|
||||||
Reference in New Issue
Block a user