/[gentoo-projects]/pax-utils/scanelf.c
Gentoo

Diff of /pax-utils/scanelf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.13 Revision 1.14
1/* 1/*
2 * Copyright 2003 Ned Ludd <solar@gentoo.org> 2 * Copyright 2003 Ned Ludd <solar@gentoo.org>
3 * Copyright 1999-2005 Gentoo Foundation 3 * Copyright 1999-2005 Gentoo Foundation
4 * Distributed under the terms of the GNU General Public License v2 4 * Distributed under the terms of the GNU General Public License v2
5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.13 2005/03/31 18:34:01 solar Exp $ 5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.14 2005/04/01 19:56:34 vapier Exp $
6 * 6 *
7 ******************************************************************** 7 ********************************************************************
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the 10 * published by the Free Software Foundation; either version 2 of the
31#include <dirent.h> 31#include <dirent.h>
32#include <getopt.h> 32#include <getopt.h>
33 33
34#include "paxelf.h" 34#include "paxelf.h"
35 35
36static const char *rcsid = "$Id: scanelf.c,v 1.13 2005/03/31 18:34:01 solar Exp $"; 36static const char *rcsid = "$Id: scanelf.c,v 1.14 2005/04/01 19:56:34 vapier Exp $";
37 37
38 38
39/* helper functions for showing errors */ 39/* helper functions for showing errors */
40#define argv0 "scanelf\0" /*((*argv != NULL) ? argv[0] : __FILE__ "\b\b")*/ 40#define argv0 "scanelf\0" /*((*argv != NULL) ? argv[0] : __FILE__ "\b\b")*/
41#define warn(fmt, args...) \ 41#define warn(fmt, args...) \
59 59
60/* variables to control behavior */ 60/* variables to control behavior */
61static char scan_ldpath = 0; 61static char scan_ldpath = 0;
62static char scan_envpath = 0; 62static char scan_envpath = 0;
63static char dir_recurse = 0; 63static char dir_recurse = 0;
64static char dir_crossmount = 1;
64static char show_pax = 0; 65static char show_pax = 0;
65static char show_stack = 0; 66static char show_stack = 0;
66static char show_textrel = 0; 67static char show_textrel = 0;
67static char show_rpath = 0; 68static char show_rpath = 0;
68static char show_header = 1; 69static char show_header = 1;
69static char be_quiet = 0; 70static char be_quiet = 0;
71static char be_verbose = 0;
70 72
71 73
72 74
73/* scan an elf file and show all the fun stuff */ 75/* scan an elf file and show all the fun stuff */
74static void scanelf_file(const char *filename) 76static void scanelf_file(const char *filename)
75{ 77{
76 int i; 78 int i;
77 char found_stack, found_relro, found_textrel, found_rpath; 79 char found_pax, found_stack, found_relro, found_textrel, found_rpath;
78 Elf_Dyn *dyn; 80 Elf_Dyn *dyn;
79 elfobj *elf = NULL; 81 elfobj *elf = NULL;
80 82
81 found_stack = found_relro = found_textrel = found_rpath = 0; 83 found_pax = found_stack = found_relro = found_textrel = found_rpath = 0;
82 84
83 /* verify this is real ELF */ 85 /* verify this is real ELF */
84 if ((elf = readelf(filename)) == NULL) 86 if ((elf = readelf(filename)) == NULL) {
87 if (be_verbose > 1) printf("File '%s' is not an ELF\n", filename);
85 return; 88 return;
89 }
86 if (check_elf_header(elf->ehdr) || !IS_ELF(elf)) 90 if (check_elf_header(elf->ehdr) || !IS_ELF(elf)) {
91 if (be_verbose > 1) printf("Cannot handle ELF '%s' :(\n", filename);
87 goto bail; 92 goto bail;
93 }
94
95 if (be_verbose) printf("Scanning file %s\n", filename);
88 96
89 /* show the header */ 97 /* show the header */
90 if (!be_quiet && show_header) { 98 if (!be_quiet && show_header) {
91 fputs(" TYPE ", stderr); 99 fputs(" TYPE ", stdout);
92 if (show_pax) fputs(" PAX ", stderr); 100 if (show_pax) fputs(" PAX ", stdout);
93 if (show_stack) fputs(" STACK/RELRO ", stderr); 101 if (show_stack) fputs(" STK/REL ", stdout);
94 if (show_textrel) fputs(" TEXTREL ", stderr); 102 if (show_textrel) fputs("TEXTREL ", stdout);
95 if (show_rpath) fputs(" RPATH ", stderr); 103 if (show_rpath) fputs("RPATH ", stdout);
96 fputs(" FILE\n", stderr); 104 fputs(" FILE\n", stdout);
97 show_header = 0; 105 show_header = 0;
98 } 106 }
99 107
100 /* dump all the good stuff */ 108 /* dump all the good stuff */
101 if (!be_quiet) 109 if (!be_quiet)
102 printf("%-7s ", get_elfetype(elf->ehdr->e_type)); 110 printf("%-7s ", get_elfetype(elf->ehdr->e_type));
103 111
104 if (show_pax) 112 if (show_pax) {
113 char *paxflags = pax_short_hf_flags(PAX_FLAGS(elf));
114 if (!be_quiet || (be_quiet && strncmp(paxflags, "PeMRxS", 6))) {
115 found_pax = 1;
105 printf("%s ", pax_short_hf_flags(PAX_FLAGS(elf))); 116 printf("%s ", pax_short_hf_flags(PAX_FLAGS(elf)));
117 }
118 }
106 119
107 /* stack fun */ 120 /* stack fun */
108 if (show_stack) { 121 if (show_stack) {
109 for (i = 0; i < elf->ehdr->e_phnum; i++) { 122 for (i = 0; i < elf->ehdr->e_phnum; i++) {
110 if (elf->phdr[i].p_type != PT_GNU_STACK && \ 123 if (elf->phdr[i].p_type != PT_GNU_STACK && \
159 printf("%s ", rpath); 172 printf("%s ", rpath);
160 } 173 }
161 ++dyn; 174 ++dyn;
162 } 175 }
163 } 176 }
164 if (!be_quiet && !found_rpath) fputs("- ", stdout); 177 if (!be_quiet && !found_rpath) fputs(" - ", stdout);
165 } 178 }
166 179
167 if (!be_quiet || show_pax || found_stack || found_textrel || found_rpath) 180 if (!be_quiet || found_pax || found_stack || found_textrel || found_rpath)
168 puts(filename); 181 puts(filename);
169 182
170bail: 183bail:
171 unreadelf(elf); 184 unreadelf(elf);
172} 185}
174/* scan a directory for ET_EXEC files and print when we find one */ 187/* scan a directory for ET_EXEC files and print when we find one */
175static void scanelf_dir(const char *path) 188static void scanelf_dir(const char *path)
176{ 189{
177 register DIR *dir; 190 register DIR *dir;
178 register struct dirent *dentry; 191 register struct dirent *dentry;
179 struct stat st; 192 struct stat st_top, st;
180 char *p; 193 char *p;
181 int len = 0; 194 int len = 0;
182 195
183 /* make sure path exists */ 196 /* make sure path exists */
184 if (lstat(path, &st) == -1) 197 if (lstat(path, &st_top) == -1)
185 return; 198 return;
186 199
187 /* ok, if it isn't a directory, assume we can open it */ 200 /* ok, if it isn't a directory, assume we can open it */
188 if (!S_ISDIR(st.st_mode)) { 201 if (!S_ISDIR(st_top.st_mode)) {
189 scanelf_file(path); 202 scanelf_file(path);
190 return; 203 return;
191 } 204 }
192 205
193 /* now scan the dir looking for fun stuff */ 206 /* now scan the dir looking for fun stuff */
194 if ((dir = opendir(path)) == NULL) { 207 if ((dir = opendir(path)) == NULL) {
195 warnf("could not opendir %s: %s", path, strerror(errno)); 208 warnf("could not opendir %s: %s", path, strerror(errno));
196 return; 209 return;
197 } 210 }
211 if (be_verbose) printf("Scanning dir %s\n", path);
198 212
199 while ((dentry = readdir(dir))) { 213 while ((dentry = readdir(dir))) {
200 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, "..")) 214 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
201 continue; 215 continue;
202 len = (strlen(path) + 2 + strlen(dentry->d_name)); 216 len = (strlen(path) + 2 + strlen(dentry->d_name));
208 strncat(p, dentry->d_name, len); 222 strncat(p, dentry->d_name, len);
209 if (lstat(p, &st) != -1) { 223 if (lstat(p, &st) != -1) {
210 if (S_ISREG(st.st_mode)) 224 if (S_ISREG(st.st_mode))
211 scanelf_file(p); 225 scanelf_file(p);
212 else if (dir_recurse && S_ISDIR(st.st_mode)) { 226 else if (dir_recurse && S_ISDIR(st.st_mode)) {
227 if (dir_crossmount || (st_top.st_dev == st.st_dev))
213 scanelf_dir(p); 228 scanelf_dir(p);
214 } 229 }
215 } 230 }
216 free(p); 231 free(p);
217 } 232 }
218 closedir(dir); 233 closedir(dir);
261} 276}
262 277
263 278
264 279
265/* usage / invocation handling functions */ 280/* usage / invocation handling functions */
266#define PARSE_FLAGS "plRxstraqhV" 281#define PARSE_FLAGS "plRmxstraqvHhV"
267static struct option const long_opts[] = { 282static struct option const long_opts[] = {
268 {"path", no_argument, NULL, 'p'}, 283 {"path", no_argument, NULL, 'p'},
269 {"ldpath", no_argument, NULL, 'l'}, 284 {"ldpath", no_argument, NULL, 'l'},
270 {"recursive", no_argument, NULL, 'R'}, 285 {"recursive", no_argument, NULL, 'R'},
286 {"mount", no_argument, NULL, 'm'},
271 {"pax", no_argument, NULL, 'x'}, 287 {"pax", no_argument, NULL, 'x'},
272 {"stack", no_argument, NULL, 's'}, 288 {"stack", no_argument, NULL, 's'},
273 {"textrel", no_argument, NULL, 't'}, 289 {"textrel", no_argument, NULL, 't'},
274 {"rpath", no_argument, NULL, 'r'}, 290 {"rpath", no_argument, NULL, 'r'},
275 {"all", no_argument, NULL, 'a'}, 291 {"all", no_argument, NULL, 'a'},
276 {"quiet", no_argument, NULL, 'q'}, 292 {"quiet", no_argument, NULL, 'q'},
277/* {"vebose", no_argument, NULL, 'v'},*/ 293 {"verbose", no_argument, NULL, 'v'},
294 {"noheader", no_argument, NULL, 'H'},
278 {"help", no_argument, NULL, 'h'}, 295 {"help", no_argument, NULL, 'h'},
279 {"version", no_argument, NULL, 'V'}, 296 {"version", no_argument, NULL, 'V'},
280 {NULL, no_argument, NULL, 0x0} 297 {NULL, no_argument, NULL, 0x0}
281}; 298};
282static char *opts_help[] = { 299static char *opts_help[] = {
283 "Scan all directories in PATH environment", 300 "Scan all directories in PATH environment",
284 "Scan all directories in /etc/ld.so.conf", 301 "Scan all directories in /etc/ld.so.conf",
285 "Scan directories recursively\n", 302 "Scan directories recursively",
303 "Don't recursively cross mount points\n",
286 "Print PaX markings", 304 "Print PaX markings",
287 "Print GNU_STACK markings", 305 "Print GNU_STACK markings",
288 "Print TEXTREL information", 306 "Print TEXTREL information",
289 "Print RPATH information", 307 "Print RPATH information",
290 "Print all scanned info", 308 "Print all scanned info (-x -s -t -r)\n",
291 "Only output 'bad' things\n", 309 "Only output 'bad' things",
292/* "Be verbose !",*/ 310 "Be verbose (can be specified more than once)",
311 "Don't display the header",
293 "Print this help and exit", 312 "Print this help and exit",
294 "Print version and exit", 313 "Print version and exit",
295 NULL 314 NULL
296}; 315};
297 316
324 __FILE__, __DATE__, argv0, rcsid); 343 __FILE__, __DATE__, argv0, rcsid);
325 exit(EXIT_SUCCESS); 344 exit(EXIT_SUCCESS);
326 break; 345 break;
327 case 'h': usage(EXIT_SUCCESS); break; 346 case 'h': usage(EXIT_SUCCESS); break;
328 347
348 case 'H': show_header = 0; break;
329 case 'l': scan_ldpath = 1; break; 349 case 'l': scan_ldpath = 1; break;
330 case 'p': scan_envpath = 1; break; 350 case 'p': scan_envpath = 1; break;
331 case 'R': dir_recurse = 1; break; 351 case 'R': dir_recurse = 1; break;
352 case 'm': dir_crossmount = 0; break;
332 case 'x': show_pax = 1; break; 353 case 'x': show_pax = 1; break;
333 case 's': show_stack = 1; break; 354 case 's': show_stack = 1; break;
334 case 't': show_textrel = 1; break; 355 case 't': show_textrel = 1; break;
335 case 'r': show_rpath = 1; break; 356 case 'r': show_rpath = 1; break;
336 case 'q': be_quiet = 1; break; 357 case 'q': be_quiet = 1; break;
358 case 'v': be_verbose = (be_verbose % 20) + 1; break;
337 case 'a': show_pax = show_stack = show_textrel = show_rpath = 1; break; 359 case 'a': show_pax = show_stack = show_textrel = show_rpath = 1; break;
338 360
339 case ':': 361 case ':':
340 warn("Option missing parameter"); 362 warn("Option missing parameter");
341 usage(EXIT_FAILURE); 363 usage(EXIT_FAILURE);
348 err("Unhandled option '%c'", flag); 370 err("Unhandled option '%c'", flag);
349 break; 371 break;
350 } 372 }
351 } 373 }
352 374
375 if (be_quiet && be_verbose)
376 err("You can be quiet or you can be verbose, not both, stupid");
377
353 if (scan_ldpath) scanelf_ldpath(); 378 if (scan_ldpath) scanelf_ldpath();
354 if (scan_envpath) scanelf_envpath(); 379 if (scan_envpath) scanelf_envpath();
355 while (optind < argc) 380 while (optind < argc)
356 scanelf_dir(argv[optind++]); 381 scanelf_dir(argv[optind++]);
357} 382}

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

  ViewVC Help
Powered by ViewVC 1.1.20