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: poc/
Date: Tue, 27 Sep 2011 21:17:03
Message-Id: 9b0d55e53638d64ee667fc5b8d6b9e628c925cd9.blueness@gentoo
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 +}