diff options
Diffstat (limited to 'binutils/patches/pr13534-02.diff')
-rw-r--r-- | binutils/patches/pr13534-02.diff | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/binutils/patches/pr13534-02.diff b/binutils/patches/pr13534-02.diff new file mode 100644 index 0000000..78e1879 --- /dev/null +++ b/binutils/patches/pr13534-02.diff @@ -0,0 +1,136 @@ +commit 433cc73f9df08a1435b4d07a7bd3eed20f0c3dcd +Author: Francois Gouget <fgouget@codeweavers.com> +Date: Tue Dec 20 19:39:41 2011 +0100 + + bfd: Refuse to create an invalid archive when an archive element is too big. + + The archive format stores element sizes as a 10 character string and thus cannot handle anything 10GB or more. + +diff --git a/bfd/archive.c b/bfd/archive.c +index 5c5b3d4..05aba6c 100644 +--- a/bfd/archive.c ++++ b/bfd/archive.c +@@ -179,13 +179,18 @@ _bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val) + memcpy (p, buf, n); + } + +-void ++int + _bfd_ar_sizepad (char *p, size_t n, bfd_size_type size) + { + static char buf[21]; + size_t len; + snprintf (buf, sizeof (buf), "%-10" BFD_VMA_FMT "u", size); + len = strlen (buf); ++ if (len > n) ++ { ++ bfd_set_error(bfd_error_file_too_big); ++ return 0; ++ } + if (len < n) + { + memcpy (p, buf, len); +@@ -193,6 +198,7 @@ _bfd_ar_sizepad (char *p, size_t n, bfd_size_type size) + } + else + memcpy (p, buf, n); ++ return 1; + } + + bfd_boolean +@@ -1786,8 +1792,9 @@ _bfd_bsd44_write_ar_hdr (bfd *archive, bfd *abfd) + + BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size); + +- _bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), +- arch_eltdata (abfd)->parsed_size + padded_len); ++ if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), ++ arch_eltdata (abfd)->parsed_size + padded_len)) ++ return FALSE; + + if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr)) + return FALSE; +@@ -1907,8 +1914,8 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member) + status.st_gid); + _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo", + status.st_mode); +- _bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), +- status.st_size); ++ if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), status.st_size)) ++ return NULL; + memcpy (hdr->ar_fmag, ARFMAG, 2); + ared->parsed_size = status.st_size; + ared->arch_header = (char *) hdr; +@@ -2148,8 +2155,9 @@ _bfd_write_archive_contents (bfd *arch) + memset (&hdr, ' ', sizeof (struct ar_hdr)); + memcpy (hdr.ar_name, ename, strlen (ename)); + /* Round size up to even number in archive header. */ +- _bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), +- (elength + 1) & ~(bfd_size_type) 1); ++ if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), ++ (elength + 1) & ~(bfd_size_type) 1)) ++ return FALSE; + memcpy (hdr.ar_fmag, ARFMAG, 2); + if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) + != sizeof (struct ar_hdr)) +@@ -2425,7 +2433,8 @@ bsd_write_armap (bfd *arch, + bfd_ardata (arch)->armap_timestamp); + _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid); + _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", gid); +- _bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize); ++ if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize)) ++ return FALSE; + memcpy (hdr.ar_fmag, ARFMAG, 2); + if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) + != sizeof (struct ar_hdr)) +@@ -2580,7 +2589,8 @@ coff_write_armap (bfd *arch, + + memset (&hdr, ' ', sizeof (struct ar_hdr)); + hdr.ar_name[0] = '/'; +- _bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize); ++ if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize)) ++ return FALSE; + _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", + ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0 + ? time (NULL) : 0)); +diff --git a/bfd/archive64.c b/bfd/archive64.c +index a906508..bdbda0a 100644 +--- a/bfd/archive64.c ++++ b/bfd/archive64.c +@@ -169,8 +169,8 @@ bfd_elf64_archive_write_armap (bfd *arch, + + memset (&hdr, ' ', sizeof (struct ar_hdr)); + memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/")); +- _bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), +- mapsize); ++ if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize)) ++ return FALSE; + _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", + time (NULL)); + /* This, at least, is what Intel coff sets the values to.: */ +diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h +index 57197ac..a4ba4b6 100644 +--- a/bfd/libbfd-in.h ++++ b/bfd/libbfd-in.h +@@ -203,7 +203,7 @@ extern void *_bfd_generic_read_ar_hdr + (bfd *); + extern void _bfd_ar_spacepad + (char *, size_t, const char *, long); +-extern void _bfd_ar_sizepad ++extern int _bfd_ar_sizepad + (char *, size_t, bfd_size_type); + + extern void *_bfd_generic_read_ar_hdr_mag +diff --git a/bfd/libbfd.h b/bfd/libbfd.h +index 121e865..7f142d0 100644 +--- a/bfd/libbfd.h ++++ b/bfd/libbfd.h +@@ -208,7 +208,7 @@ extern void *_bfd_generic_read_ar_hdr + (bfd *); + extern void _bfd_ar_spacepad + (char *, size_t, const char *, long); +-extern void _bfd_ar_sizepad ++extern int _bfd_ar_sizepad + (char *, size_t, bfd_size_type); + + extern void *_bfd_generic_read_ar_hdr_mag |