mirror of
https://frontier.innolan.net/github/amigaos-binutils.git
synced 2026-09-12 02:01:42 +00:00
- backported function _bfd_ar_spacepad() from newer binutils versions in archive.c which fixes buffer overflow problems in these older versions of binutils.
This commit is contained in:
+48
-51
@@ -173,6 +173,22 @@ static const char *normalize
|
||||
static struct areltdata *bfd_ar_hdr_from_filesystem
|
||||
PARAMS ((bfd *abfd, const char *, bfd *member));
|
||||
|
||||
void
|
||||
_bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val)
|
||||
{
|
||||
static char buf[20];
|
||||
size_t len;
|
||||
snprintf (buf, sizeof (buf), fmt, val);
|
||||
len = strlen (buf);
|
||||
if (len < n)
|
||||
{
|
||||
memcpy (p, buf, len);
|
||||
memset (p + len, ' ', n - len);
|
||||
}
|
||||
else
|
||||
memcpy (p, buf, n);
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
_bfd_generic_mkarchive (abfd)
|
||||
bfd *abfd;
|
||||
@@ -1327,17 +1343,8 @@ _bfd_construct_extended_name_table (abfd, trailing_slash, tabloc, tablen)
|
||||
strptr[thislen + 1] = '\012';
|
||||
}
|
||||
hdr->ar_name[0] = ar_padchar (current);
|
||||
/* We know there will always be enough room (one of the few
|
||||
cases where you may safely use sprintf). */
|
||||
sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc));
|
||||
/* Kinda Kludgy. We should just use the returned value of
|
||||
sprintf but not all implementations get this right. */
|
||||
{
|
||||
char *temp = hdr->ar_name + 2;
|
||||
for (; temp < hdr->ar_name + maxname; temp++)
|
||||
if (*temp == '\0')
|
||||
*temp = ' ';
|
||||
}
|
||||
_bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld",
|
||||
strptr - *tabloc);
|
||||
strptr += thislen + 1;
|
||||
if (trailing_slash)
|
||||
++strptr;
|
||||
@@ -1417,10 +1424,8 @@ bfd_ar_hdr_from_filesystem (abfd, filename, member)
|
||||
/* ar headers are space padded, not null padded! */
|
||||
memset ((PTR) hdr, ' ', sizeof (struct ar_hdr));
|
||||
|
||||
strncpy (hdr->ar_fmag, ARFMAG, 2);
|
||||
|
||||
/* Goddamned sprintf doesn't permit MAXIMUM field lengths. */
|
||||
sprintf ((hdr->ar_date), "%-12ld", (long) status.st_mtime);
|
||||
_bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld",
|
||||
status.st_mtime);
|
||||
#ifdef HPUX_LARGE_AR_IDS
|
||||
/* HP has a very "special" way to handle UID/GID's with numeric values
|
||||
> 99999. */
|
||||
@@ -1428,7 +1433,8 @@ bfd_ar_hdr_from_filesystem (abfd, filename, member)
|
||||
hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_uid);
|
||||
else
|
||||
#endif
|
||||
sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid);
|
||||
_bfd_ar_spacepad (hdr->ar_uid, sizeof (hdr->ar_uid), "%ld",
|
||||
status.st_uid);
|
||||
#ifdef HPUX_LARGE_AR_IDS
|
||||
/* HP has a very "special" way to handle UID/GID's with numeric values
|
||||
> 99999. */
|
||||
@@ -1436,20 +1442,13 @@ bfd_ar_hdr_from_filesystem (abfd, filename, member)
|
||||
hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_gid);
|
||||
else
|
||||
#endif
|
||||
sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid);
|
||||
sprintf ((hdr->ar_mode), "%-8o", (unsigned int) status.st_mode);
|
||||
sprintf ((hdr->ar_size), "%-10ld", (long) status.st_size);
|
||||
/* Correct for a lossage in sprintf whereby it null-terminates. I cannot
|
||||
understand how these C losers could design such a ramshackle bunch of
|
||||
IO operations. */
|
||||
temp = (char *) hdr;
|
||||
temp1 = temp + sizeof (struct ar_hdr) - 2;
|
||||
for (; temp < temp1; temp++)
|
||||
{
|
||||
if (*temp == '\0')
|
||||
*temp = ' ';
|
||||
}
|
||||
strncpy (hdr->ar_fmag, ARFMAG, 2);
|
||||
_bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld",
|
||||
status.st_gid);
|
||||
_bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
|
||||
status.st_mode);
|
||||
_bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
|
||||
status.st_size);
|
||||
memcpy (hdr->ar_fmag, ARFMAG, 2);
|
||||
ared->parsed_size = status.st_size;
|
||||
ared->arch_header = (char *) hdr;
|
||||
|
||||
@@ -1754,12 +1753,9 @@ _bfd_write_archive_contents (arch)
|
||||
memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
|
||||
strcpy (hdr.ar_name, ename);
|
||||
/* Round size up to even number in archive header. */
|
||||
sprintf (&(hdr.ar_size[0]), "%-10d",
|
||||
(int) ((elength + 1) & ~(bfd_size_type) 1));
|
||||
strncpy (hdr.ar_fmag, ARFMAG, 2);
|
||||
for (i = 0; i < sizeof (struct ar_hdr); i++)
|
||||
if (((char *) (&hdr))[i] == '\0')
|
||||
(((char *) (&hdr))[i]) = ' ';
|
||||
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
|
||||
(elength + 1) & ~(bfd_size_type) 1);
|
||||
memcpy (hdr.ar_fmag, ARFMAG, 2);
|
||||
if ((bfd_bwrite ((PTR) &hdr, (bfd_size_type) sizeof (struct ar_hdr), arch)
|
||||
!= sizeof (struct ar_hdr))
|
||||
|| bfd_bwrite (etable, elength, arch) != elength)
|
||||
@@ -2007,11 +2003,12 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
|
||||
bfd_ardata (arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET;
|
||||
bfd_ardata (arch)->armap_datepos = (SARMAG
|
||||
+ offsetof (struct ar_hdr, ar_date[0]));
|
||||
sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp);
|
||||
sprintf (hdr.ar_uid, "%ld", (long) getuid ());
|
||||
sprintf (hdr.ar_gid, "%ld", (long) getgid ());
|
||||
sprintf (hdr.ar_size, "%-10d", (int) mapsize);
|
||||
strncpy (hdr.ar_fmag, ARFMAG, 2);
|
||||
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
|
||||
bfd_ardata (arch)->armap_timestamp);
|
||||
_bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", getuid ());
|
||||
_bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", getgid ());
|
||||
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);
|
||||
memcpy (hdr.ar_fmag, ARFMAG, 2);
|
||||
for (i = 0; i < sizeof (struct ar_hdr); i++)
|
||||
if (((char *) (&hdr))[i] == '\0')
|
||||
(((char *) (&hdr))[i]) = ' ';
|
||||
@@ -2101,10 +2098,8 @@ _bfd_archive_bsd_update_armap_timestamp (arch)
|
||||
|
||||
/* Prepare an ASCII version suitable for writing. */
|
||||
memset (hdr.ar_date, 0, sizeof (hdr.ar_date));
|
||||
sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp);
|
||||
for (i = 0; i < sizeof (hdr.ar_date); i++)
|
||||
if (hdr.ar_date[i] == '\0')
|
||||
(hdr.ar_date)[i] = ' ';
|
||||
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
|
||||
bfd_ardata (arch)->armap_timestamp);
|
||||
|
||||
/* Write it into the file. */
|
||||
bfd_ardata (arch)->armap_datepos = (SARMAG
|
||||
@@ -2168,13 +2163,15 @@ coff_write_armap (arch, elength, map, symbol_count, stridx)
|
||||
|
||||
memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
|
||||
hdr.ar_name[0] = '/';
|
||||
sprintf (hdr.ar_size, "%-10d", (int) mapsize);
|
||||
sprintf (hdr.ar_date, "%ld", (long) time (NULL));
|
||||
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
|
||||
mapsize);
|
||||
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
|
||||
time (NULL));
|
||||
/* This, at least, is what Intel coff sets the values to. */
|
||||
sprintf ((hdr.ar_uid), "%d", 0);
|
||||
sprintf ((hdr.ar_gid), "%d", 0);
|
||||
sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
|
||||
strncpy (hdr.ar_fmag, ARFMAG, 2);
|
||||
_bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
|
||||
_bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
|
||||
_bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
|
||||
memcpy (hdr.ar_fmag, ARFMAG, 2);
|
||||
|
||||
for (i = 0; i < sizeof (struct ar_hdr); i++)
|
||||
if (((char *) (&hdr))[i] == '\0')
|
||||
|
||||
Reference in New Issue
Block a user