Gentoo Archives: gentoo-commits

From: "Anthony G. Basile" <blueness@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/elfix:master commit in: /
Date: Thu, 05 May 2011 19:47:06
Message-Id: 1fe9aab862a37ebb377333133560b7790324eb2b.blueness@gentoo
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