[binutils-gdb] Arm: parse_neon_type() weaknesses

Jan Beulich jbeulich@sourceware.org
Fri Aug 8 09:46:02 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d582b4eb1be1199b1a41d922355bc62f763b19ef

commit d582b4eb1be1199b1a41d922355bc62f763b19ef
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Aug 8 11:43:02 2025 +0200

    Arm: parse_neon_type() weaknesses
    
    The custom parsing done there and in one of its callers allowed various
    bogus constructs to be accepted. Insist on a non-zero leading digit when
    parsing numbers, don't lose upper bits, and insist on proper separation
    of operands.

Diff:
---
 gas/config/tc-arm.c                     | 14 ++++++++++----
 gas/testsuite/gas/arm/neon-suffix-bad.d |  2 +-
 gas/testsuite/gas/arm/neon-suffix-bad.l | 21 +++++++++++++++++++++
 gas/testsuite/gas/arm/neon-suffix-bad.s | 22 ++++++++++++++++++++++
 4 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 99c07d4b93b..217864bc09b 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -1474,7 +1474,7 @@ parse_neon_type (struct neon_type *type, char **str)
   while (type->elems < NEON_MAX_TYPE_ELS)
     {
       enum neon_el_type thistype = NT_untyped;
-      unsigned thissize = -1u;
+      unsigned long thissize = -1ul;
 
       if (*ptr != '.')
 	break;
@@ -1505,14 +1505,17 @@ parse_neon_type (struct neon_type *type, char **str)
 	      return FAIL;
 	    }
 	  ptr += 1;
+	  if (!ISDIGIT (*ptr) || *ptr == '0')
+	    goto unexpected;
 	  thissize = strtoul (ptr, &ptr, 10);
 	  if (thissize != 16)
 	    {
-	      as_bad (_("bad size %d in type specifier"), thissize);
+	      as_bad (_("bad size %lu in type specifier"), thissize);
 	      return FAIL;
 	    }
 	  goto done;
 	default:
+	unexpected:
 	  as_bad (_("unexpected character `%c' in type specifier"), *ptr);
 	  return FAIL;
 	}
@@ -1525,12 +1528,14 @@ parse_neon_type (struct neon_type *type, char **str)
       else
 	{
 	parsesize:
+	  if (!ISDIGIT (*ptr) || *ptr == '0')
+	    goto unexpected;
 	  thissize = strtoul (ptr, &ptr, 10);
 
 	  if (thissize != 8 && thissize != 16 && thissize != 32
 	      && thissize != 64)
 	    {
-	      as_bad (_("bad size %d in type specifier"), thissize);
+	      as_bad (_("bad size %lu in type specifier"), thissize);
 	      return FAIL;
 	    }
 	}
@@ -22470,7 +22475,8 @@ opcode_lookup (char **str)
 	  if (parse_neon_type (&inst.vectype, str) == FAIL)
 	    return NULL;
 	}
-      else if (end[offset] != '\0' && !is_whitespace (end[offset]))
+
+      if (**str != '\0' && !is_whitespace (**str))
 	return NULL;
     }
   else
diff --git a/gas/testsuite/gas/arm/neon-suffix-bad.d b/gas/testsuite/gas/arm/neon-suffix-bad.d
index 7e3bdfea694..3ffa49315ae 100644
--- a/gas/testsuite/gas/arm/neon-suffix-bad.d
+++ b/gas/testsuite/gas/arm/neon-suffix-bad.d
@@ -1,3 +1,3 @@
-# name: Bad suffix for non-Neon mnemonic
+# name: Bad suffix for (non-)Neon mnemonic
 # as: -mfpu=neon
 # error_output: neon-suffix-bad.l
diff --git a/gas/testsuite/gas/arm/neon-suffix-bad.l b/gas/testsuite/gas/arm/neon-suffix-bad.l
index 091429dc11a..234d95f71df 100644
--- a/gas/testsuite/gas/arm/neon-suffix-bad.l
+++ b/gas/testsuite/gas/arm/neon-suffix-bad.l
@@ -7,3 +7,24 @@
 [^:]*:10: Error: invalid neon suffix for non neon instruction
 [^:]*:11: Error: invalid neon suffix for non neon instruction
 [^:]*:12: Error: invalid instruction shape -- `vcvt.f64.s32 d0,s0,#11'
+[^:]*:19: Error: unexpected character `0' .*
+#?[^:]*:19: Error: .*
+[^:]*:20: Error: unexpected character `0' .*
+#?[^:]*:20: Error: .*
+[^:]*:22: Error: unexpected character `-' .*
+#?[^:]*:22: Error: .*
+[^:]*:23: Error: bad instruction .*
+[^:]*:25: Error: bad size .*
+#?[^:]*:25: Error: .*
+[^:]*:26: Error: bad size .*
+#?[^:]*:26: Error: .*
+[^:]*:28: Error: unexpected type character `b' .*
+#?[^:]*:28: Error: .*
+[^:]*:29: Error: unexpected character ` ' .*
+#?[^:]*:29: Error: .*
+[^:]*:30: Error: .* register expected .*
+[^:]*:31: Error: unexpected character ` ' .*
+#?[^:]*:31: Error: .*
+[^:]*:32: Error: .* register expected .*
+[^:]*:34: Error: bad instruction .*
+[^:]*:35: Error: bad instruction .*
diff --git a/gas/testsuite/gas/arm/neon-suffix-bad.s b/gas/testsuite/gas/arm/neon-suffix-bad.s
index 20c60fe89f5..50360f9f343 100644
--- a/gas/testsuite/gas/arm/neon-suffix-bad.s
+++ b/gas/testsuite/gas/arm/neon-suffix-bad.s
@@ -11,3 +11,25 @@ faddd.f32 d0, d0, d0
 faddd.f64 d0, d0, d0
 vcvt.f64.s32 d0, s0, #11
 
+	.arm
+	.arch armv8.6-a
+	.arch_extension simd
+	vcvt.bf16.f32	d0, q0		@ good, for reference
+
+	vcvt.bf016.f32	d0, q0
+	vcvt.bf16.f032	d0, q0
+
+	vcvt.bf-4294967280.f32	d0, q0
+	vcvt.bf16.f-4294967264	d0, q0
+
+	vcvt.bf4294967312.f32	d0, q0
+	vcvt.bf16.f4294967328	d0, q0
+
+	vcvt.b f16.f32	d0, q0
+	vcvt.bf 16.f32	d0, q0
+	vcvt.bf16 .f32	d0, q0
+	vcvt.bf16. f32	d0, q0
+	vcvt.bf16.f 32	d0, q0
+
+	vcvt.bf16.f32d0, q0
+	vcvt.bf16.fd0, q0


More information about the Binutils-cvs mailing list