PR gas/7059
authorDave Korn <dave.korn@artimi.com>
Wed, 18 Feb 2009 18:38:06 +0000 (18:38 +0000)
committerDave Korn <dave.korn@artimi.com>
Wed, 18 Feb 2009 18:38:06 +0000 (18:38 +0000)
* coffcode.h (coff_write_object_contents):  Don't let the string
table offset overflow the s_name field when using long section names.

bfd/ChangeLog
bfd/coffcode.h

index fad6a18..55f1c73 100644 (file)
@@ -1,5 +1,11 @@
 2009-18-02  Dave Korn  <dave.korn.cygwin@gmail.com>
 
+       PR gas/7059
+       * coffcode.h (coff_write_object_contents):  Don't let the string
+       table offset overflow the s_name field when using long section names.
+
+2009-18-02  Dave Korn  <dave.korn.cygwin@gmail.com>
+
        * coff-alpha.c (alpha_ecoff_backend_data):  Initialise fields which
        control long section name handling with ECOFF_NO_LONG_SECTION_NAMES.
        * coff-mips.c (mips_ecoff_backend_data):  Likewise.
index cfa1a40..59bb223 100644 (file)
@@ -3629,8 +3629,29 @@ coff_write_object_contents (bfd * abfd)
          len = strlen (current->name);
          if (len > SCNNMLEN)
            {
-             memset (section.s_name, 0, SCNNMLEN);
-             sprintf (section.s_name, "/%lu", (unsigned long) string_size);
+             /* The s_name field is defined to be NUL-padded but need not be
+                NUL-terminated.  We use a temporary buffer so that we can still
+                sprintf all eight chars without splatting a terminating NUL
+                over the first byte of the following member (s_paddr).  */
+             char s_name_buf[SCNNMLEN + 1];
+
+             /* An inherent limitation of the /nnnnnnn notation used to indicate
+                the offset of the long name in the string table is that we
+                cannot address entries beyone the ten million byte boundary.  */
+             if (string_size >= 10000000)
+               {
+                 bfd_set_error (bfd_error_file_too_big);
+                 (*_bfd_error_handler)
+                   (_("%B: section %s: string table overflow at offset %ld"),
+                   abfd, current->name, string_size);
+                 return FALSE;
+               }
+
+             /* snprintf not strictly necessary now we've verified the value
+                has less than eight ASCII digits, but never mind.  */
+             snprintf (s_name_buf, SCNNMLEN + 1, "/%lu", (unsigned long) string_size);
+             /* Then strncpy takes care of any padding for us.  */
+             strncpy (section.s_name, s_name_buf, SCNNMLEN);
              string_size += len + 1;
              long_section_names = TRUE;
            }