Author: Alan Modra <amodra@gmail.com>
Date:   Wed, 15 Jan 2025 19:13:43 +1030

PR32560 stack-buffer-overflow at objdump disassemble_bytes

There's always someone pushing the boundaries.

	PR 32560
	* objdump.c (MAX_INSN_WIDTH): Define.
	(insn_width): Make it an unsigned long.
	(disassemble_bytes): Use MAX_INSN_WIDTH to size buffer.
	(main <OPTION_INSN_WIDTH>): Restrict size of insn_width.

Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=baac6c221e9d69335bf41366a1c7d87d8ab2f893]
CVE: CVE-2025-0840

Signed-off-by: Deepesh Varatharajan <Deepesh.Varatharajan@windriver.com>

diff --git a/binutils/objdump.c b/binutils/objdump.c
index 49e944b1..dba726e3 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -116,7 +116,8 @@ static bool disassemble_all;		/* -D */
 static int disassemble_zeroes;		/* --disassemble-zeroes */
 static bool formats_info;		/* -i */
 int wide_output;			/* -w */
-static int insn_width;			/* --insn-width */
+#define MAX_INSN_WIDTH 49
+static unsigned long insn_width;       /* --insn-width */
 static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
 static bfd_vma stop_address = (bfd_vma) -1;  /* --stop-address */
 static int dump_debugging;		/* --debugging */
@@ -3327,7 +3328,7 @@ disassemble_bytes (struct disassemble_info *inf,
 	}
       else
 	{
-	  char buf[50];
+	  char buf[MAX_INSN_WIDTH + 1];
 	  unsigned int bpc = 0;
 	  unsigned int pb = 0;
 
@@ -5995,8 +5996,9 @@ main (int argc, char **argv)
 	  break;
 	case OPTION_INSN_WIDTH:
 	  insn_width = strtoul (optarg, NULL, 0);
-	  if (insn_width <= 0)
-	    fatal (_("error: instruction width must be positive"));
+	  if (insn_width - 1 >= MAX_INSN_WIDTH)
+	    fatal (_("error: instruction width must be in the range 1 to "
+	             XSTRING (MAX_INSN_WIDTH)));
 	  break;
 	case OPTION_INLINES:
 	  unwind_inlines = true;
