summaryrefslogtreecommitdiff
path: root/binutils/patches/pr13534-02.diff
blob: 78e18790eac79b85656bc81c02ba5d48363cc869 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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