| 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.36 2005/04/15 22:02:03 vapier Exp $ |
5 | * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.37 2005/04/16 06:34:39 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 |
| … | |
… | |
| 33 | #include <getopt.h> |
33 | #include <getopt.h> |
| 34 | #include <assert.h> |
34 | #include <assert.h> |
| 35 | |
35 | |
| 36 | #include "paxelf.h" |
36 | #include "paxelf.h" |
| 37 | |
37 | |
| 38 | static const char *rcsid = "$Id: scanelf.c,v 1.36 2005/04/15 22:02:03 vapier Exp $"; |
38 | static const char *rcsid = "$Id: scanelf.c,v 1.37 2005/04/16 06:34:39 vapier Exp $"; |
| 39 | #define argv0 "scanelf" |
39 | #define argv0 "scanelf" |
| 40 | |
40 | |
| 41 | |
41 | |
| 42 | |
42 | |
| 43 | /* prototypes */ |
43 | /* prototypes */ |
| … | |
… | |
| 49 | static void parseargs(int argc, char *argv[]); |
49 | static void parseargs(int argc, char *argv[]); |
| 50 | |
50 | |
| 51 | /* variables to control behavior */ |
51 | /* variables to control behavior */ |
| 52 | static char scan_ldpath = 0; |
52 | static char scan_ldpath = 0; |
| 53 | static char scan_envpath = 0; |
53 | static char scan_envpath = 0; |
|
|
54 | static char scan_symlink = 1; |
| 54 | static char dir_recurse = 0; |
55 | static char dir_recurse = 0; |
| 55 | static char dir_crossmount = 1; |
56 | static char dir_crossmount = 1; |
| 56 | static char show_pax = 0; |
57 | static char show_pax = 0; |
| 57 | static char show_stack = 0; |
58 | static char show_stack = 0; |
| 58 | static char show_textrel = 0; |
59 | static char show_textrel = 0; |
| … | |
… | |
| 72 | char found_pax, found_stack, found_relro, found_textrel, |
73 | char found_pax, found_stack, found_relro, found_textrel, |
| 73 | found_rpath, found_needed, found_sym; |
74 | found_rpath, found_needed, found_sym; |
| 74 | elfobj *elf; |
75 | elfobj *elf; |
| 75 | struct stat st; |
76 | struct stat st; |
| 76 | |
77 | |
| 77 | /* make sure path exists */ |
78 | /* make sure 'filename' exists */ |
| 78 | if (lstat(filename, &st) == -1) |
79 | if (lstat(filename, &st) == -1) |
| 79 | return; |
80 | return; |
| 80 | if (!S_ISREG(st.st_mode)) |
81 | /* always handle regular files and handle symlinked files if no -y */ |
|
|
82 | if (!(S_ISREG(st.st_mode) || (S_ISLNK(st.st_mode) && scan_symlink))) |
| 81 | return; |
83 | return; |
|
|
84 | |
| 82 | found_pax = found_stack = found_relro = found_textrel = \ |
85 | found_pax = found_stack = found_relro = found_textrel = \ |
| 83 | found_rpath = found_needed = found_sym = 0; |
86 | found_rpath = found_needed = found_sym = 0; |
| 84 | |
87 | |
| 85 | /* verify this is real ELF */ |
88 | /* verify this is real ELF */ |
| 86 | if ((elf = readelf(filename)) == NULL) { |
89 | if ((elf = readelf(filename)) == NULL) { |
| … | |
… | |
| 415 | } |
418 | } |
| 416 | |
419 | |
| 417 | |
420 | |
| 418 | |
421 | |
| 419 | /* usage / invocation handling functions */ |
422 | /* usage / invocation handling functions */ |
| 420 | #define PARSE_FLAGS "plRmxetrns:aqvo:BhV" |
423 | #define PARSE_FLAGS "plRmyxetrns:aqvo:BhV" |
| 421 | #define a_argument required_argument |
424 | #define a_argument required_argument |
| 422 | static struct option const long_opts[] = { |
425 | static struct option const long_opts[] = { |
| 423 | {"path", no_argument, NULL, 'p'}, |
426 | {"path", no_argument, NULL, 'p'}, |
| 424 | {"ldpath", no_argument, NULL, 'l'}, |
427 | {"ldpath", no_argument, NULL, 'l'}, |
| 425 | {"recursive", no_argument, NULL, 'R'}, |
428 | {"recursive", no_argument, NULL, 'R'}, |
| 426 | {"mount", no_argument, NULL, 'm'}, |
429 | {"mount", no_argument, NULL, 'm'}, |
|
|
430 | {"symlink", no_argument, NULL, 'y'}, |
| 427 | {"pax", no_argument, NULL, 'x'}, |
431 | {"pax", no_argument, NULL, 'x'}, |
| 428 | {"header", no_argument, NULL, 'e'}, |
432 | {"header", no_argument, NULL, 'e'}, |
| 429 | {"textrel", no_argument, NULL, 't'}, |
433 | {"textrel", no_argument, NULL, 't'}, |
| 430 | {"rpath", no_argument, NULL, 'r'}, |
434 | {"rpath", no_argument, NULL, 'r'}, |
| 431 | {"needed", no_argument, NULL, 'n'}, |
435 | {"needed", no_argument, NULL, 'n'}, |
| … | |
… | |
| 441 | }; |
445 | }; |
| 442 | static char *opts_help[] = { |
446 | static char *opts_help[] = { |
| 443 | "Scan all directories in PATH environment", |
447 | "Scan all directories in PATH environment", |
| 444 | "Scan all directories in /etc/ld.so.conf", |
448 | "Scan all directories in /etc/ld.so.conf", |
| 445 | "Scan directories recursively", |
449 | "Scan directories recursively", |
| 446 | "Don't recursively cross mount points\n", |
450 | "Don't recursively cross mount points", |
|
|
451 | "Don't scan symlinks\n", |
| 447 | "Print PaX markings", |
452 | "Print PaX markings", |
| 448 | "Print GNU_STACK markings", |
453 | "Print GNU_STACK markings", |
| 449 | "Print TEXTREL information", |
454 | "Print TEXTREL information", |
| 450 | "Print RPATH information", |
455 | "Print RPATH information", |
| 451 | "Print NEEDED information", |
456 | "Print NEEDED information", |
| … | |
… | |
| 462 | |
467 | |
| 463 | /* display usage and exit */ |
468 | /* display usage and exit */ |
| 464 | static void usage(int status) |
469 | static void usage(int status) |
| 465 | { |
470 | { |
| 466 | int i; |
471 | int i; |
| 467 | printf("¤ Scan ELF binaries for stuff\n" |
472 | printf("¤ Scan ELF binaries for stuff\n\n" |
| 468 | "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0); |
473 | "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0); |
| 469 | printf("Options: -[%s]\n", PARSE_FLAGS); |
474 | printf("Options: -[%s]\n", PARSE_FLAGS); |
| 470 | for (i = 0; long_opts[i].name; ++i) |
475 | for (i = 0; long_opts[i].name; ++i) |
| 471 | if (long_opts[i].has_arg == no_argument) |
476 | if (long_opts[i].has_arg == no_argument) |
| 472 | printf(" -%c, --%-13s× %s\n", long_opts[i].val, |
477 | printf(" -%c, --%-13s× %s\n", long_opts[i].val, |
| … | |
… | |
| 503 | break; |
508 | break; |
| 504 | } |
509 | } |
| 505 | |
510 | |
| 506 | case 's': find_sym = strdup(optarg); break; |
511 | case 's': find_sym = strdup(optarg); break; |
| 507 | |
512 | |
|
|
513 | case 'y': scan_symlink = 0; break; |
| 508 | case 'B': show_banner = 0; break; |
514 | case 'B': show_banner = 0; break; |
| 509 | case 'l': scan_ldpath = 1; break; |
515 | case 'l': scan_ldpath = 1; break; |
| 510 | case 'p': scan_envpath = 1; break; |
516 | case 'p': scan_envpath = 1; break; |
| 511 | case 'R': dir_recurse = 1; break; |
517 | case 'R': dir_recurse = 1; break; |
| 512 | case 'm': dir_crossmount = 0; break; |
518 | case 'm': dir_crossmount = 0; break; |