asan: dlltool buffer overflow: embedded NUL in string
authorAlan Modra <amodra@gmail.com>
Wed, 3 Nov 2021 05:51:42 +0000 (16:21 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 3 Nov 2021 06:36:09 +0000 (17:06 +1030)
yyleng gives the pattern length, xstrdup just copies up to the NUL.
So it is quite possible writing at an index of yyleng-2 overflows
the xstrdup allocated string buffer.  xmemdup quite handily avoids
this problem, even writing the terminating NUL over the trailing
quote.  Use it in ldlex.l too where we'd already had a report of this
problem and fixed it by hand, and to implement xmemdup0 in gas.

binutils/
* deflex.l (single and double quote strings): Use xmemdup.
gas/
* as.h (xmemdup0): Use xmemdup.
ld/
PR 20906
* ldlex.l (double quote string): Use xmemdup.

binutils/deflex.l
gas/as.h
ld/ldlex.l

index 1f3ba6532d469db4fb79a206af732d213efa42f9..def908c113938b8885efd6282de54c78c4c744ef 100644 (file)
@@ -69,14 +69,12 @@ int linenumber;
                }
 
 "\""[^\"]*"\"" {
-               yylval.id = xstrdup (yytext+1);
-               yylval.id[yyleng-2] = 0;
+               yylval.id = xmemdup (yytext + 1, yyleng - 2, yyleng - 1);
                return ID;
                }
 
 "\'"[^\']*"\'" {
-               yylval.id = xstrdup (yytext+1);
-               yylval.id[yyleng-2] = 0;
+               yylval.id = xmemdup (yytext + 1, yyleng - 2, yyleng - 1);
                return ID;
                }
 "*".*          { }
index 14a768f8889778bf79c760bf0fed6275944b3f16..f3f12fbd2f8fdb5ad6bd4a0e5a147fd46704b0c2 100644 (file)
--- a/gas/as.h
+++ b/gas/as.h
@@ -484,9 +484,7 @@ void add_debug_prefix_map (const char *);
 static inline char *
 xmemdup0 (const char *in, size_t len)
 {
-  char *out = (char *) xmalloc (len + 1);
-  out[len] = 0;
-  return (char *) memcpy (out, in, len);
+  return xmemdup (in, len, len + 1);
 }
 
 struct expressionS;
index 6aeba6de6567fe5cb22a5bbda8416d02561cc53d..5db1e731b7408ec0c750de48b55a4d41468c46d5 100644 (file)
@@ -431,18 +431,10 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
        }
 
 <SCRIPT,EXPRESSION,WILD,VERS_NODE,INPUTLIST>"\""[^\"]*"\"" {
-                                       /* No matter the state, quotes
-                                          give what's inside.  */
-                                       bfd_size_type len;
-                                       yylval.name = xstrdup (yytext + 1);
-                                       /* PR ld/20906.  A corrupt input file
-                                          can contain bogus strings.  */
-                                       len = strlen (yylval.name);
-                                       if (len > (bfd_size_type) yyleng - 2)
-                                         len = yyleng - 2;
-                                       yylval.name[len] = 0;
-                                       return NAME;
-                               }
+               /* No matter the state, quotes give what's inside.  */
+               yylval.name = xmemdup (yytext + 1, yyleng - 2, yyleng - 1);
+               return NAME;
+       }
 
 <SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"\n" {
                                lineno++; }