1 |
commit: 9b0d55e53638d64ee667fc5b8d6b9e628c925cd9 |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Sep 27 21:16:48 2011 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Sep 27 21:16:48 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=9b0d55e5 |
7 |
|
8 |
poc/paxctl-xattr.c: get and set pax flags in xattrs |
9 |
|
10 |
--- |
11 |
poc/Makefile.am | 5 +- |
12 |
poc/paxctl-xattr.c | 374 ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
13 |
2 files changed, 377 insertions(+), 2 deletions(-) |
14 |
|
15 |
diff --git a/poc/Makefile.am b/poc/Makefile.am |
16 |
index e8c94d5..68022f9 100644 |
17 |
--- a/poc/Makefile.am |
18 |
+++ b/poc/Makefile.am |
19 |
@@ -1,7 +1,8 @@ |
20 |
-noinst_PROGRAMS = mangle-paxflags bad-mmap |
21 |
+noinst_PROGRAMS = bad-mmap mangle-paxflags paxctl-xattr |
22 |
+bad_mmap_SOURCES = bad-mmap.c |
23 |
mangle_paxflags_SOURCES = mangle-paxflags.c |
24 |
mangle_paxflags_LDADD = -lelf |
25 |
-bad_mmap_SOURCES = bad-mmap.c |
26 |
+paxctl_xattr_SOURCES = paxctl-xattr.c |
27 |
|
28 |
check_SCRIPTS = poc.sh |
29 |
|
30 |
|
31 |
diff --git a/poc/paxctl-xattr.c b/poc/paxctl-xattr.c |
32 |
new file mode 100644 |
33 |
index 0000000..eb97166 |
34 |
--- /dev/null |
35 |
+++ b/poc/paxctl-xattr.c |
36 |
@@ -0,0 +1,374 @@ |
37 |
+/* |
38 |
+ paxctl-xattr.c: get/set pax flags on xattr for an ELF object |
39 |
+ Copyright (C) 2011 Anthony G. Basile |
40 |
+ |
41 |
+ This program is free software: you can redistribute it and/or modify |
42 |
+ it under the terms of the GNU General Public License as published by |
43 |
+ the Free Software Foundation, either version 3 of the License, or |
44 |
+ (at your option) any later version. |
45 |
+ |
46 |
+ This program is distributed in the hope that it will be useful, |
47 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
48 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
49 |
+ GNU General Public License for more details. |
50 |
+ |
51 |
+ You should have received a copy of the GNU General Public License |
52 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>. |
53 |
+*/ |
54 |
+ |
55 |
+#include <stdio.h> |
56 |
+#include <stdint.h> |
57 |
+#include <stdlib.h> |
58 |
+#include <string.h> |
59 |
+#include <error.h> |
60 |
+#include <errno.h> |
61 |
+#include <libgen.h> |
62 |
+ |
63 |
+#include <gelf.h> |
64 |
+#include <sys/xattr.h> |
65 |
+ |
66 |
+#include <sys/types.h> |
67 |
+#include <sys/stat.h> |
68 |
+#include <fcntl.h> |
69 |
+#include <unistd.h> |
70 |
+ |
71 |
+#include <config.h> |
72 |
+ |
73 |
+#define PAX_NAMESPACE "user.pax" |
74 |
+ |
75 |
+void |
76 |
+print_help(char *v) |
77 |
+{ |
78 |
+ printf( |
79 |
+ "\n" |
80 |
+ "Package Name : " PACKAGE_STRING "\n" |
81 |
+ "Bug Reports : " PACKAGE_BUGREPORT "\n" |
82 |
+ "Program Name : %s\n" |
83 |
+ "Description : Get or set xattr pax flags on an ELF object\n\n" |
84 |
+ "Usage : %s [-PpEeMmRrXxSsv ELF] | [-Z ELF] | [-z ELF] | [-h]\n\n" |
85 |
+ "Options : -P enable PAGEEXEC\t-p disable PAGEEXEC\n" |
86 |
+ " : -S enable SEGMEXEC\t-s disable SEGMEXEC\n" |
87 |
+ " : -M enable MPROTECT\t-m disable MPROTECT\n" |
88 |
+ " : -E enable EMUTRAMP\t-e disable EMUTRAMP\n" |
89 |
+ " : -R enable RANDMMAP\t-r disable RANDMMAP\n" |
90 |
+ " : -X enable RANDEXEC\t-x disable RANDEXEC\n" |
91 |
+ " : -Z most secure settings\t-z all default settings\n" |
92 |
+ " : -v view the flags\n" |
93 |
+ " : -h print out this help\n\n" |
94 |
+ "Note : If both enabling and disabling flags are set, the default - is used\n\n", |
95 |
+ basename(v), |
96 |
+ basename(v) |
97 |
+ ); |
98 |
+ |
99 |
+ exit(EXIT_SUCCESS); |
100 |
+} |
101 |
+ |
102 |
+ |
103 |
+char * |
104 |
+parse_cmd_args(int c, char *v[], int *pax_flags, int *view_flags) |
105 |
+{ |
106 |
+ int i, oc; |
107 |
+ int compat; |
108 |
+ |
109 |
+ compat = 0; |
110 |
+ |
111 |
+ *pax_flags = 0; |
112 |
+ *view_flags = 0; |
113 |
+ while((oc = getopt(c, v,":PpEeMmRrXxSsZzvh")) != -1) |
114 |
+ switch(oc) |
115 |
+ { |
116 |
+ case 'P': |
117 |
+ *pax_flags |= PF_PAGEEXEC; |
118 |
+ compat |= 1; |
119 |
+ break; |
120 |
+ case 'p': |
121 |
+ *pax_flags |= PF_NOPAGEEXEC; |
122 |
+ compat |= 1; |
123 |
+ break ; |
124 |
+ case 'S': |
125 |
+ *pax_flags |= PF_SEGMEXEC; |
126 |
+ compat |= 1; |
127 |
+ break; |
128 |
+ case 's': |
129 |
+ *pax_flags |= PF_NOSEGMEXEC; |
130 |
+ compat |= 1; |
131 |
+ break ; |
132 |
+ case 'M': |
133 |
+ *pax_flags |= PF_MPROTECT; |
134 |
+ compat |= 1; |
135 |
+ break; |
136 |
+ case 'm': |
137 |
+ *pax_flags |= PF_NOMPROTECT; |
138 |
+ compat |= 1; |
139 |
+ break ; |
140 |
+ case 'E': |
141 |
+ *pax_flags |= PF_EMUTRAMP; |
142 |
+ compat |= 1; |
143 |
+ break; |
144 |
+ case 'e': |
145 |
+ *pax_flags |= PF_NOEMUTRAMP; |
146 |
+ compat |= 1; |
147 |
+ break ; |
148 |
+ case 'R': |
149 |
+ *pax_flags |= PF_RANDMMAP; |
150 |
+ compat |= 1; |
151 |
+ break; |
152 |
+ case 'r': |
153 |
+ *pax_flags |= PF_NORANDMMAP; |
154 |
+ compat |= 1; |
155 |
+ break ; |
156 |
+ case 'X': |
157 |
+ *pax_flags |= PF_RANDEXEC; |
158 |
+ compat |= 1; |
159 |
+ break; |
160 |
+ case 'x': |
161 |
+ *pax_flags |= PF_NORANDEXEC; |
162 |
+ compat |= 1; |
163 |
+ break ; |
164 |
+ case 'Z': |
165 |
+ *pax_flags = PF_PAGEEXEC | PF_SEGMEXEC | PF_MPROTECT | |
166 |
+ PF_NOEMUTRAMP | PF_RANDMMAP | PF_RANDEXEC; |
167 |
+ compat += 1; |
168 |
+ break ; |
169 |
+ case 'z': |
170 |
+ *pax_flags = PF_PAGEEXEC | PF_NOPAGEEXEC | PF_SEGMEXEC | PF_NOSEGMEXEC | |
171 |
+ PF_MPROTECT | PF_NOMPROTECT | PF_EMUTRAMP | PF_NOEMUTRAMP | |
172 |
+ PF_RANDMMAP | PF_NORANDMMAP | PF_RANDEXEC | PF_NORANDEXEC; |
173 |
+ compat += 1; |
174 |
+ break; |
175 |
+ case 'v': |
176 |
+ *view_flags = 1; |
177 |
+ compat |= 1; |
178 |
+ break; |
179 |
+ case 'h': |
180 |
+ print_help(v[0]); |
181 |
+ break; |
182 |
+ case '?': |
183 |
+ default: |
184 |
+ error(EXIT_FAILURE, 0, "option -%c is invalid: ignored.", optopt ) ; |
185 |
+ } |
186 |
+ |
187 |
+ if(compat != 1 || v[optind] == NULL) |
188 |
+ print_help(v[0]); |
189 |
+ |
190 |
+ return v[optind] ; |
191 |
+} |
192 |
+ |
193 |
+ |
194 |
+#define BUF_SIZE 7 |
195 |
+void |
196 |
+print_flags(int fd) |
197 |
+{ |
198 |
+ char xt_buf[BUF_SIZE]; |
199 |
+ |
200 |
+ static ssize_t xsize = 1024; |
201 |
+ static char *xattrs = NULL; |
202 |
+ ssize_t i, xret = -1; |
203 |
+ |
204 |
+ static ssize_t vsize = 1024; |
205 |
+ static char *value = NULL; |
206 |
+ ssize_t vret = -1; |
207 |
+ |
208 |
+ memset(xt_buf, 0, BUF_SIZE); |
209 |
+ xattrs = malloc(xsize); |
210 |
+ value = malloc(vsize); |
211 |
+ |
212 |
+ //If at first we don't succeed, grow buffer size |
213 |
+ while(((xret = flistxattr(fd, xattrs, xsize)) == -1) && (errno == ERANGE)) |
214 |
+ { |
215 |
+ xsize <<= 1; |
216 |
+ xattrs = realloc(xattrs, xsize); |
217 |
+ } |
218 |
+ |
219 |
+ if(errno == ENOTSUP) |
220 |
+ { |
221 |
+ printf("XT_PAX: not found without Extended Attribute Support\n"); |
222 |
+ return; |
223 |
+ } |
224 |
+ |
225 |
+ for(i = 0; i < xret; i += strlen(&xattrs[i]) + 1) |
226 |
+ { |
227 |
+ |
228 |
+ if(strcmp(&xattrs[i], PAX_NAMESPACE) == 0) |
229 |
+ { |
230 |
+ printf("here\n"); |
231 |
+ |
232 |
+ while(((vret = fgetxattr(fd, &xattrs[i], value, vsize)) == -1) && (errno == ERANGE)) |
233 |
+ { |
234 |
+ xsize <<= 1; |
235 |
+ xattrs = realloc(xattrs, xsize); |
236 |
+ } |
237 |
+ |
238 |
+ /* |
239 |
+ valueLen = getxattr(argv[j], &xattrs[ns], value, XATTR_SIZE); |
240 |
+ if (valueLen == -1) { |
241 |
+ printf("couldn't get value"); |
242 |
+ } else { |
243 |
+ for (k = 0; k < valueLen; k++) |
244 |
+ printf("%02x ", (unsigned int) value[k]); |
245 |
+ } |
246 |
+ |
247 |
+ xt_buf[0] = xt_flags & PF_PAGEEXEC ? 'P' : |
248 |
+ xt_flags & PF_NOPAGEEXEC ? 'p' : '-' ; |
249 |
+ |
250 |
+ xt_buf[1] = xt_flags & PF_SEGMEXEC ? 'S' : |
251 |
+ xt_flags & PF_NOSEGMEXEC ? 's' : '-'; |
252 |
+ |
253 |
+ xt_buf[2] = xt_flags & PF_MPROTECT ? 'M' : |
254 |
+ xt_flags & PF_NOMPROTECT ? 'm' : '-'; |
255 |
+ |
256 |
+ xt_buf[3] = xt_flags & PF_EMUTRAMP ? 'E' : |
257 |
+ xt_flags & PF_NOEMUTRAMP ? 'e' : '-'; |
258 |
+ |
259 |
+ xt_buf[4] = xt_flags & PF_RANDMMAP ? 'R' : |
260 |
+ xt_flags & PF_NORANDMMAP ? 'r' : '-'; |
261 |
+ |
262 |
+ xt_buf[5] = xt_flags & PF_RANDEXEC ? 'X' : |
263 |
+ xt_flags & PF_NORANDEXEC ? 'x' : '-'; |
264 |
+ |
265 |
+ printf("XT_PAX: %s\n", xt_buf); |
266 |
+ */ |
267 |
+ } |
268 |
+ } |
269 |
+} |
270 |
+ |
271 |
+ |
272 |
+void |
273 |
+set_flags(int fd, int *pax_flags) |
274 |
+{ |
275 |
+ char xt_buf[BUF_SIZE]; |
276 |
+ memset(xt_buf, 0, BUF_SIZE); |
277 |
+ |
278 |
+ /* |
279 |
+ if( / DOME xattrs is supported / ) |
280 |
+ { |
281 |
+ //PAGEEXEC |
282 |
+ if(*pax_flags & PF_PAGEEXEC) |
283 |
+ { |
284 |
+ phdr.p_flags |= PF_PAGEEXEC; |
285 |
+ phdr.p_flags &= ~PF_NOPAGEEXEC; |
286 |
+ } |
287 |
+ if(*pax_flags & PF_NOPAGEEXEC) |
288 |
+ { |
289 |
+ phdr.p_flags &= ~PF_PAGEEXEC; |
290 |
+ phdr.p_flags |= PF_NOPAGEEXEC; |
291 |
+ } |
292 |
+ if((*pax_flags & PF_PAGEEXEC) && (*pax_flags & PF_NOPAGEEXEC)) |
293 |
+ { |
294 |
+ phdr.p_flags &= ~PF_PAGEEXEC; |
295 |
+ phdr.p_flags &= ~PF_NOPAGEEXEC; |
296 |
+ } |
297 |
+ |
298 |
+ //SEGMEXEC |
299 |
+ if(*pax_flags & PF_SEGMEXEC) |
300 |
+ { |
301 |
+ phdr.p_flags |= PF_SEGMEXEC; |
302 |
+ phdr.p_flags &= ~PF_NOSEGMEXEC; |
303 |
+ } |
304 |
+ if(*pax_flags & PF_NOSEGMEXEC) |
305 |
+ { |
306 |
+ phdr.p_flags &= ~PF_SEGMEXEC; |
307 |
+ phdr.p_flags |= PF_NOSEGMEXEC; |
308 |
+ } |
309 |
+ if((*pax_flags & PF_SEGMEXEC) && (*pax_flags & PF_NOSEGMEXEC)) |
310 |
+ { |
311 |
+ phdr.p_flags &= ~PF_SEGMEXEC; |
312 |
+ phdr.p_flags &= ~PF_NOSEGMEXEC; |
313 |
+ } |
314 |
+ |
315 |
+ //MPROTECT |
316 |
+ if(*pax_flags & PF_MPROTECT) |
317 |
+ { |
318 |
+ phdr.p_flags |= PF_MPROTECT; |
319 |
+ phdr.p_flags &= ~PF_NOMPROTECT; |
320 |
+ } |
321 |
+ if(*pax_flags & PF_NOMPROTECT) |
322 |
+ { |
323 |
+ phdr.p_flags &= ~PF_MPROTECT; |
324 |
+ phdr.p_flags |= PF_NOMPROTECT; |
325 |
+ } |
326 |
+ if((*pax_flags & PF_MPROTECT) && (*pax_flags & PF_NOMPROTECT)) |
327 |
+ { |
328 |
+ phdr.p_flags &= ~PF_MPROTECT; |
329 |
+ phdr.p_flags &= ~PF_NOMPROTECT; |
330 |
+ } |
331 |
+ |
332 |
+ //EMUTRAMP |
333 |
+ if(*pax_flags & PF_EMUTRAMP) |
334 |
+ { |
335 |
+ phdr.p_flags |= PF_EMUTRAMP; |
336 |
+ phdr.p_flags &= ~PF_NOEMUTRAMP; |
337 |
+ } |
338 |
+ if(*pax_flags & PF_NOEMUTRAMP) |
339 |
+ { |
340 |
+ phdr.p_flags &= ~PF_EMUTRAMP; |
341 |
+ phdr.p_flags |= PF_NOEMUTRAMP; |
342 |
+ } |
343 |
+ if((*pax_flags & PF_EMUTRAMP) && (*pax_flags & PF_NOEMUTRAMP)) |
344 |
+ { |
345 |
+ phdr.p_flags &= ~PF_EMUTRAMP; |
346 |
+ phdr.p_flags &= ~PF_NOEMUTRAMP; |
347 |
+ } |
348 |
+ |
349 |
+ //RANDMMAP |
350 |
+ if(*pax_flags & PF_RANDMMAP) |
351 |
+ { |
352 |
+ phdr.p_flags |= PF_RANDMMAP; |
353 |
+ phdr.p_flags &= ~PF_NORANDMMAP; |
354 |
+ } |
355 |
+ if(*pax_flags & PF_NORANDMMAP) |
356 |
+ { |
357 |
+ phdr.p_flags &= ~PF_RANDMMAP; |
358 |
+ phdr.p_flags |= PF_NORANDMMAP; |
359 |
+ } |
360 |
+ if((*pax_flags & PF_RANDMMAP) && (*pax_flags & PF_NORANDMMAP)) |
361 |
+ { |
362 |
+ phdr.p_flags &= ~PF_RANDMMAP; |
363 |
+ phdr.p_flags &= ~PF_NORANDMMAP; |
364 |
+ } |
365 |
+ |
366 |
+ //RANDEXEC |
367 |
+ if(*pax_flags & PF_RANDEXEC) |
368 |
+ { |
369 |
+ phdr.p_flags |= PF_RANDEXEC; |
370 |
+ phdr.p_flags &= ~PF_NORANDEXEC; |
371 |
+ } |
372 |
+ if(*pax_flags & PF_NORANDEXEC) |
373 |
+ { |
374 |
+ phdr.p_flags &= ~PF_RANDEXEC; |
375 |
+ phdr.p_flags |= PF_NORANDEXEC; |
376 |
+ } |
377 |
+ if((*pax_flags & PF_RANDEXEC) && (*pax_flags & PF_NORANDEXEC)) |
378 |
+ { |
379 |
+ phdr.p_flags &= ~PF_RANDEXEC; |
380 |
+ phdr.p_flags &= ~PF_NORANDEXEC; |
381 |
+ } |
382 |
+ |
383 |
+ / update xattr / |
384 |
+ } |
385 |
+ else |
386 |
+ printf("XT_PAX: not found\n"); |
387 |
+ */ |
388 |
+} |
389 |
+ |
390 |
+ |
391 |
+int |
392 |
+main( int argc, char *argv[]) |
393 |
+{ |
394 |
+ int fd; |
395 |
+ int pax_flags, view_flags; |
396 |
+ char *f_name; |
397 |
+ |
398 |
+ f_name = parse_cmd_args(argc, argv, &pax_flags, &view_flags); |
399 |
+ |
400 |
+ if((fd = open(f_name, O_RDWR)) < 0) |
401 |
+ error(EXIT_FAILURE, 0, "open() fail."); |
402 |
+ |
403 |
+ if(pax_flags != 0) |
404 |
+ set_flags(fd, &pax_flags); |
405 |
+ |
406 |
+ if(view_flags == 1) |
407 |
+ print_flags(fd); |
408 |
+ |
409 |
+ close(fd); |
410 |
+} |