diff --git a/backport-PR32399-buffer-overflow-printing-core_file_failing_c.patch b/backport-PR32399-buffer-overflow-printing-core_file_failing_c.patch new file mode 100644 index 0000000000000000000000000000000000000000..f7a9f93153bfe42b769a949fbd9939cb97ddb798 --- /dev/null +++ b/backport-PR32399-buffer-overflow-printing-core_file_failing_c.patch @@ -0,0 +1,118 @@ +From 1e3b2da08eb21042f01a9f6862b487ca77484c92 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Fri, 29 Nov 2024 10:18:36 +1030 +Subject: [PATCH] PR32399, buffer overflow printing core_file_failing_command + +Assorted targets do not check, as the ELF targets do, that the program +name in a core file is NUL terminated. Fix some of them. I haven't +attempted to fix all targets because editing host specific code can +easily result in build bugs, which aren't discovered until someone +build binutils for that host. (Of the files edited here, I can't +easily compile hpux-core.c and osf-core.c on a linux system.) + + PR 32399 + * hppabsd-core.c (hppabsd_core_core_file_p): Ensure core_command + string is terminated. + * hpux-core.c (hpux_core_core_file_p): Likewise. + * irix-core.c (irix_core_core_file_p): Likewise. + * lynx-core.c (lynx_core_file_p): Likewise. + * osf-core.c (osf_core_core_file_p): Likewise. + * mach-o.c (bfd_mach_o_core_file_failing_command): Likewise. +--- + bfd/hppabsd-core.c | 3 ++- + bfd/hpux-core.c | 3 ++- + bfd/irix-core.c | 3 ++- + bfd/lynx-core.c | 3 ++- + bfd/mach-o.c | 4 ++-- + bfd/osf-core.c | 3 ++- + 6 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/bfd/hppabsd-core.c b/bfd/hppabsd-core.c +index ae5d1f8f1e5..1c24e641b3a 100644 +--- a/bfd/hppabsd-core.c ++++ b/bfd/hppabsd-core.c +@@ -179,7 +179,8 @@ hppabsd_core_core_file_p (bfd *abfd) + goto fail; + core_regsec (abfd)->vma = 0; + +- strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1); ++ strncpy (core_command (abfd), u.u_comm, MAXCOMLEN); ++ core_command (abfd)[MAXCOMLEN] = 0; + core_signal (abfd) = u.u_code; + return _bfd_no_cleanup; + +diff --git a/bfd/hpux-core.c b/bfd/hpux-core.c +index 1e2ea926f02..18516e3a897 100644 +--- a/bfd/hpux-core.c ++++ b/bfd/hpux-core.c +@@ -177,7 +177,8 @@ hpux_core_core_file_p (bfd *abfd) + if (bfd_bread ((void *) &proc_exec, (bfd_size_type) core_header.len, + abfd) != core_header.len) + break; +- strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1); ++ strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN); ++ core_command (abfd)[MAXCOMLEN] = 0; + good_sections++; + } + break; +diff --git a/bfd/irix-core.c b/bfd/irix-core.c +index 80cb82d0fa3..7a486841d35 100644 +--- a/bfd/irix-core.c ++++ b/bfd/irix-core.c +@@ -203,7 +203,8 @@ irix_core_core_file_p (bfd *abfd) + if (!core_hdr (abfd)) + return NULL; + +- strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE); ++ strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE - 1); ++ core_command (abfd)[CORE_NAMESIZE - 1] = 0; + core_signal (abfd) = coreout.c_sigcause; + + if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0) +diff --git a/bfd/lynx-core.c b/bfd/lynx-core.c +index 44d94ad8745..7870dc62866 100644 +--- a/bfd/lynx-core.c ++++ b/bfd/lynx-core.c +@@ -120,7 +120,8 @@ lynx_core_file_p (bfd *abfd) + if (!core_hdr (abfd)) + return NULL; + +- strncpy (core_command (abfd), pss.pname, PNMLEN + 1); ++ strncpy (core_command (abfd), pss.pname, PNMLEN); ++ core_command (abfd)[PNMLEN] = 0; + + /* Compute the size of the thread contexts */ + +diff --git a/bfd/mach-o.c b/bfd/mach-o.c +index 974747caadd..037718fb22c 100644 +--- a/bfd/mach-o.c ++++ b/bfd/mach-o.c +@@ -6019,9 +6019,9 @@ bfd_mach_o_core_file_failing_command (bfd *abfd) + int ret; + + ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len); +- if (ret < 0) ++ if (ret < 0 || len == 0) + return NULL; +- ++ buf[len - 1] = 0; + return (char *) buf; + } + +diff --git a/bfd/osf-core.c b/bfd/osf-core.c +index 55b127d48b3..6869dfa23ea 100644 +--- a/bfd/osf-core.c ++++ b/bfd/osf-core.c +@@ -92,7 +92,8 @@ osf_core_core_file_p (bfd *abfd) + if (!core_hdr (abfd)) + return NULL; + +- strncpy (core_command (abfd), core_header.name, MAXCOMLEN + 1); ++ strncpy (core_command (abfd), core_header.name, MAXCOMLEN); ++ core_command (abfd)[MAXCOMLEN] = 0; + core_signal (abfd) = core_header.signo; + + for (i = 0; i < core_header.nscns; i++) +-- +2.28.0.windows.1 + diff --git a/backport-Re-PR32399-buffer-overflow-printing-core_file_failin.patch b/backport-Re-PR32399-buffer-overflow-printing-core_file_failin.patch new file mode 100644 index 0000000000000000000000000000000000000000..c3c59f2c1ab083febf402593032df297f6177aa7 --- /dev/null +++ b/backport-Re-PR32399-buffer-overflow-printing-core_file_failin.patch @@ -0,0 +1,220 @@ +From 8ab91a033555c5faae1bcd615800670b91673731 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Sat, 30 Nov 2024 16:41:14 +1030 +Subject: [PATCH] Re: PR32399, buffer overflow printing + core_file_failing_command + +Fix more potential buffer overflows, and correct trad-code.c and +cisco-core.c where they should be using bfd_{z}alloc rather than +bfd_{z}malloc. To stop buffer overflows with fuzzed objects that +don't have a terminator on the core_file_failing_command string, this +patch allocates an extra byte at the end of the entire header buffer +rather than poking a NUL at the end of the name array (u_comm[] or +similar) because (a) it's better to not overwrite the file data, and +(b) it is possible that some core files make use of fields in struct +user beyond the end of u_comm to extend the command name. The patch +also changes some unnecessary uses of bfd_zalloc to bfd_alloc. +There's not much point in clearing memeory that will shortly be +completely overwritten. + + PR 32399 + * aix5ppc-core.c (xcoff64_core_p): Allocate an extra byte to + ensure the core_file_failing_command string is terminated. + * netbsd-core.c (netbsd_core_file_p): Likewise. + * ptrace-core.c (ptrace_unix_core_file_p): Likewise. + * rs6000-core.c (rs6000coff_core_p): Likewise. + * trad-core.c (trad_unix_core_file_p): Likewise, and bfd_alloc + tdata rather than bfd_zmalloc. + * cisco-core.c (cisco_core_file_validate): bfd_zalloc tdata. +--- + bfd/aix5ppc-core.c | 15 ++++++++------- + bfd/cisco-core.c | 2 +- + bfd/netbsd-core.c | 14 ++++++++------ + bfd/ptrace-core.c | 8 +++++--- + bfd/rs6000-core.c | 5 ++++- + bfd/trad-core.c | 8 +++++--- + 6 files changed, 31 insertions(+), 21 deletions(-) + +diff --git a/bfd/aix5ppc-core.c b/bfd/aix5ppc-core.c +index 179a7bf5b78..a6d6449fc57 100644 +--- a/bfd/aix5ppc-core.c ++++ b/bfd/aix5ppc-core.c +@@ -66,8 +66,7 @@ xcoff64_core_p (bfd *abfd) + if (bfd_seek (abfd, 0, SEEK_SET) != 0) + goto xcoff64_core_p_error; + +- if (sizeof (struct core_dumpxx) +- != bfd_bread (&core, sizeof (struct core_dumpxx), abfd)) ++ if (sizeof core != bfd_bread (&core, sizeof core, abfd)) + goto xcoff64_core_p_error; + + if (bfd_stat (abfd, &statbuf) < 0) +@@ -111,14 +110,16 @@ xcoff64_core_p (bfd *abfd) + return NULL; + } + +- new_core_hdr = bfd_zalloc (abfd, sizeof (struct core_dumpxx)); ++ new_core_hdr = bfd_alloc (abfd, sizeof (*new_core_hdr) + 1); + if (NULL == new_core_hdr) + return NULL; + +- memcpy (new_core_hdr, &core, sizeof (struct core_dumpxx)); +- /* The core_hdr() macro is no longer used here because it would +- expand to code relying on gcc's cast-as-lvalue extension, +- which was removed in gcc 4.0. */ ++ memcpy (new_core_hdr, &core, sizeof (*new_core_hdr)); ++ ++ /* Ensure core_file_failing_command string is terminated. This is ++ just to stop buffer overflows on fuzzed files. */ ++ ((char *) new_core_hdr)[sizeof (*new_core_hdr)] = 0; ++ + abfd->tdata.any = new_core_hdr; + + /* .stack section. */ +diff --git a/bfd/cisco-core.c b/bfd/cisco-core.c +index 75b11150f6d..1bbb44192ff 100644 +--- a/bfd/cisco-core.c ++++ b/bfd/cisco-core.c +@@ -154,7 +154,7 @@ cisco_core_file_validate (bfd *abfd, int crash_info_loc) + /* OK, we believe you. You're a core file. */ + + amt = sizeof (struct cisco_core_struct); +- abfd->tdata.cisco_core_data = (struct cisco_core_struct *) bfd_zmalloc (amt); ++ abfd->tdata.cisco_core_data = bfd_zalloc (abfd, amt); + if (abfd->tdata.cisco_core_data == NULL) + return NULL; + +diff --git a/bfd/netbsd-core.c b/bfd/netbsd-core.c +index 647af9d7bc2..ae56f3913e4 100644 +--- a/bfd/netbsd-core.c ++++ b/bfd/netbsd-core.c +@@ -47,7 +47,7 @@ + struct netbsd_core_struct + { + struct core core; +-} *rawptr; ++}; + + /* Handle NetBSD-style core dump file. */ + +@@ -60,9 +60,9 @@ netbsd_core_file_p (bfd *abfd) + asection *asect; + struct core core; + struct coreseg coreseg; +- size_t amt = sizeof core; ++ struct netbsd_core_struct *rawptr; + +- val = bfd_bread (&core, amt, abfd); ++ val = bfd_bread (&core, sizeof core, abfd); + if (val != sizeof core) + { + /* Too small to be a core file. */ +@@ -76,13 +76,15 @@ netbsd_core_file_p (bfd *abfd) + return 0; + } + +- amt = sizeof (struct netbsd_core_struct); +- rawptr = (struct netbsd_core_struct *) bfd_zalloc (abfd, amt); ++ rawptr = bfd_alloc (abfd, sizeof (*rawptr) + 1); + if (rawptr == NULL) + return 0; + +- rawptr->core = core; + abfd->tdata.netbsd_core_data = rawptr; ++ rawptr->core = core; ++ /* Ensure core_file_failing_command string is terminated. This is ++ just to stop buffer overflows on fuzzed files. */ ++ ((char *) rawptr)[sizeof (*rawptr)] = 0; + + offset = core.c_hdrsize; + for (i = 0; i < core.c_nseg; i++) +diff --git a/bfd/ptrace-core.c b/bfd/ptrace-core.c +index 426d6070dc8..5952c06f8b6 100644 +--- a/bfd/ptrace-core.c ++++ b/bfd/ptrace-core.c +@@ -61,7 +61,6 @@ ptrace_unix_core_file_p (bfd *abfd) + int val; + struct ptrace_user u; + struct trad_core_struct *rawptr; +- size_t amt; + flagword flags; + + val = bfd_bread ((void *)&u, (bfd_size_type) sizeof u, abfd); +@@ -77,8 +76,7 @@ ptrace_unix_core_file_p (bfd *abfd) + + /* Allocate both the upage and the struct core_data at once, so + a single free() will free them both. */ +- amt = sizeof (struct trad_core_struct); +- rawptr = (struct trad_core_struct *) bfd_zalloc (abfd, amt); ++ rawptr = bfd_alloc (abfd, sizeof (*rawptr) + 1); + + if (rawptr == NULL) + return 0; +@@ -87,6 +85,10 @@ ptrace_unix_core_file_p (bfd *abfd) + + rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */ + ++ /* Ensure core_file_failing_command string is terminated. This is ++ just to stop buffer overflows on fuzzed files. */ ++ ((char *) rawptr)[sizeof (*rawptr)] = 0; ++ + /* Create the sections. */ + + flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; +diff --git a/bfd/rs6000-core.c b/bfd/rs6000-core.c +index 19b9f46631f..ac8b29838ad 100644 +--- a/bfd/rs6000-core.c ++++ b/bfd/rs6000-core.c +@@ -476,12 +476,15 @@ rs6000coff_core_p (bfd *abfd) + #else + size = sizeof (core.new_dump); + #endif +- tmpptr = (char *) bfd_zalloc (abfd, (bfd_size_type) size); ++ tmpptr = bfd_alloc (abfd, size + 1); + if (!tmpptr) + return NULL; + + /* Copy core file header. */ + memcpy (tmpptr, &core, size); ++ /* Ensure core_file_failing_command string is terminated. This is ++ just to stop buffer overflows on fuzzed files. */ ++ tmpptr[size] = 0; + set_tdata (abfd, tmpptr); + + /* Set architecture. */ +diff --git a/bfd/trad-core.c b/bfd/trad-core.c +index 012bc4bdd01..06b6bdadd87 100644 +--- a/bfd/trad-core.c ++++ b/bfd/trad-core.c +@@ -65,7 +65,6 @@ trad_unix_core_file_p (bfd *abfd) + int val; + struct user u; + struct trad_core_struct *rawptr; +- size_t amt; + flagword flags; + + #ifdef TRAD_CORE_USER_OFFSET +@@ -132,8 +131,7 @@ trad_unix_core_file_p (bfd *abfd) + + /* Allocate both the upage and the struct core_data at once, so + a single free() will free them both. */ +- amt = sizeof (struct trad_core_struct); +- rawptr = (struct trad_core_struct *) bfd_zmalloc (amt); ++ rawptr = bfd_alloc (abfd, sizeof (*rawptr) + 1); + if (rawptr == NULL) + return 0; + +@@ -141,6 +139,10 @@ trad_unix_core_file_p (bfd *abfd) + + rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */ + ++ /* Ensure core_file_failing_command string is terminated. This is ++ just to stop buffer overflows on fuzzed files. */ ++ ((char *) rawptr)[sizeof (*rawptr)] = 0; ++ + /* Create the sections. */ + + flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; +-- +2.28.0.windows.1 + diff --git a/binutils.spec b/binutils.spec index cd26e0c44c84b98624ffa0f02e008038f5fd917b..143453937e6174433203de6ca2b615fa0b8be821 100644 --- a/binutils.spec +++ b/binutils.spec @@ -2,7 +2,7 @@ Summary: A GNU collection of binary utilities Name: binutils%{?_with_debug:-debug} Version: 2.41 -Release: 18 +Release: 19 License: GPL-3.0-or-later AND (GPL-3.0-or-later WITH Bison-exception-2.2) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND BSD-3-Clause AND GFDL-1.3-or-later AND GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later URL: https://sourceware.org/binutils @@ -383,6 +383,12 @@ Patch5014: backport-CVE-2025-0840.patch # Purpose: PR32716, objdump -i memory leak # Lifetime: fixed in master Patch5015: backport-CVE-2025-3198.patch + +# Purpose: PR32399, buffer overflow printing core_file_failing_command +# Lifetime: Fixed in 2.44 +Patch5016: backport-PR32399-buffer-overflow-printing-core_file_failing_c.patch +Patch5017: backport-Re-PR32399-buffer-overflow-printing-core_file_failin.patch + #---------------------------------------------------------------------------- Patch6001: aarch64-add-l4-instruction.patch @@ -1401,6 +1407,9 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Fri Apr 18 2025 eastb233 - 2.41-19 +- Fix PR32399, buffer overflow printing core_file_failing_command + * Sun Apr 06 2025 Funda Wang - 2.41-18 - Fix CVE-2025-3198: Memory leak issue in objdump