diff --git a/CVE-2026-40467.patch b/CVE-2026-40467.patch new file mode 100644 index 0000000..a38f588 --- /dev/null +++ b/CVE-2026-40467.patch @@ -0,0 +1,40 @@ +From 7016e0e024012490356fb8ccff270d78e0eacf12 Mon Sep 17 00:00:00 2001 +From: "Arnold D. Robbins" +Date: Fri, 3 Apr 2026 12:02:11 +0300 +Subject: [PATCH] Small memory management fix in io.c. + +--- + io.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/io.c b/io.c +index c595c009..abae0373 100644 +--- a/io.c ++++ b/io.c +@@ -2836,22 +2836,25 @@ do_getline_redir(int into_variable, enum redirval redirtype) + assert(redirtype != redirect_none); + redir_exp = TOP(); + rp = redirect(redir_exp, redirtype, & redir_error, false); +- DEREF(redir_exp); + decr_sp(); + if (rp == NULL) { + if (redir_error) { /* failed redirect */ + if (! do_traditional) + update_ERRNO_int(redir_error); + } ++ DEREF(redir_exp); + return make_number((AWKNUM) -1.0); + } else if ((rp->flag & RED_TWOWAY) != 0 && rp->iop == NULL) { + if (is_non_fatal_redirect(redir_exp->stptr, redir_exp->stlen)) { + update_ERRNO_int(EBADF); ++ DEREF(redir_exp); + return make_number((AWKNUM) -1.0); + } + (void) close_rp(rp, CLOSE_ALL); ++ DEREF(redir_exp); // we're about to die, but what the heck, release it anyway + fatal(_("getline: attempt to read from closed read end of two-way pipe")); + } ++ DEREF(redir_exp); + iop = rp->iop; + if (iop == NULL) /* end of input */ + return make_number((AWKNUM) 0.0); diff --git a/CVE-2026-40468-part1.patch b/CVE-2026-40468-part1.patch new file mode 100644 index 0000000..52ec586 --- /dev/null +++ b/CVE-2026-40468-part1.patch @@ -0,0 +1,37 @@ +From 062f2f2581b991362c046f7f2e238ffa34e6f8c7 Mon Sep 17 00:00:00 2001 +From: "Arnold D. Robbins" +Date: Sat, 4 Apr 2026 21:45:58 +0300 +Subject: [PATCH] Minor integer overflow fixes. + +--- + ChangeLog | 8 ++++++++ + builtin.c | 2 +- + node.c | 2 +- + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/builtin.c b/builtin.c +index 4193d3497..f6a37ac76 100644 +--- a/builtin.c ++++ b/builtin.c +@@ -1805,7 +1805,7 @@ do_sub(int nargs, unsigned int flags) + char *repl; + char *replend; + size_t repllen; +- int sofar; ++ size_t sofar; + int ampersands; + int matches = 0; + Regexp *rp; +diff --git a/node.c b/node.c +index 021eaf6cd..81787e5f0 100644 +--- a/node.c ++++ b/node.c +@@ -583,7 +583,7 @@ parse_escape(const char **string_ptr, const char **result, size_t *nbytes) + parse_escape(const char **string_ptr) + { + int c = *(*string_ptr)++; +- int i; ++ int64_t i; + int count; + int j; + const char *start; diff --git a/CVE-2026-40468-part2.patch b/CVE-2026-40468-part2.patch new file mode 100644 index 0000000..e654983 --- /dev/null +++ b/CVE-2026-40468-part2.patch @@ -0,0 +1,58 @@ +From aa7272a6e1184cdd21ab8f89200219abd8053eda Mon Sep 17 00:00:00 2001 +From: "Arnold D. Robbins" +Date: Mon, 6 Apr 2026 10:56:38 +0300 +Subject: [PATCH] Add overflow checking in do_sub for 32 bit systems. + +--- + ChangeLog | 9 +++++++++ + builtin.c | 25 ++++++++++++++++++++----- + 2 files changed, 29 insertions(+), 5 deletions(-) + +diff --git a/builtin.c b/builtin.c +index f6a37ac76..f33525d5b 100644 +--- a/builtin.c ++++ b/builtin.c +@@ -1819,11 +1819,13 @@ do_sub(int nargs, unsigned int flags) + long current; + bool lastmatchnonzero; + char *mb_indices = NULL; ++ const char *fname = NULL; // for fatal message, below + + if ((flags & GENSUB) != 0) { + double d; + NODE *glob_flag; + ++ fname = "gensub"; + tmp = PEEK(3); + rp = re_update(tmp); + +@@ -1855,6 +1857,7 @@ do_sub(int nargs, unsigned int flags) + } + DEREF(glob_flag); + } else { ++ fname = ((flags & GSUB) != 0) ? "gsub" : "sub"; + /* take care of regexp early, in case re_update is fatal */ + + tmp = PEEK(2); +@@ -1975,6 +1975,21 @@ do_sub(int nargs, unsigned int flags) + * vary since ampersand is actual text of regexp match. + */ + ++ // 4/2026: This overflow check simply provides a fatal ++ // message instead of letting realloc() die later after ++ // a buffer overrun. It simply makes the user experience better, ++ // but does not prevent gawk from dying miserably. I suppose ++ // it's worth the trouble, but just barely. ++ ++ /* uint64_t so the product is 64-bit even on 32-bit ILP32 builds */ ++ uint64_t repl_contribution = ++ (uint64_t)(unsigned int)ampersands ++ * (uint64_t)(uintptr_t)(matchend - matchstart); ++ if (repl_contribution > (uint64_t)SIZE_MAX ++ || repl_contribution > (uint64_t)SIZE_MAX - (size_t)(matchend - text) ++ - repllen - 1) ++ fatal(_("%s: replacement expansion too large"), fname); ++ + /* + * add 1 to len to handle "empty" case where + * matchend == matchstart and we force a match on a single diff --git a/CVE-2026-40553-part1.patch b/CVE-2026-40553-part1.patch new file mode 100644 index 0000000..161d107 --- /dev/null +++ b/CVE-2026-40553-part1.patch @@ -0,0 +1,30 @@ +From cca0366144336b49aaa7d5d949966ce8e2c70843 Mon Sep 17 00:00:00 2001 +From: "Arnold D. Robbins" +Date: Wed, 15 Apr 2026 09:39:02 +0300 +Subject: [PATCH] Avoid buffer overflow in extension/readdir.c. + +--- + extension/ChangeLog | 6 ++++++ + extension/readdir.c | 6 +++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/extension/readdir.c b/extension/readdir.c +index 89cc4b42b..1aba0f722 100644 +--- a/extension/readdir.c ++++ b/extension/readdir.c +@@ -117,10 +117,12 @@ ftype(struct dirent *entry, const char *dirname) + #endif + char fname[PATH_MAX]; + struct stat sbuf; ++ int count; ++ ++ count = snprintf(fname, sizeof(fname), "%s/%s", dirname, entry->d_name); ++ if (count > sizeof(fname)) ++ return "u"; // buffer overflow. skip stat() call. + +- strcpy(fname, dirname); +- strcat(fname, "/"); +- strcat(fname, entry->d_name); + if (stat(fname, &sbuf) == 0) { + if (S_ISBLK(sbuf.st_mode)) + return "b"; diff --git a/CVE-2026-40553-part2.patch b/CVE-2026-40553-part2.patch new file mode 100644 index 0000000..a704efa --- /dev/null +++ b/CVE-2026-40553-part2.patch @@ -0,0 +1,23 @@ +From bfa2e4b890a44100a99d26b54af385479528b12e Mon Sep 17 00:00:00 2001 +From: "Arnold D. Robbins" +Date: Fri, 17 Apr 2026 11:48:19 +0300 +Subject: [PATCH] Small fix in extension/readdir.c. + +--- + extension/ChangeLog | 5 +++++ + extension/readdir.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/extension/readdir.c b/extension/readdir.c +index 1aba0f722..b94ec6e7e 100644 +--- a/extension/readdir.c ++++ b/extension/readdir.c +@@ -120,7 +120,7 @@ ftype(struct dirent *entry, const char *dirname) + int count; + + count = snprintf(fname, sizeof(fname), "%s/%s", dirname, entry->d_name); +- if (count > sizeof(fname)) ++ if (count >= sizeof(fname)) + return "u"; // buffer overflow. skip stat() call. + + if (stat(fname, &sbuf) == 0) { diff --git a/gawk.spec b/gawk.spec index 6196c90..8165452 100644 --- a/gawk.spec +++ b/gawk.spec @@ -47,7 +47,7 @@ Name: gawk Summary: The GNU version of the AWK text processing utility Version: 5.1.0 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ and GPLv2+ and LGPLv2+ and BSD @@ -120,6 +120,18 @@ Patch001: proc-rv.patch #Patch008: gawk-api-version.patch +#https://cgit.git.savannah.gnu.org/cgit/gawk.git/commit/?id=cca0366144336b49aaa7d5d949966ce8e2c70843 +Patch002: CVE-2026-40553-part1.patch +#https://cgit.git.savannah.gnu.org/cgit/gawk.git/commit/?id=bfa2e4b890a44100a99d26b54af385479528b12e +Patch003: CVE-2026-40553-part2.patch + +#https://cgit.git.savannah.gnu.org/cgit/gawk.git/commit/?id=a2d18c74109e41bec29a23098eba2e00057286d8 +Patch004: CVE-2026-40467.patch + +#https://cgit.git.savannah.gnu.org/cgit/gawk.git/commit/?id=062f2f2581b991362c046f7f2e238ffa34e6f8c7 +Patch005: CVE-2026-40468-part1.patch +#https://cgit.git.savannah.gnu.org/cgit/gawk.git/commit/?id=aa7272a6e1184cdd21ab8f89200219abd8053eda +Patch006: CVE-2026-40468-part2.patch # Downstream patches -- these should be always included when doing rebase: @@ -289,6 +301,14 @@ install -m 0644 -p doc/gawkinet.{pdf,ps} %{buildroot}%{_docdir}/%{name} # ============================================================================= %changelog +* Fri Aug 21 2026 Jakub Martisko - 5.1.0-7 +- Fix use after free in io.c +- Fix buffer overflow in extensions/readdir.c +- Fix integer overflow in buildin.c +Resolves: CVE-2026-40467 +Resolves: CVE-2026-40468 +Resolves: CVE-2026-40553 + * Wed Feb 16 2022 Jakub Martisko - 5.1.0-6 Fix the issue with incorect handling of return values of some processes Resolves: rhbz#2055107