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
