1 |
commit: 1fe9aab862a37ebb377333133560b7790324eb2b |
2 |
Author: Anthony G. Basile <basile <AT> opensource <DOT> dyc <DOT> edu> |
3 |
AuthorDate: Thu May 5 19:46:23 2011 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu May 5 19:46:23 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=1fe9aab8 |
7 |
|
8 |
poc/mangle-paxflags.c: remove EI_PAX and PT_PAX_FLAGS from an elf |
9 |
|
10 |
|
11 |
Makefile.am | 5 +- |
12 |
configure.ac | 14 +++ |
13 |
poc/Makefile.am | 26 +++++ |
14 |
tests/bad-gnustack.c => poc/bad-mmap.c | 15 ++- |
15 |
poc/mangle-paxflags.c | 181 ++++++++++++++++++++++++++++++++ |
16 |
tests/Makefile.am | 1 - |
17 |
tests/bad-gnustack.c | 2 +- |
18 |
tests/bad32.asm | 2 +- |
19 |
tests/bad64.asm | 2 +- |
20 |
9 files changed, 240 insertions(+), 8 deletions(-) |
21 |
|
22 |
diff --cc poc/Makefile.am |
23 |
index 0000000,b5d0ae7..e8c94d5 |
24 |
mode 000000,100644..100644 |
25 |
--- a/poc/Makefile.am |
26 |
+++ b/poc/Makefile.am |
27 |
@@@ -1,0 -1,4 +1,26 @@@ |
28 |
+ noinst_PROGRAMS = mangle-paxflags bad-mmap |
29 |
+ mangle_paxflags_SOURCES = mangle-paxflags.c |
30 |
+ mangle_paxflags_LDADD = -lelf |
31 |
+ bad_mmap_SOURCES = bad-mmap.c |
32 |
++ |
33 |
++check_SCRIPTS = poc.sh |
34 |
++ |
35 |
++poc.sh: |
36 |
++ @echo "================================================================================" |
37 |
++ @echo |
38 |
++ ./mangle-paxflags bad-mmap |
39 |
++ ./bad-mmap |
40 |
++ @echo |
41 |
++ @echo "========================================" |
42 |
++ @echo |
43 |
++ ./mangle-paxflags -p bad-mmap |
44 |
++ ./mangle-paxflags bad-mmap |
45 |
++ ./bad-mmap |
46 |
++ @echo |
47 |
++ @echo "========================================" |
48 |
++ @echo |
49 |
++ ./mangle-paxflags -e bad-mmap |
50 |
++ ./mangle-paxflags bad-mmap |
51 |
++ ./bad-mmap |
52 |
++ @echo |
53 |
++ @echo "================================================================================" |
54 |
diff --cc poc/bad-mmap.c |
55 |
index 74105ed,c459abb..04df26d |
56 |
--- a/poc/bad-mmap.c |
57 |
+++ b/poc/bad-mmap.c |
58 |
@@@ -1,24 -1,20 +1,33 @@@ |
59 |
+/* |
60 |
- bad.c: C source for sample elf with X on GNU_STACK |
61 |
++ bad-mmap.c: create 4k anonymous mmap with RWX protection |
62 |
+ Copyright (C) 2011 Anthony G. Basile |
63 |
+ |
64 |
+ This program is free software: you can redistribute it and/or modify |
65 |
+ it under the terms of the GNU General Public License as published by |
66 |
+ the Free Software Foundation, either version 3 of the License, or |
67 |
+ (at your option) any later version. |
68 |
+ |
69 |
+ This program is distributed in the hope that it will be useful, |
70 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
71 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
72 |
+ GNU General Public License for more details. |
73 |
+ |
74 |
+ You should have received a copy of the GNU General Public License |
75 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>. |
76 |
+*/ |
77 |
++ |
78 |
+ #include <stdio.h> |
79 |
#include <stdlib.h> |
80 |
+ #include <sys/mman.h> |
81 |
+ #include <errno.h> |
82 |
+ #include <string.h> |
83 |
|
84 |
- int main() |
85 |
+ int |
86 |
+ main() |
87 |
{ |
88 |
- badness(); |
89 |
+ if( mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) != MAP_FAILED ) |
90 |
- { |
91 |
+ printf("mmap(): succeeded\n"); |
92 |
- return 0; |
93 |
- } |
94 |
+ else |
95 |
- { |
96 |
+ printf("mmap(): %s\n", strerror(errno)); |
97 |
- return 1; |
98 |
- } |
99 |
+ return 0; |
100 |
} |
101 |
diff --cc poc/mangle-paxflags.c |
102 |
index 0000000,9d59a96..76fe56b |
103 |
mode 000000,100644..100644 |
104 |
--- a/poc/mangle-paxflags.c |
105 |
+++ b/poc/mangle-paxflags.c |
106 |
@@@ -1,0 -1,72 +1,181 @@@ |
107 |
+ /* |
108 |
- fix-gnustack.c: check and optionally remove exec flag on Elf GNU_STACK |
109 |
++ mangle-paxflags.c: check and optionally remove EI_PAX and/or PT_PAX_FLAGS |
110 |
+ Copyright (C) 2011 Anthony G. Basile |
111 |
+ |
112 |
+ This program is free software: you can redistribute it and/or modify |
113 |
+ it under the terms of the GNU General Public License as published by |
114 |
+ the Free Software Foundation, either version 3 of the License, or |
115 |
+ (at your option) any later version. |
116 |
+ |
117 |
+ This program is distributed in the hope that it will be useful, |
118 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
119 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
120 |
+ GNU General Public License for more details. |
121 |
+ |
122 |
+ You should have received a copy of the GNU General Public License |
123 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>. |
124 |
+ */ |
125 |
+ |
126 |
+ #include <stdio.h> |
127 |
+ #include <stdlib.h> |
128 |
+ #include <string.h> |
129 |
+ #include <error.h> |
130 |
+ |
131 |
+ #include <gelf.h> |
132 |
+ |
133 |
+ #include <sys/types.h> |
134 |
+ #include <sys/stat.h> |
135 |
+ #include <fcntl.h> |
136 |
+ #include <unistd.h> |
137 |
+ |
138 |
++// From chpax.h |
139 |
++#define EI_PAX 14 // Index in e_ident[] where to read flags |
140 |
++#define HF_PAX_PAGEEXEC 1 // 0: Paging based non-exec pages |
141 |
++#define HF_PAX_EMUTRAMP 2 // 0: Emulate trampolines |
142 |
++#define HF_PAX_MPROTECT 4 // 0: Restrict mprotect() |
143 |
++#define HF_PAX_RANDMMAP 8 // 0: Randomize mmap() base |
144 |
++#define HF_PAX_RANDEXEC 16 // 1: Randomize ET_EXEC base |
145 |
++#define HF_PAX_SEGMEXEC 32 // 0: Segmentation based non-exec pages |
146 |
++ |
147 |
++ |
148 |
++#define PRINT(E,F,I) printf("%s: %s\n", #E, E & F ? ( I ? "enabled" : "disabled" ) : ( I ? "disabled" : "enabled" ) ); |
149 |
++#define CASE(N,P) case P: printf("%d: %s\n", (int)N, #P); break |
150 |
++ |
151 |
++ |
152 |
++char * |
153 |
++parse_cmd_args( int c, char *v[], int *flag_ei_pax, int *flag_pt_pax_flags ) |
154 |
++{ |
155 |
++ int i, oc; |
156 |
++ |
157 |
++ if((c != 2)&&(c != 3)&&(c != 4)) |
158 |
++ error(EXIT_FAILURE, 0, "Usage: %s [-e] [-p] elffile", v[0]); |
159 |
++ |
160 |
++ *flag_ei_pax = 0; |
161 |
++ *flag_pt_pax_flags = 0; |
162 |
++ while((oc = getopt(c, v,":ep")) != -1) |
163 |
++ switch(oc) |
164 |
++ { |
165 |
++ case 'e': |
166 |
++ *flag_ei_pax = 1; |
167 |
++ break ; |
168 |
++ case 'p': |
169 |
++ *flag_pt_pax_flags = 1; |
170 |
++ break; |
171 |
++ case '?': |
172 |
++ default: |
173 |
++ error(EXIT_FAILURE, 0, "option -%c is invalid: ignored.", optopt ) ; |
174 |
++ } |
175 |
++ |
176 |
++ return v[optind] ; |
177 |
++} |
178 |
+ |
179 |
+ |
180 |
+ int |
181 |
+ main( int argc, char *argv[]) |
182 |
+ { |
183 |
+ int fd; |
184 |
++ int flag_ei_pax, flag_pt_pax_flags; |
185 |
++ int found_ei_pax, found_pt_pax_flags; |
186 |
+ char *f_name; |
187 |
+ size_t i, phnum; |
188 |
+ |
189 |
+ Elf *elf; |
190 |
++ GElf_Ehdr ehdr; |
191 |
+ GElf_Phdr phdr; |
192 |
+ |
193 |
- f_name = argv[1]; |
194 |
++ f_name = parse_cmd_args( argc, argv, &flag_ei_pax, &flag_pt_pax_flags ); |
195 |
+ |
196 |
+ if(elf_version(EV_CURRENT) == EV_NONE) |
197 |
+ error(EXIT_FAILURE, 0, "Library out of date."); |
198 |
+ |
199 |
- if((fd = open(f_name, O_RDWR)) < 0) |
200 |
- error(EXIT_FAILURE, 0, "open() fail."); |
201 |
- if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL) |
202 |
- error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(-1)); |
203 |
++ if( flag_ei_pax || flag_pt_pax_flags ) |
204 |
++ { |
205 |
++ if((fd = open(f_name, O_RDWR)) < 0) |
206 |
++ error(EXIT_FAILURE, 0, "open() fail."); |
207 |
++ if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL) |
208 |
++ error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(elf_errno())); |
209 |
++ } |
210 |
++ else |
211 |
++ { |
212 |
++ if((fd = open(f_name, O_RDONLY)) < 0) |
213 |
++ error(EXIT_FAILURE, 0, "open() fail."); |
214 |
++ if((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) |
215 |
++ error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(elf_errno())); |
216 |
++ } |
217 |
++ |
218 |
+ if(elf_kind(elf) != ELF_K_ELF) |
219 |
+ error(EXIT_FAILURE, 0, "elf_kind() fail: this is not an elf file."); |
220 |
+ |
221 |
++ if(gelf_getehdr(elf,&ehdr) != &ehdr) |
222 |
++ error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno())); |
223 |
++ |
224 |
++ found_ei_pax = ((u_long) ehdr.e_ident[EI_PAX + 1] << 8) + (u_long) ehdr.e_ident[EI_PAX]; |
225 |
++ |
226 |
++ printf("==== EI_PAX ====\n") ; |
227 |
++ PRINT(HF_PAX_PAGEEXEC, found_ei_pax, 0); |
228 |
++ PRINT(HF_PAX_EMUTRAMP, found_ei_pax, 1); |
229 |
++ PRINT(HF_PAX_MPROTECT, found_ei_pax, 0); |
230 |
++ PRINT(HF_PAX_RANDMMAP, found_ei_pax, 0); |
231 |
++ PRINT(HF_PAX_RANDEXEC, found_ei_pax, 1); |
232 |
++ PRINT(HF_PAX_SEGMEXEC, found_ei_pax, 0); |
233 |
++ printf("\n"); |
234 |
++ |
235 |
++ if( flag_ei_pax ) |
236 |
++ { |
237 |
++ printf("Disabling EI_PAX\n\n"); |
238 |
++ ehdr.e_ident[EI_PAX] = 0xFF; |
239 |
++ ehdr.e_ident[EI_PAX + 1] = 0xFF; |
240 |
++ if(!gelf_update_ehdr(elf, &ehdr)) |
241 |
++ error(EXIT_FAILURE, 0, "gelf_update_ehdr(): %s", elf_errmsg(elf_errno())); |
242 |
++ } |
243 |
++ |
244 |
++ printf("==== PHRDs ====\n") ; |
245 |
++ found_pt_pax_flags = 0 ; |
246 |
+ elf_getphdrnum(elf, &phnum); |
247 |
+ for(i=0; i<phnum; ++i) |
248 |
+ { |
249 |
+ if(gelf_getphdr(elf, i, &phdr) != &phdr) |
250 |
- error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(-1)); |
251 |
++ error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno())); |
252 |
++ |
253 |
++ switch(phdr.p_type) |
254 |
++ { |
255 |
++ CASE(i,PT_NULL); |
256 |
++ CASE(i,PT_LOAD); |
257 |
++ CASE(i,PT_DYNAMIC); |
258 |
++ CASE(i,PT_INTERP); |
259 |
++ CASE(i,PT_NOTE); |
260 |
++ CASE(i,PT_SHLIB); |
261 |
++ CASE(i,PT_PHDR); |
262 |
++ CASE(i,PT_TLS); |
263 |
++ CASE(i,PT_NUM); |
264 |
++ CASE(i,PT_LOOS); |
265 |
++ CASE(i,PT_GNU_EH_FRAME); |
266 |
++ CASE(i,PT_GNU_STACK); |
267 |
++ CASE(i,PT_GNU_RELRO); |
268 |
++ CASE(i,PT_PAX_FLAGS); |
269 |
++ CASE(i,PT_LOSUNW); |
270 |
++ //CASE(i,PT_SUNWBSS); |
271 |
++ CASE(i,PT_SUNWSTACK); |
272 |
++ CASE(i,PT_HISUNW); |
273 |
++ //CASE(i,PT_HIOS); |
274 |
++ CASE(i,PT_LOPROC); |
275 |
++ CASE(i,PT_HIPROC); |
276 |
++ } |
277 |
+ |
278 |
- if(phdr.p_type == PT_PAX_FLAGS) |
279 |
++ if((phdr.p_type == PT_PAX_FLAGS) && flag_pt_pax_flags ) |
280 |
+ { |
281 |
- printf("Found PT_PAX_FLAGS\n"); |
282 |
++ found_pt_pax_flags = 1 ; |
283 |
+ phdr.p_type = PT_NULL; |
284 |
+ if(!gelf_update_phdr(elf, i, &phdr)) |
285 |
- error(EXIT_FAILURE, 0, "gelf_update_phdr(): %s", elf_errmsg(-1)); |
286 |
++ error(EXIT_FAILURE, 0, "gelf_update_phdr(): %s", elf_errmsg(elf_errno())); |
287 |
+ } |
288 |
+ } |
289 |
+ |
290 |
++ if( found_pt_pax_flags ) |
291 |
++ printf("Setting PT_PAX_FLAGS to PT_NULL\n\n"); |
292 |
++ else |
293 |
++ printf("\n\n"); |
294 |
++ |
295 |
+ elf_end(elf); |
296 |
+ close(fd); |
297 |
+ } |
298 |
diff --cc tests/Makefile.am |
299 |
index ab23520,ab23520..59bf905 |
300 |
--- a/tests/Makefile.am |
301 |
+++ b/tests/Makefile.am |
302 |
@@@ -20,7 -20,7 +20,6 @@@ test.sh |
303 |
@echo |
304 |
@echo "Fixed Bad GNU_STACK Elf" |
305 |
@../src/fix-gnustack bad-gnustack |
306 |
-- @rm -f good |
307 |
@echo |
308 |
@echo "================================================================================" |
309 |
|
310 |
diff --cc tests/bad-gnustack.c |
311 |
index 74105ed,74105ed..fa7bcf5 |
312 |
--- a/tests/bad-gnustack.c |
313 |
+++ b/tests/bad-gnustack.c |
314 |
@@@ -1,5 -1,5 +1,5 @@@ |
315 |
/* |
316 |
-- bad.c: C source for sample elf with X on GNU_STACK |
317 |
++ bad-gnustack.c: C source for sample elf with X on GNU_STACK |
318 |
Copyright (C) 2011 Anthony G. Basile |
319 |
|
320 |
This program is free software: you can redistribute it and/or modify |
321 |
diff --cc tests/bad32.asm |
322 |
index df8296c,df8296c..8020ac7 |
323 |
--- a/tests/bad32.asm |
324 |
+++ b/tests/bad32.asm |
325 |
@@@ -1,4 -1,4 +1,4 @@@ |
326 |
--;test-bad32.asm: 32-bit asm source for sample elf with X on GNU_STACK |
327 |
++;bad32.asm: 32-bit asm source for sample elf with X on GNU_STACK |
328 |
;Copyright (C) 2011 Anthony G. Basile |
329 |
; |
330 |
;This program is free software: you can redistribute it and/or modify |
331 |
diff --cc tests/bad64.asm |
332 |
index 3a8af73,3a8af73..1164095 |
333 |
--- a/tests/bad64.asm |
334 |
+++ b/tests/bad64.asm |
335 |
@@@ -1,4 -1,4 +1,4 @@@ |
336 |
--;test-bad64.asm: 64-bit asm source for sample elf with X on GNU_STACK |
337 |
++;bad64.asm: 64-bit asm source for sample elf with X on GNU_STACK |
338 |
;Copyright (C) 2011 Anthony G. Basile |
339 |
; |
340 |
;This program is free software: you can redistribute it and/or modify |