[binutils-gdb] elf32_arm_copy_special_section_fields wild read

Alan Modra via Binutils-cvs <[email protected]> Sun, 28 Jun 2026 13:18:32 +0000 (GMT)
Newsgroups gmane.comp.gnu.binutils.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=19a3a9cfa14e88c25e9131b27a3529fd7315a31d

commit 19a3a9cfa14e88c25e9131b27a3529fd7315a31d
Author: Alan Modra <[email protected]>
Date:   Sun Jun 28 22:13:09 2026 +0930

    elf32_arm_copy_special_section_fields wild read
    
    This function has a number of loops with a controlling expression of
    (i-- > 0) with tests in the loop to break out on finding something.
    If that something is not found, the value of i is -1u on loop exit.
    Code following the loop expects the "not found" value of i to be 0.
    This can lead to an attempted access of oheaders[-1u].
    
    oheaders is elf_elfsections(obfd), the ELF section header table.  We
    are not interested here in anything at index zero of the array, so the
    proper loop control is --i > 0, or equivalently, --i != 0.
    
            * elf32-arm.c (elf32_arm_copy_special_section_fields): Correct
            loop controlling expressions.

Diff:
---
 bfd/elf32-arm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index e27aff48411..6a9be5dda2f 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -20062,7 +20062,7 @@ elf32_arm_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
 	    && iheaders[isection->sh_link]->bfd_section->output_section != NULL
 	    )
 	  {
-	    for (i = elf_numsections (obfd); i-- > 0;)
+	    for (i = elf_numsections (obfd); --i != 0;)
 	      if (oheaders[i]->bfd_section
 		  == iheaders[isection->sh_link]->bfd_section->output_section)
 		break;
@@ -20075,16 +20075,16 @@ elf32_arm_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
 	       with input section names.  Unfortunately we don't.  So instead
 	       we use a simple heuristic and look for the nearest executable
 	       section before this one.  */
-	    for (i = elf_numsections (obfd); i-- > 0;)
+	    for (i = elf_numsections (obfd); --i != 0;)
 	      if (oheaders[i] == osection)
 		break;
 	    if (i == 0)
 	      break;
 
-	    while (i-- > 0)
+	    while (--i != 0)
 	      if (oheaders[i]->sh_type == SHT_PROGBITS
-		  && (oheaders[i]->sh_flags & (SHF_ALLOC | SHF_EXECINSTR))
-		  == (SHF_ALLOC | SHF_EXECINSTR))
+		  && ((oheaders[i]->sh_flags & (SHF_ALLOC | SHF_EXECINSTR))
+		      == (SHF_ALLOC | SHF_EXECINSTR)))
 		break;
 	  }