1 |
commit: 28309dafebd27f7afbaee68d97b77fed68b04e99 |
2 |
Author: Anthony G. Basile <basile <AT> opensource <DOT> dyc <DOT> edu> |
3 |
AuthorDate: Fri May 6 02:43:01 2011 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri May 6 02:43:01 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=28309daf |
7 |
|
8 |
src/paxctl-ng.c: added help and create PT_PAX_FLAGS |
9 |
|
10 |
--- |
11 |
configure.ac | 2 +- |
12 |
poc/mangle-paxflags.c | 6 +- |
13 |
src/Makefile.am | 4 +- |
14 |
src/fix-gnustack.c | 2 +- |
15 |
poc/mangle-paxflags.c => src/paxctl-ng.c | 181 +++++++++++++++++++++++------ |
16 |
5 files changed, 151 insertions(+), 44 deletions(-) |
17 |
|
18 |
diff --git a/configure.ac b/configure.ac |
19 |
index 560cc82..15ffc03 100644 |
20 |
--- a/configure.ac |
21 |
+++ b/configure.ac |
22 |
@@ -11,7 +11,7 @@ AC_ARG_ENABLE( |
23 |
[tests], |
24 |
AS_HELP_STRING( |
25 |
[--enable-tests], |
26 |
- [enable tests] |
27 |
+ [perform tests] |
28 |
), |
29 |
[ |
30 |
AS_IF( |
31 |
|
32 |
diff --git a/poc/mangle-paxflags.c b/poc/mangle-paxflags.c |
33 |
index 301dad7..8e2607c 100644 |
34 |
--- a/poc/mangle-paxflags.c |
35 |
+++ b/poc/mangle-paxflags.c |
36 |
@@ -50,7 +50,7 @@ print_help(char *v) |
37 |
"Package Name : " PACKAGE_STRING "\n" |
38 |
"Bug Reports : " PACKAGE_BUGREPORT "\n" |
39 |
"Description : Check for, or conditionally remove, executable flag from PT_GNU_STACK\n\n" |
40 |
- "Usage : %s {-h | [-e] [-p] ELFfile}\n" |
41 |
+ "Usage : %s {[-e] [-p] ELFfile | -h}\n" |
42 |
"options : Print out EI_PAX and PT_PAX_FLAGS information\n" |
43 |
" : -e Set all EI_PAX flags to least secure setting, pEmrXs\n" |
44 |
" : -p Remove PT_PAX_FLAGS program header\n" |
45 |
@@ -105,7 +105,7 @@ main( int argc, char *argv[]) |
46 |
GElf_Ehdr ehdr; |
47 |
GElf_Phdr phdr; |
48 |
|
49 |
- f_name = parse_cmd_args( argc, argv, &flag_ei_pax, &flag_pt_pax_flags ); |
50 |
+ f_name = parse_cmd_args(argc, argv, &flag_ei_pax, &flag_pt_pax_flags); |
51 |
|
52 |
if(elf_version(EV_CURRENT) == EV_NONE) |
53 |
error(EXIT_FAILURE, 0, "Library out of date."); |
54 |
@@ -129,7 +129,7 @@ main( int argc, char *argv[]) |
55 |
error(EXIT_FAILURE, 0, "elf_kind() fail: this is not an elf file."); |
56 |
|
57 |
if(gelf_getehdr(elf,&ehdr) != &ehdr) |
58 |
- error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno())); |
59 |
+ error(EXIT_FAILURE, 0, "gelf_getehdr(): %s", elf_errmsg(elf_errno())); |
60 |
|
61 |
found_ei_pax = ((u_long) ehdr.e_ident[EI_PAX + 1] << 8) + (u_long) ehdr.e_ident[EI_PAX]; |
62 |
|
63 |
|
64 |
diff --git a/src/Makefile.am b/src/Makefile.am |
65 |
index e63a5f2..8e4709c 100644 |
66 |
--- a/src/Makefile.am |
67 |
+++ b/src/Makefile.am |
68 |
@@ -1,3 +1,5 @@ |
69 |
-bin_PROGRAMS = fix-gnustack |
70 |
+bin_PROGRAMS = fix-gnustack paxctl-ng |
71 |
fix_gnustack_SOURCES = fix-gnustack.c |
72 |
fix_gnustack_LDADD = -lelf |
73 |
+paxctl_ng_SOURCES = paxctl-ng.c |
74 |
+paxctl_ng_LDADD = -lelf |
75 |
|
76 |
diff --git a/src/fix-gnustack.c b/src/fix-gnustack.c |
77 |
index 02eb4d5..2afd7da 100644 |
78 |
--- a/src/fix-gnustack.c |
79 |
+++ b/src/fix-gnustack.c |
80 |
@@ -87,7 +87,7 @@ main( int argc, char *argv[]) |
81 |
Elf *elf; |
82 |
GElf_Phdr phdr; |
83 |
|
84 |
- f_name = parse_cmd_args( argc, argv, &flagv ); |
85 |
+ f_name = parse_cmd_args(argc, argv, &flagv); |
86 |
|
87 |
if(elf_version(EV_CURRENT) == EV_NONE) |
88 |
error(EXIT_FAILURE, 0, "Library out of date."); |
89 |
|
90 |
diff --git a/poc/mangle-paxflags.c b/src/paxctl-ng.c |
91 |
similarity index 56% |
92 |
copy from poc/mangle-paxflags.c |
93 |
copy to src/paxctl-ng.c |
94 |
index 301dad7..9f1b86a 100644 |
95 |
--- a/poc/mangle-paxflags.c |
96 |
+++ b/src/paxctl-ng.c |
97 |
@@ -1,5 +1,5 @@ |
98 |
/* |
99 |
- mangle-paxflags.c: check and optionally remove EI_PAX and/or PT_PAX_FLAGS |
100 |
+ paxctl-ng.c: get/set pax flags on an ELF object |
101 |
Copyright (C) 2011 Anthony G. Basile |
102 |
|
103 |
This program is free software: you can redistribute it and/or modify |
104 |
@@ -30,14 +30,7 @@ |
105 |
|
106 |
#include <config.h> |
107 |
|
108 |
-// From chpax.h |
109 |
-#define EI_PAX 14 // Index in e_ident[] where to read flags |
110 |
-#define HF_PAX_PAGEEXEC 1 // 0: Paging based non-exec pages |
111 |
-#define HF_PAX_EMUTRAMP 2 // 0: Emulate trampolines |
112 |
-#define HF_PAX_MPROTECT 4 // 0: Restrict mprotect() |
113 |
-#define HF_PAX_RANDMMAP 8 // 0: Randomize mmap() base |
114 |
-#define HF_PAX_RANDEXEC 16 // 1: Randomize ET_EXEC base |
115 |
-#define HF_PAX_SEGMEXEC 32 // 0: Segmentation based non-exec pages |
116 |
+#define EI_PAX 14 // Index in e_ident[] where to read flags - from chpax.h |
117 |
|
118 |
#define PRINT(E,F,I) printf("%s:\t%s\n", #E, E & F ? ( I ? "enabled" : "disabled" ) : ( I ? "disabled" : "enabled" ) ); |
119 |
#define CASE(N,P) case P: printf("%d: %s\n", (int)N, #P); break |
120 |
@@ -49,11 +42,17 @@ print_help(char *v) |
121 |
printf( |
122 |
"Package Name : " PACKAGE_STRING "\n" |
123 |
"Bug Reports : " PACKAGE_BUGREPORT "\n" |
124 |
- "Description : Check for, or conditionally remove, executable flag from PT_GNU_STACK\n\n" |
125 |
- "Usage : %s {-h | [-e] [-p] ELFfile}\n" |
126 |
- "options : Print out EI_PAX and PT_PAX_FLAGS information\n" |
127 |
- " : -e Set all EI_PAX flags to least secure setting, pEmrXs\n" |
128 |
- " : -p Remove PT_PAX_FLAGS program header\n" |
129 |
+ "Description : Get or set pax flags on an ELF object\n\n" |
130 |
+ "Usage : %s {[-pPeEmMrRxXsSzZC] ELFfile | [-h]}\n" |
131 |
+ "options : Print out pax flag information\n" |
132 |
+ " : -p Disable PAGEEXEC\t-P Enable PAGEEXEC\n" |
133 |
+ " : -e Disable EMUTRAMP\t-E Enable EMUTRAMP\n" |
134 |
+ " : -m Disable MPROTECT\t-M Enable MPROTECT\n" |
135 |
+ " : -r Disable RANDMMAP\t-R Enable RANDMMAP\n" |
136 |
+ " : -x Disable RANDEXEC\t-X Enable RANDEXEC\n" |
137 |
+ " : -s Disable SEGMEXEC\t-X Enable SEGMEXEC\n" |
138 |
+ " : -z Default least secure\t-Z Default most secure\n" |
139 |
+ " : -C Created PT_PAX_FLAGS program header\n" |
140 |
" : -h Print out this help\n", |
141 |
v |
142 |
); |
143 |
@@ -63,23 +62,48 @@ print_help(char *v) |
144 |
|
145 |
|
146 |
char * |
147 |
-parse_cmd_args( int c, char *v[], int *flag_ei_pax, int *flag_pt_pax_flags ) |
148 |
+parse_cmd_args( int c, char *v[], int *pax_flags, int *create_flag ) |
149 |
{ |
150 |
int i, oc; |
151 |
|
152 |
if((c != 2)&&(c != 3)&&(c != 4)) |
153 |
- error(EXIT_FAILURE, 0, "Usage: %s {[-e] [-p] ELFfile | [-h]}", v[0]); |
154 |
+ error(EXIT_FAILURE, 0, "Usage: %s {[-pPeEmMrRxXsSzZC] ELFfile | [-h]}", v[0]); |
155 |
|
156 |
- *flag_ei_pax = 0; |
157 |
- *flag_pt_pax_flags = 0; |
158 |
- while((oc = getopt(c, v,":eph")) != -1) |
159 |
+ *pax_flags = 0; |
160 |
+ *create_flag = 0; |
161 |
+ while((oc = getopt(c, v,":pPeEmMrRxXsSzZCh")) != -1) |
162 |
switch(oc) |
163 |
{ |
164 |
+ case 'p': |
165 |
+ break ; |
166 |
+ case 'P': |
167 |
+ break; |
168 |
case 'e': |
169 |
- *flag_ei_pax = 1; |
170 |
break ; |
171 |
- case 'p': |
172 |
- *flag_pt_pax_flags = 1; |
173 |
+ case 'E': |
174 |
+ break; |
175 |
+ case 'm': |
176 |
+ break ; |
177 |
+ case 'M': |
178 |
+ break; |
179 |
+ case 'r': |
180 |
+ break ; |
181 |
+ case 'R': |
182 |
+ break; |
183 |
+ case 'x': |
184 |
+ break ; |
185 |
+ case 'X': |
186 |
+ break; |
187 |
+ case 's': |
188 |
+ break ; |
189 |
+ case 'S': |
190 |
+ break; |
191 |
+ case 'z': |
192 |
+ break ; |
193 |
+ case 'Z': |
194 |
+ break; |
195 |
+ case 'C': |
196 |
+ *create_flag = 1; |
197 |
break; |
198 |
case 'h': |
199 |
print_help(v[0]); |
200 |
@@ -94,23 +118,83 @@ parse_cmd_args( int c, char *v[], int *flag_ei_pax, int *flag_pt_pax_flags ) |
201 |
|
202 |
|
203 |
int |
204 |
+no_pt_pax_flags(Elf *e) |
205 |
+{ |
206 |
+ size_t i, phnum; |
207 |
+ GElf_Phdr phdr; |
208 |
+ |
209 |
+ elf_getphdrnum(e, &phnum); |
210 |
+ for(i=0; i<phnum; ++i) |
211 |
+ { |
212 |
+ if(gelf_getphdr(e, i, &phdr) != &phdr) |
213 |
+ error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno())); |
214 |
+ if(phdr.p_type == PT_PAX_FLAGS) |
215 |
+ return 0; |
216 |
+ } |
217 |
+ return 1; |
218 |
+} |
219 |
+ |
220 |
+ |
221 |
+int |
222 |
+create_pt_pax_flags(Elf *e) |
223 |
+{ |
224 |
+ size_t i, phnum; |
225 |
+ GElf_Phdr phdr; |
226 |
+ |
227 |
+ elf_getphdrnum(e, &phnum); |
228 |
+ for(i=0; i<phnum; ++i) |
229 |
+ { |
230 |
+ if(gelf_getphdr(e, i, &phdr) != &phdr) |
231 |
+ error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno())); |
232 |
+ if(phdr.p_type == PT_NULL) |
233 |
+ { |
234 |
+ phdr.p_type = PT_PAX_FLAGS; |
235 |
+ phdr.p_flags = PF_NOEMUTRAMP|PF_NORANDEXEC; |
236 |
+ if(!gelf_update_phdr(e, i, &phdr)) |
237 |
+ error(EXIT_FAILURE, 0, "gelf_update_phdr(): %s", elf_errmsg(elf_errno())); |
238 |
+ return 1; |
239 |
+ } |
240 |
+ } |
241 |
+ |
242 |
+ |
243 |
+ /* |
244 |
+ if( !(phdr = gelf_newphdr(Elf *e, size_t phnum)) ) |
245 |
+ { |
246 |
+ phdr.p_type = PT_PAX_FLAGS; |
247 |
+ //phdr.p_offset |
248 |
+ //phdr.p_vaddr |
249 |
+ //phdr.p_paddr |
250 |
+ //phdr.p_filesz |
251 |
+ //phdr.p_memsz |
252 |
+ phdr.p_flags = PF_NOEMUTRAMP|PF_NORANDEXEC; |
253 |
+ //phdr.p_align |
254 |
+ |
255 |
+ if(!gelf_update_phdr(e, i, &phdr)) |
256 |
+ error(EXIT_FAILURE, 0, "gelf_update_phdr(): %s", elf_errmsg(elf_errno())); |
257 |
+ return 1; |
258 |
+ } |
259 |
+ error(EXIT_FAILURE, 0, "gelf_newphdr(): %s", elf_errmsg(elf_errno())); |
260 |
+ */ |
261 |
+ |
262 |
+} |
263 |
+ |
264 |
+ |
265 |
+int |
266 |
main( int argc, char *argv[]) |
267 |
{ |
268 |
int fd; |
269 |
- int flag_ei_pax, flag_pt_pax_flags, found_ei_pax; |
270 |
+ int pax_flags, create_flag; |
271 |
char *f_name; |
272 |
- size_t i, phnum; |
273 |
|
274 |
Elf *elf; |
275 |
GElf_Ehdr ehdr; |
276 |
- GElf_Phdr phdr; |
277 |
|
278 |
- f_name = parse_cmd_args( argc, argv, &flag_ei_pax, &flag_pt_pax_flags ); |
279 |
+ f_name = parse_cmd_args(argc, argv, &pax_flags, &create_flag); |
280 |
|
281 |
if(elf_version(EV_CURRENT) == EV_NONE) |
282 |
error(EXIT_FAILURE, 0, "Library out of date."); |
283 |
|
284 |
- if( flag_ei_pax || flag_pt_pax_flags ) |
285 |
+ if(create_flag) |
286 |
{ |
287 |
if((fd = open(f_name, O_RDWR)) < 0) |
288 |
error(EXIT_FAILURE, 0, "open() fail."); |
289 |
@@ -128,11 +212,39 @@ main( int argc, char *argv[]) |
290 |
if(elf_kind(elf) != ELF_K_ELF) |
291 |
error(EXIT_FAILURE, 0, "elf_kind() fail: this is not an elf file."); |
292 |
|
293 |
- if(gelf_getehdr(elf,&ehdr) != &ehdr) |
294 |
- error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno())); |
295 |
|
296 |
- found_ei_pax = ((u_long) ehdr.e_ident[EI_PAX + 1] << 8) + (u_long) ehdr.e_ident[EI_PAX]; |
297 |
|
298 |
+ |
299 |
+ |
300 |
+ if(create_flag) |
301 |
+ { |
302 |
+ //To be safe, let's make sure EI_PAX flags are zero-ed for most secure legacy |
303 |
+ if(gelf_getehdr(elf, &ehdr) != &ehdr) |
304 |
+ error(EXIT_FAILURE, 0, "gelf_getehdr(): %s", elf_errmsg(elf_errno())); |
305 |
+ |
306 |
+ ehdr.e_ident[EI_PAX] = 0; |
307 |
+ ehdr.e_ident[EI_PAX + 1] = 0; |
308 |
+ |
309 |
+ if(!gelf_update_ehdr(elf, &ehdr)) |
310 |
+ error(EXIT_FAILURE, 0, "gelf_update_ehdr(): %s", elf_errmsg(elf_errno())); |
311 |
+ |
312 |
+ if(no_pt_pax_flags(elf)) |
313 |
+ { |
314 |
+ printf("PT_PAX_FLAGS phdr not found: creating one\n"); |
315 |
+ if(create_pt_pax_flags(elf)) |
316 |
+ { |
317 |
+ printf("PT_PAX_FLAGS phdr create: succeeded\n"); |
318 |
+ } |
319 |
+ else |
320 |
+ error(EXIT_FAILURE, 0, "PT_PAX_FLAGS phdr create: failed"); |
321 |
+ } |
322 |
+ else |
323 |
+ error(EXIT_FAILURE, 0, "PT_PAX_FLAGS phdr found: nothing to do"); |
324 |
+ } |
325 |
+ |
326 |
+ |
327 |
+ |
328 |
+ /* |
329 |
printf("==== EI_PAX ====\n") ; |
330 |
PRINT(HF_PAX_PAGEEXEC, found_ei_pax, 0); |
331 |
PRINT(HF_PAX_EMUTRAMP, found_ei_pax, 1); |
332 |
@@ -142,14 +254,6 @@ main( int argc, char *argv[]) |
333 |
PRINT(HF_PAX_SEGMEXEC, found_ei_pax, 0); |
334 |
printf("\n"); |
335 |
|
336 |
- if( flag_ei_pax ) |
337 |
- { |
338 |
- printf("Disabling EI_PAX\n\n"); |
339 |
- ehdr.e_ident[EI_PAX] = 0xFF; |
340 |
- ehdr.e_ident[EI_PAX + 1] = 0xFF; |
341 |
- if(!gelf_update_ehdr(elf, &ehdr)) |
342 |
- error(EXIT_FAILURE, 0, "gelf_update_ehdr(): %s", elf_errmsg(elf_errno())); |
343 |
- } |
344 |
|
345 |
printf("==== PHRDs ====\n") ; |
346 |
elf_getphdrnum(elf, &phnum); |
347 |
@@ -208,6 +312,7 @@ main( int argc, char *argv[]) |
348 |
} |
349 |
} |
350 |
printf("\n\n"); |
351 |
+ */ |
352 |
|
353 |
elf_end(elf); |
354 |
close(fd); |