Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package busybox for openSUSE:Factory checked 
in at 2026-08-26 19:51:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/busybox (Old)
 and      /work/SRC/openSUSE:Factory/.busybox.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "busybox"

Wed Aug 26 19:51:09 2026 rev:99 rq:1373537 version:1.38.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/busybox/busybox.changes  2026-07-12 
16:20:16.250183604 +0200
+++ /work/SRC/openSUSE:Factory/.busybox.new.1258/busybox.changes        
2026-08-26 19:51:23.058785158 +0200
@@ -1,0 +2,34 @@
+Tue Aug 21 16:25:27 UTC 2026 - Radoslav Kolev <[email protected]>
+
+- Fix stack exhaustion in the ash applet caused by unbounded shell
+  function recursion (CVE-2026-38755, bsc#1271548)
+  * ash-fix-evalfun.patch
+
+-------------------------------------------------------------------
+Tue Aug 21 12:10:52 UTC 2026 - Radoslav Kolev <[email protected]>
+
+- Fix out-of-bounds read in ifsbreakup() (CVE-2026-38754, bsc#1271547)
+  * 0001-ash-fix-out-of-bounds-read-in-ifsbreakup.patch
+
+-------------------------------------------------------------------
+Tue Aug 21 11:58:15 UTC 2026 - Radoslav Kolev <[email protected]>
+
+- Fix use-after-free in the awk applet regexp processing code when
+  text replacement operations are used (CVE-2026-38753, bsc#1271545)
+  * awk-fix-use-after-free-sub.patch
+
+-------------------------------------------------------------------
+Mon Aug 20 15:14:21 UTC 2026 - Radoslav Kolev <[email protected]>
+
+- Fix stack exhaustion in the awk applet caused by unbounded
+  function call recursion (CVE-2026-38752, bsc#1271544)
+  * awk-fix-recursion.patch
+
+-------------------------------------------------------------------
+Mon Aug 20 12:20:37 UTC 2026 - Radoslav Kolev <[email protected]>
+
+- Fix heap buffer overflow in the awk applet when a regexp ends
+  with a backslash (CVE-2023-42366, bsc#1217586)
+  * 0001-awk.c-fix-CVE-2023-42366-bug-15874.patch
+
+-------------------------------------------------------------------

New:
----
  0001-ash-fix-out-of-bounds-read-in-ifsbreakup.patch
  0001-awk.c-fix-CVE-2023-42366-bug-15874.patch
  ash-fix-evalfun.patch
  awk-fix-recursion.patch
  awk-fix-use-after-free-sub.patch

----------(New B)----------
  New:- Fix out-of-bounds read in ifsbreakup() (CVE-2026-38754, bsc#1271547)
  * 0001-ash-fix-out-of-bounds-read-in-ifsbreakup.patch
  New:  with a backslash (CVE-2023-42366, bsc#1217586)
  * 0001-awk.c-fix-CVE-2023-42366-bug-15874.patch
  New:  function recursion (CVE-2026-38755, bsc#1271548)
  * ash-fix-evalfun.patch
  New:  function call recursion (CVE-2026-38752, bsc#1271544)
  * awk-fix-recursion.patch
  New:  text replacement operations are used (CVE-2026-38753, bsc#1271545)
  * awk-fix-use-after-free-sub.patch
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ busybox.spec ++++++
--- /var/tmp/diff_new_pack.Yg21mq/_old  2026-08-26 19:51:24.647841123 +0200
+++ /var/tmp/diff_new_pack.Yg21mq/_new  2026-08-26 19:51:24.649841193 +0200
@@ -49,6 +49,17 @@
 Patch6:         0001-update_passwd-Avoid-selinux_preserve_fcontext-if-SEL.patch
 # PATCH-FIX-UPSTREAM - Fix bsc#1253245 (CVE-2025-60876), submitted to mailing 
list
 Patch7:         wget-don-t-allow-control-characters-in-url.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1217586 (CVE-2023-42366), heap-buffer-overflow 
in awk next_token()
+# the patch has been submitted upstream a long time ago, but never applied
+Patch8:         0001-awk.c-fix-CVE-2023-42366-bug-15874.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1271544 (CVE-2026-38752), stack exhaustion in 
awk
+Patch9:         awk-fix-recursion.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1271545 (CVE-2026-38753), use-after-free in aw
+Patch10:        awk-fix-use-after-free-sub.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1271547 (CVE-2026-38754), out-of-bounds read in 
ash ifsbreakup(), upstream commit a448b6d5b
+Patch11:        0001-ash-fix-out-of-bounds-read-in-ifsbreakup.patch
+# PATCH-FIX-UPSTREAM - Fix bsc#1271548 (CVE-2026-38755), stack exhaustion on 
deep ash function recursion
+Patch12:        ash-fix-evalfun.patch
 
 # other patches
 Patch100:       busybox.install.patch

++++++ 0001-ash-fix-out-of-bounds-read-in-ifsbreakup.patch ++++++
>From a448b6d5b21e5b21249391389b6f0551d9bea136 Mon Sep 17 00:00:00 2001
From: Sanghyun Park <[email protected]>
Date: Thu, 18 Jun 2026 17:04:20 +0900
Subject: [PATCH] ash: fix out-of-bounds read in ifsbreakup()

ifsfree() does not only release allocated ifsregion nodes; it also clears
the global IFS region state used by ifsbreakup(). If argstr() raises an
error while expanding an argument, ash longjmps out of expandarg() before
that cleanup runs, leaving stale IFS split offsets behind.

A later expansion can reuse the stack for a shorter string. ifsbreakup()
then sees the stale IFS state, trusts the old offsets, and can walk past
the current stack block before dereferencing p.

Follow dash's root-cause fix: when an expansion-related handler catches
EXERROR and continues, restore the handler and call ifsfree(). Apply
the cleanup to redirectsafe(), expandstr(), and evaltree().

Upstream commit:

    Date:   Mon Dec 5 23:02:01 2022 +0800
    expand: Add ifsfree to expand to fix a logic error that causes a buffer 
over-read

    On Mon, Jun 20, 2022 at 02:27:10PM -0400, Alex Gorinson wrote:
    > Due to a logic error in the ifsbreakup function in expand.c if a
    > heredoc and normal command is run one after the other by means of a
    > semi-colon, when the second command drops into ifsbreakup the command
    > will be evaluated with the ifslastp/ifsfirst struct that was set when
    > the here doc was evaluated. This results in a buffer over-read that
    > can leak the program's heap, stack, and arena addresses which can be
    > used to beat ASLR.
    >
    > Steps to Reproduce:
    > First bug:
    > cmd args: ~/exampleDir/example> dash
    > $ M='AAAAAAAAAAAAAAAAA'    <note: 17 A's>
    > $ q00(){
    > $ <<000;echo
    > $ ${D?$M$M$M$M$M$M}        <note: 6 $M's>
    > $ 000
    > $ }
    > $ q00                      <note: After the q00 is typed in, the leak
    > should be echo'd out; this works with ash, busybox ash, and dash and
    > with all option args.>
    >
    > Patch:
    > Adding the following to expand.c will fix both bugs in one go.
    > (Thank you to Harald van Dijk and Michael Greenberg for doing the
    > heavy lifting for this patch!)
    > ==========================
    > --- a/src/expand.c
    > +++ b/src/expand.c
    > @@ -859,6 +859,7 @@
    > if (discard)
    > return -1;
    >
    > +ifsfree();
    > sh_error("Bad substitution");
    > }
    >
    > @@ -1739,6 +1740,7 @@
    > } else
    > msg = umsg;
    > }
    > +ifsfree();
    > sh_error("%.*s: %s%s", end - var - 1, var, msg, tail);
    >  }
    > ==========================

    Thanks for the report!

    I think it's better to add the ifsfree() call to the exception
    handling path as other sh_error calls may trigger this too.

function                                             old     new   delta
restore_handler_expandarg                              -      33     +33
evaltree                                             725     711     -14
static.redirectsafe                                  141     124     -17
expandstr                                            262     242     -20
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/3 up/down: 36/-45)            Total: -18 bytes

Signed-off-by: Sanghyun Park <[email protected]>
Signed-off-by: Denys Vlasenko <[email protected]>
---
 shell/ash.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index fb887f31b..b8ff67b16 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -5574,6 +5574,7 @@ write2pipe(int pip[2], const char *p, size_t len)
 
 /* openhere needs this forward reference */
 static void expandhere(union node *arg);
+static void ifsfree(void);
 static int
 openhere(union node *redir)
 {
@@ -5998,6 +5999,17 @@ redirect(union node *redir, int flags)
        //      preverrout_fd = copied_fd2;
 }
 
+static void
+restore_handler_expandarg(struct jmploc *savehandler, int err)
+{
+       exception_handler = savehandler;
+       if (err) {
+               if (exception_type != EXERROR)
+                       longjmp(exception_handler->loc, 1);
+               ifsfree();
+       }
+}
+
 static int
 redirectsafe(union node *redir, int flags)
 {
@@ -6013,9 +6025,7 @@ redirectsafe(union node *redir, int flags)
                exception_handler = &jmploc;
                redirect(redir, flags);
        }
-       exception_handler = savehandler;
-       if (err && exception_type != EXERROR)
-               longjmp(exception_handler->loc, 1);
+       restore_handler_expandarg(savehandler, err);
        RESTORE_INT(saveint);
        return err;
 }
@@ -9792,9 +9802,7 @@ evaltree(union node *n, int flags)
                        trap_depth--;
                        in_trap_ERR = 0;
 
-                       exception_handler = savehandler;
-                       if (err && exception_type != EXERROR)
-                               longjmp(exception_handler->loc, 1);
+                       restore_handler_expandarg(savehandler, err);
 
                        exitstatus = savestatus;
                }
@@ -14009,9 +14017,7 @@ expandstr(const char *ps, int syntax_type)
        result = stackblock();
 
 out:
-       exception_handler = savehandler;
-       if (err && exception_type != EXERROR)
-               longjmp(exception_handler->loc, 1);
+       restore_handler_expandarg(savehandler, err);
 
        doprompt = saveprompt;
        /* Try: PS1='`xxx(`' */
-- 
2.52.0


++++++ 0001-awk.c-fix-CVE-2023-42366-bug-15874.patch ++++++
>From 5cf8b332429a1dd9afef3337bae92aeddaeff993 Mon Sep 17 00:00:00 2001
From: Valery Ushakov <[email protected]>
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.
---
 editors/awk.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/editors/awk.c b/editors/awk.c
index 728ee8685..be48df7c7 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -1165,9 +1165,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;
                                }
                        }
-- 
2.34.1


++++++ ash-fix-evalfun.patch ++++++
>From sanghyun.park.cnu at gmail.com  Tue Jun 16 03:19:27 2026
From: sanghyun.park.cnu at gmail.com (Sanghyun Park)
Date: Tue, 16 Jun 2026 12:19:27 +0900
Subject: [PATCH] ash: fix stack overflow in evalfun()
Message-ID: <[email protected]>

Recursive shell functions can repeatedly enter evalfun() until the
process stack is exhausted. Track active shell function calls and raise a
normal shell error when the recursion limit is reached.

The counter is decremented through the existing funcdone cleanup path so
errors raised from inside the function body unwind it correctly.

Signed-off-by: Sanghyun Park <sanghyun.park.cnu at gmail.com>
---
 shell/ash.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/shell/ash.c b/shell/ash.c
index cda6c85..2e319cc 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -481,6 +481,7 @@ struct globals_misc {
        int shlvl;
 #define rootshell (!shlvl)
        int errlinno;
+       unsigned func_depth;
 
        char *minusc;  /* argument to -c option */
 
@@ -588,6 +589,7 @@ extern struct globals_misc *BB_GLOBAL_CONST 
ash_ptr_to_globals_misc;
 #define rootpid     (G_misc.rootpid    )
 #define shlvl       (G_misc.shlvl      )
 #define errlinno    (G_misc.errlinno   )
+#define func_depth  (G_misc.func_depth )
 #define minusc      (G_misc.minusc     )
 #define curdir      (G_misc.curdir     )
 #define physdir     (G_misc.physdir    )
@@ -10321,6 +10323,10 @@ evalfun(struct funcnode *func, int argc, char **argv, 
int flags)
        int savefuncline;
        char *savefuncname;
        char *savetrap = NULL;
+       enum { MAX_ASH_FUNC_DEPTH = 1000 };
+
+       if (func_depth >= MAX_ASH_FUNC_DEPTH)
+               ash_msg_and_raise_error("function recursion limit exceeded");
 
        if (!Eflag) {
                savetrap = trap[NTRAP_ERR];
@@ -10339,6 +10345,7 @@ evalfun(struct funcnode *func, int argc, char **argv, 
int flags)
        exception_handler = &jmploc;
        shellparam.malloced = 0;
        func->count++;
+       func_depth++;
        funcname = func->n.ndefun.text;
        funcline = func->n.ndefun.linno;
        INTON;
@@ -10360,6 +10367,7 @@ evalfun(struct funcnode *func, int argc, char **argv, 
int flags)
        }
        funcline = savefuncline;
        lineno = savelineno;
+       func_depth--;
        freefunc(func);
        freeparam(&shellparam);
        shellparam = saveparam;
-- 
2.48.1



++++++ awk-fix-recursion.patch ++++++
>From sanghyun.park.cnu at gmail.com  Tue Jun 16 03:16:05 2026
From: sanghyun.park.cnu at gmail.com (Sanghyun Park)
Date: Tue, 16 Jun 2026 12:16:05 +0900
Subject: [PATCH] awk: fix stack overflow in evaluate()
Message-ID: <[email protected]>

Recursive awk functions can keep re-entering evaluate() until the
process stack is exhausted. Track active function-call depth and report a
normal awk error once the limit is reached instead of overflowing the
stack.

Signed-off-by: Sanghyun Park <sanghyun.park.cnu at gmail.com>
---
 editors/awk.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/editors/awk.c b/editors/awk.c
index dd8f4ac..f15832b 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -633,6 +633,7 @@ struct globals {
        smalluint exitcode;
 
        unsigned evaluate__seed;
+       unsigned evaluate__func_depth;
        var *evaluate__fnargs;
        regex_t evaluate__sreg;
 
@@ -703,6 +704,7 @@ static const char EMSG_UNEXP_TOKEN[] ALIGN1 = "Unexpected 
token";
 static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero";
 static const char EMSG_INV_FMT[] ALIGN1 = "Invalid format specifier";
 static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments";
+static const char EMSG_RECURSION[] ALIGN1 = "Recursion limit exceeded";
 static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array";
 static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error";
 static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function";
@@ -2988,6 +2990,7 @@ static var *evaluate(node *op, var *res)
 #define fnargs (G.evaluate__fnargs)
 /* seed is initialized to 1 */
 #define seed   (G.evaluate__seed)
+#define func_depth (G.evaluate__func_depth)
 #define sreg   (G.evaluate__sreg)
 
        var *tmpvars;
@@ -3299,13 +3302,17 @@ static var *evaluate(node *op, var *res)
                        var *argvars, *sv_fnargs;
                        const char *sv_progname;
                        int nargs, i;
+                       enum { MAX_AWK_FUNC_DEPTH = 1000 };
 
                        debug_printf_eval("FUNC\n");
 
                        if (!op->r.f->defined)
                                syntax_error(EMSG_UNDEF_FUNC);
+                       if (func_depth >= MAX_AWK_FUNC_DEPTH)
+                               syntax_error(EMSG_RECURSION);
 
                        /* The body might be empty, still has to eval the args 
*/
+                       func_depth++;
                        nargs = op->r.f->nargs;
                        argvars = nvalloc(nargs);
                        i = 0;
@@ -3333,6 +3340,7 @@ static var *evaluate(node *op, var *res)
 
                        g_progname = sv_progname;
                        fnargs = sv_fnargs;
+                       func_depth--;
 
                        break;
                }
@@ -3690,6 +3698,7 @@ static var *evaluate(node *op, var *res)
        return res;
 #undef fnargs
 #undef seed
+#undef func_depth
 #undef sreg
 }
 
-- 
2.48.1

++++++ awk-fix-use-after-free-sub.patch ++++++
>From sanghyun.park.cnu at gmail.com  Tue Jun 16 03:18:43 2026
From: sanghyun.park.cnu at gmail.com (Sanghyun Park)
Date: Tue, 16 Jun 2026 12:18:43 +0900
Subject: [PATCH] awk: fix use-after-free in awk_sub()
Message-ID: <[email protected]>

awk_sub() receives the replacement text as a pointer into awk variable
storage. Evaluating the regular expression argument can change that
storage through as_regex(), leaving the replacement pointer dangling
before strlen() and the replacement loop use it.

Copy the replacement string before calling as_regex() so substitution
uses stable storage for the duration of the operation.

Signed-off-by: Sanghyun Park <sanghyun.park.cnu at gmail.com>
---
 editors/awk.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/editors/awk.c b/editors/awk.c
index f15832b..8a51827 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -2555,6 +2555,7 @@ static char *awk_printf(node *n, size_t *len)
 static int awk_sub(node *rn, const char *repl, int nm, var *src, var *dest 
/*,int subexp*/)
 {
        char *resbuf;
+       char *repl_copy;
        const char *sp;
        int match_no, residx, replen, resbufsize;
        int regexec_flags;
@@ -2572,7 +2573,9 @@ static int awk_sub(node *rn, const char *repl, int nm, 
var *src, var *dest /*,in
        resbuf = NULL;
        residx = 0;
        match_no = 0;
+       repl_copy = xstrdup(repl);
        regex = as_regex(rn, &sreg);
+       repl = repl_copy;
        sp = getvar_s(src ? src : intvar[F0]);
 #if defined(REG_STARTEND)
        src_string = sp;
@@ -2662,6 +2665,7 @@ static int awk_sub(node *rn, const char *repl, int nm, 
var *src, var *dest /*,in
        setvar_p(dest ? dest : intvar[F0], resbuf);
        if (regex == &sreg)
                regfree(regex);
+       free(repl_copy);
        return match_no;
 }
 
-- 
2.48.1

Reply via email to