Skip to content

Latest commit

 

History

History
199 lines (190 loc) · 6.88 KB

glibc.diff

File metadata and controls

199 lines (190 loc) · 6.88 KB
 
Mar 4, 2015
Mar 4, 2015
1
2
3
4
diff -ruBb glibc-2.19-orig/elf/dl-load.c glibc-2.19/elf/dl-load.c
--- glibc-2.19-orig/elf/dl-load.c 2015-02-28 06:52:37.000000000 -0800
+++ glibc-2.19/elf/dl-load.c 2015-02-28 06:51:36.442857109 -0800
@@ -26,6 +26,7 @@
5
6
7
8
9
10
11
#include <unistd.h>
#include <ldsodefs.h>
#include <bits/wordsize.h>
+#include <bits/byteswap.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
Mar 4, 2015
Mar 4, 2015
12
@@ -131,6 +132,7 @@
13
14
15
16
17
18
19
# define FILEBUF_SIZE 832
#endif
char buf[FILEBUF_SIZE] __attribute__ ((aligned (__alignof (ElfW(Ehdr)))));
+ ElfW(Off) base_offset; /* for FatELF binaries. */
};
/* This is the decomposed LD_LIBRARY_PATH search path. */
Mar 4, 2015
Mar 4, 2015
20
@@ -1078,7 +1080,7 @@
21
22
23
24
25
26
27
28
else
{
phdr = alloca (maplength);
- __lseek (fd, header->e_phoff, SEEK_SET);
+ __lseek (fd, header->e_phoff + fbp->base_offset, SEEK_SET);
if ((size_t) __libc_read (fd, (void *) phdr, maplength) != maplength)
{
errstring = N_("cannot read file data");
Mar 4, 2015
Mar 4, 2015
29
@@ -1293,7 +1295,7 @@
30
31
32
33
34
35
36
37
l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength,
c->prot,
MAP_COPY|MAP_FILE,
- fd, c->mapoff);
+ fd, c->mapoff + fbp->base_offset);
if (__builtin_expect ((void *) l->l_map_start == MAP_FAILED, 0))
{
map_error:
Mar 4, 2015
Mar 4, 2015
38
@@ -1344,7 +1346,7 @@
39
40
41
42
43
44
45
46
&& (__mmap ((void *) (l->l_addr + c->mapstart),
c->mapend - c->mapstart, c->prot,
MAP_FIXED|MAP_COPY|MAP_FILE,
- fd, c->mapoff)
+ fd, c->mapoff + fbp->base_offset)
== MAP_FAILED))
goto map_error;
Mar 4, 2015
Mar 4, 2015
47
@@ -1862,6 +1864,85 @@
Mar 4, 2015
Mar 4, 2015
49
50
51
52
53
54
55
+#define ELF32_CLASS ELFCLASS32
+#define ELF64_CLASS ELFCLASS64
+#ifndef VALID_ELF_HEADER
+# define VALID_ELF_HEADER(hdr,exp,size) (memcmp (hdr, exp, size) == 0)
+# define VALID_ELF_OSABI(osabi) (osabi == ELFOSABI_SYSV)
Mar 4, 2015
Mar 4, 2015
56
+# define VALID_ELF_ABIVERSION(osabi,ver) (ver == 0)
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
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+#define le16_to_cpu(x) __bswap_16(x)
+#define le32_to_cpu(x) __bswap_32(x)
+#define le64_to_cpu(x) __bswap_64(x)
+#else
+#define le16_to_cpu(x) (x)
+#define le32_to_cpu(x) (x)
+#define le64_to_cpu(x) (x)
+#endif
+/* See if (fd) is a handle to a FatELF file. If so, seek to the start of
+ the ELF binary we want. Returns an error string, or NULL on success.
+ If this file isn't FatELF, we consider that a success condition. */
+static const char *
+examine_fatelf(const int fd, struct filebuf *fbp)
+{
+ const fatelf_header *header = (fatelf_header *) fbp->buf;
+ size_t records = (fbp->len - sizeof (fatelf_header)) / sizeof (fatelf_record);
+ ElfW(Ehdr) ehdr;
+ size_t i;
+
+ fbp->base_offset = 0; /* make sure this is sane. */
+
+ if (fbp->len < sizeof (fatelf_header))
+ return NULL; /* Not FatELF (probably not ELF either, but oh well.) */
+ else if (le32_to_cpu(header->magic) != FATELF_MAGIC)
+ return NULL; /* not FatELF; go on with normal ELF handling code. */
+ else if (le16_to_cpu(header->version) != FATELF_FORMAT_VERSION)
+ return N_("unrecognized FatELF format version");
+
+ /* XXX There may be up to 255 records, but usually there will be 2 to 5.
+ If this proves to be a problem, we can make the effort to load more data
+ from fd here. But right now, we fit between 21 and 34 records here! */
+ if (header->num_records < records)
+ records = (size_t) header->num_records;
+
+ memset((void *) &ehdr, '\0', sizeof (ehdr));
+
+ for (i = 0; i < records; i++)
+ {
+ const fatelf_record *record = &header->records[i];
+ const uint64_t offset = le64_to_cpu(record->offset);
+ const uint64_t size = le64_to_cpu(record->size);
+ const uint64_t end_offset = offset + size;
+
+ /* the only fields any of the elf_machine_matches_host()s care about. */
+ ehdr.e_machine = (ElfW(Half)) le16_to_cpu(record->machine);
Sep 17, 2009
Sep 17, 2009
104
105
+ ehdr.e_ident[EI_OSABI] = record->osabi;
+ ehdr.e_ident[EI_ABIVERSION] = record->osabi_version;
106
107
108
109
+ ehdr.e_ident[EI_CLASS] = record->word_size;
+ ehdr.e_ident[EI_DATA] = record->byte_order;
+
+ /* if we fail a test here, we just jump to the next record. */
Sep 17, 2009
Sep 17, 2009
110
+ if (!VALID_ELF_OSABI(record->osabi))
111
+ continue;
Mar 4, 2015
Mar 4, 2015
112
+ else if (!VALID_ELF_ABIVERSION(record->osabi, record->osabi_version))
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
+ continue;
+ else if (!elf_machine_matches_host(&ehdr))
+ continue;
+ else if (((ElfW(Off)) end_offset) < offset) /* overflow? */
+ continue;
+ else if (__lseek(fd, (off_t)le64_to_cpu(record->offset), SEEK_SET) == -1)
+ continue;
+
+ /* reset fbp with the actual ELF data... */
+ fbp->base_offset = (ElfW(Off)) offset;
+ fbp->len = __libc_read(fd, fbp->buf, sizeof (fbp->buf));
+ return NULL; /* no error! */
+ }
+
+ return N_("No compatible ELF binaries in this FatELF file");
+}
+
/* Open a file and verify it is an ELF file for this architecture. We
ignore only ELF files for other architectures. Non-ELF files and
ELF files with different header information cause fatal errors since
Mar 4, 2015
Mar 4, 2015
133
134
135
@@ -1952,6 +2033,10 @@
}
while (__builtin_expect (fbp->len < sizeof (ElfW(Ehdr)), 0));
136
137
138
139
140
+ errstring = examine_fatelf(fd, fbp);
+ if (errstring)
+ goto call_lose;
+
Mar 4, 2015
Mar 4, 2015
141
/* This is where the ELF header is loaded. */
142
143
ehdr = (ElfW(Ehdr) *) fbp->buf;
Mar 4, 2015
Mar 4, 2015
144
@@ -2073,7 +2158,7 @@
145
146
147
148
149
150
151
152
else
{
phdr = alloca (maplength);
- __lseek (fd, ehdr->e_phoff, SEEK_SET);
+ __lseek (fd, ehdr->e_phoff + fbp->base_offset, SEEK_SET);
if ((size_t) __libc_read (fd, (void *) phdr, maplength) != maplength)
{
read_error:
Mar 4, 2015
Mar 4, 2015
153
@@ -2095,7 +2180,7 @@
154
155
156
157
158
159
160
161
else
{
abi_note = alloca (size);
- __lseek (fd, ph->p_offset, SEEK_SET);
+ __lseek (fd, ph->p_offset + fbp->base_offset, SEEK_SET);
if (__libc_read (fd, (void *) abi_note, size) != size)
goto read_error;
}
Mar 4, 2015
Mar 4, 2015
162
163
164
165
diff -ruBb glibc-2.19-orig/elf/elf.h glibc-2.19/elf/elf.h
--- glibc-2.19-orig/elf/elf.h 2015-02-28 06:52:37.000000000 -0800
+++ glibc-2.19/elf/elf.h 2015-02-28 06:49:49.410853919 -0800
@@ -59,6 +59,34 @@
166
167
168
169
170
171
172
173
174
175
typedef Elf32_Half Elf32_Versym;
typedef Elf64_Half Elf64_Versym;
+/* This is little endian on disk, and looks like "FA700E1F" in a hex editor. */
+#define FATELF_MAGIC (0x1F0E70FA)
+#define FATELF_FORMAT_VERSION (1)
+
+/* FatELF values on disk are always littleendian, and align like Elf64. */
+typedef struct
+{
Sep 17, 2009
Sep 17, 2009
176
177
178
179
180
181
182
+ uint16_t machine; /* maps to e_machine */
+ uint8_t osabi; /* maps to e_ident[EI_OSABI] */
+ uint8_t osabi_version; /* maps to e_ident[EI_ABIVERSION] */
+ uint8_t word_size; /* maps to e_ident[EI_CLASS] */
+ uint8_t byte_order; /* maps to e_ident[EI_DATA] */
+ uint8_t reserved0;
+ uint8_t reserved1;
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
+ uint64_t offset;
+ uint64_t size;
+} fatelf_record;
+
+/* FatELF values on disk are always littleendian, and align like Elf64. */
+typedef struct
+{
+ uint32_t magic; /* always FATELF_MAGIC */
+ uint16_t version; /* latest is always FATELF_FORMAT_VERSION */
+ uint8_t num_records;
+ uint8_t reserved0;
+ fatelf_record records[];
+} fatelf_header;
+
/* The ELF file header. This appears at the start of every ELF file. */