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: src/, /, poc/
Date: Fri, 06 May 2011 02:43:19
Message-Id: 28309dafebd27f7afbaee68d97b77fed68b04e99.blueness@gentoo
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);