/[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.72 Revision 1.73
1/* 1/*
2 * Copyright 2003-2005 Gentoo Foundation 2 * Copyright 2003-2005 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2 3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.72 2005/06/04 06:23:06 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.73 2005/06/04 13:52:54 solar Exp $
5 * 5 *
6 ******************************************************************** 6 ********************************************************************
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the 9 * published by the Free Software Foundation; either version 2 of the
33#include <dirent.h> 33#include <dirent.h>
34#include <getopt.h> 34#include <getopt.h>
35#include <assert.h> 35#include <assert.h>
36#include "paxelf.h" 36#include "paxelf.h"
37 37
38static const char *rcsid = "$Id: scanelf.c,v 1.72 2005/06/04 06:23:06 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.73 2005/06/04 13:52:54 solar Exp $";
39#define argv0 "scanelf" 39#define argv0 "scanelf"
40 40
41#define IS_MODIFIER(c) (c == '%' || c == '#') 41#define IS_MODIFIER(c) (c == '%' || c == '#')
42 42
43 43
60static char scan_envpath = 0; 60static char scan_envpath = 0;
61static char scan_symlink = 1; 61static char scan_symlink = 1;
62static char dir_recurse = 0; 62static char dir_recurse = 0;
63static char dir_crossmount = 1; 63static char dir_crossmount = 1;
64static char show_pax = 0; 64static char show_pax = 0;
65static char show_stack = 0; 65static char show_phdr = 0;
66static char show_textrel = 0; 66static char show_textrel = 0;
67static char show_rpath = 0; 67static char show_rpath = 0;
68static char show_needed = 0; 68static char show_needed = 0;
69static char show_interp = 0; 69static char show_interp = 0;
70static char show_bind = 0; 70static char show_bind = 0;
126 if (be_quiet && !shown) 126 if (be_quiet && !shown)
127 return NULL; 127 return NULL;
128 return ret; 128 return ret;
129 129
130} 130}
131static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro, char *found_load) 131static char *scanelf_file_phdr(elfobj *elf, char *found_phdr, char *found_relro, char *found_load)
132{ 132{
133 static char ret[12]; 133 static char ret[12];
134 char *found; 134 char *found;
135 unsigned long i, off, shown, check_flags; 135 unsigned long i, off, shown, check_flags;
136 unsigned char multi_stack, multi_relro, multi_load; 136 unsigned char multi_stack, multi_relro, multi_load;
137 137
138 if (!show_stack) return NULL; 138 if (!show_phdr) return NULL;
139 139
140 memcpy(ret, "--- --- ---\0", 12); 140 memcpy(ret, "--- --- ---\0", 12);
141 141
142 shown = 0; 142 shown = 0;
143 multi_stack = multi_relro = multi_load = 0; 143 multi_stack = multi_relro = multi_load = 0;
144 144
145 if (elf->phdr) { 145 if (elf->phdr) {
146#define SHOW_STACK(B) \ 146#define SHOW_PHDR(B) \
147 if (elf->elf_class == ELFCLASS ## B) { \ 147 if (elf->elf_class == ELFCLASS ## B) { \
148 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 148 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
149 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 149 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
150 uint32_t flags; \ 150 uint32_t flags; \
151 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 151 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
152 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ 152 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \
153 if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \ 153 if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \
154 found = found_stack; \ 154 found = found_phdr; \
155 off = 0; \ 155 off = 0; \
156 check_flags = PF_X; \ 156 check_flags = PF_X; \
157 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \ 157 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \
158 if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \ 158 if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \
159 found = found_relro; \ 159 found = found_relro; \
172 memcpy(ret+off, gnu_short_stack_flags(flags), 3); \ 172 memcpy(ret+off, gnu_short_stack_flags(flags), 3); \
173 *found = 1; \ 173 *found = 1; \
174 ++shown; \ 174 ++shown; \
175 } \ 175 } \
176 } 176 }
177 SHOW_STACK(32) 177 SHOW_PHDR(32)
178 SHOW_STACK(64) 178 SHOW_PHDR(64)
179 } 179 }
180 180
181 if (be_quiet && !shown) 181 if (be_quiet && !shown)
182 return NULL; 182 return NULL;
183 else 183 else
483/* scan an elf file and show all the fun stuff */ 483/* scan an elf file and show all the fun stuff */
484#define prints(str) write(fileno(stdout), str, strlen(str)) 484#define prints(str) write(fileno(stdout), str, strlen(str))
485static void scanelf_file(const char *filename) 485static void scanelf_file(const char *filename)
486{ 486{
487 unsigned long i; 487 unsigned long i;
488 char found_pax, found_stack, found_relro, found_load, found_textrel, 488 char found_pax, found_phdr, found_relro, found_load, found_textrel,
489 found_rpath, found_needed, found_interp, found_bind, 489 found_rpath, found_needed, found_interp, found_bind,
490 found_sym, found_lib, found_file; 490 found_sym, found_lib, found_file;
491 elfobj *elf; 491 elfobj *elf;
492 struct stat st; 492 struct stat st;
493 static char *out_buffer = NULL; 493 static char *out_buffer = NULL;
506 if (!S_ISREG(st.st_mode)) { 506 if (!S_ISREG(st.st_mode)) {
507 if (be_verbose > 2) printf("%s: skipping non-file\n", filename); 507 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
508 return; 508 return;
509 } 509 }
510 510
511 found_pax = found_stack = found_relro = found_load = \ 511 found_pax = found_phdr = found_relro = found_load = \
512 found_textrel = found_rpath = found_needed = found_interp = \ 512 found_textrel = found_rpath = found_needed = found_interp = \
513 found_bind = found_sym = found_lib = found_file = 0; 513 found_bind = found_sym = found_lib = found_file = 0;
514 514
515 /* verify this is real ELF */ 515 /* verify this is real ELF */
516 if ((elf = readelf(filename)) == NULL) { 516 if ((elf = readelf(filename)) == NULL) {
607 tmp = (tmp == NULL ? filename : tmp+1); 607 tmp = (tmp == NULL ? filename : tmp+1);
608 xstrcat(&out_buffer, tmp, &out_len); 608 xstrcat(&out_buffer, tmp, &out_len);
609 break; 609 break;
610 case 'o': out = get_elfetype(elf); break; 610 case 'o': out = get_elfetype(elf); break;
611 case 'x': out = scanelf_file_pax(elf, &found_pax); break; 611 case 'x': out = scanelf_file_pax(elf, &found_pax); break;
612 case 'e': out = scanelf_file_stack(elf, &found_stack, &found_relro, &found_load); break; 612 case 'e': out = scanelf_file_phdr(elf, &found_phdr, &found_relro, &found_load); break;
613 case 't': out = scanelf_file_textrel(elf, &found_textrel); break; 613 case 't': out = scanelf_file_textrel(elf, &found_textrel); break;
614 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break; 614 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break;
615 case 'n': 615 case 'n':
616 case 'N': out = scanelf_file_needed_lib(elf, &found_needed, &found_lib, (out_format[i]=='N'), &out_buffer, &out_len); break; 616 case 'N': out = scanelf_file_needed_lib(elf, &found_needed, &found_lib, (out_format[i]=='N'), &out_buffer, &out_len); break;
617 case 'i': out = scanelf_file_interp(elf, &found_interp); break; 617 case 'i': out = scanelf_file_interp(elf, &found_interp); break;
620 } 620 }
621 if (out) xstrcat(&out_buffer, out, &out_len); 621 if (out) xstrcat(&out_buffer, out, &out_len);
622 } 622 }
623 623
624#define FOUND_SOMETHING() \ 624#define FOUND_SOMETHING() \
625 (found_pax || found_stack || found_relro || found_load || found_textrel || \ 625 (found_pax || found_phdr || found_relro || found_load || found_textrel || \
626 found_rpath || found_needed || found_interp || found_bind || found_sym || found_lib) 626 found_rpath || found_needed || found_interp || found_bind || found_sym || found_lib)
627 627
628 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) { 628 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) {
629 xchrcat(&out_buffer, ' ', &out_len); 629 xchrcat(&out_buffer, ' ', &out_len);
630 xstrcat(&out_buffer, filename, &out_len); 630 xstrcat(&out_buffer, filename, &out_len);
667 while ((dentry = readdir(dir))) { 667 while ((dentry = readdir(dir))) {
668 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, "..")) 668 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
669 continue; 669 continue;
670 len = (pathlen + 1 + strlen(dentry->d_name) + 1); 670 len = (pathlen + 1 + strlen(dentry->d_name) + 1);
671 if (len >= sizeof(buf)) { 671 if (len >= sizeof(buf)) {
672 warnf("Skipping '%s': len > sizeof(buf); %d > %d\n", path, (int)len, (int)sizeof(buf)); 672 warnf("Skipping '%s': len > sizeof(buf); %u > %u\n", path, len, sizeof(buf));
673 continue; 673 continue;
674 } 674 }
675 sprintf(buf, "%s/%s", path, dentry->d_name); 675 sprintf(buf, "%s/%s", path, dentry->d_name);
676 if (lstat(buf, &st) != -1) { 676 if (lstat(buf, &st) != -1) {
677 if (S_ISREG(st.st_mode)) 677 if (S_ISREG(st.st_mode))
795 {"rpath", no_argument, NULL, 'r'}, 795 {"rpath", no_argument, NULL, 'r'},
796 {"needed", no_argument, NULL, 'n'}, 796 {"needed", no_argument, NULL, 'n'},
797 {"interp", no_argument, NULL, 'i'}, 797 {"interp", no_argument, NULL, 'i'},
798 {"bind", no_argument, NULL, 'b'}, 798 {"bind", no_argument, NULL, 'b'},
799 {"symbol", a_argument, NULL, 's'}, 799 {"symbol", a_argument, NULL, 's'},
800 {"lib", a_argument, NULL, 'N'}, 800 {"lib", a_argument, NULL, 'N'},
801 {"all", no_argument, NULL, 'a'}, 801 {"all", no_argument, NULL, 'a'},
802 {"quiet", no_argument, NULL, 'q'}, 802 {"quiet", no_argument, NULL, 'q'},
803 {"verbose", no_argument, NULL, 'v'}, 803 {"verbose", no_argument, NULL, 'v'},
804 {"format", a_argument, NULL, 'F'}, 804 {"format", a_argument, NULL, 'F'},
805 {"from", a_argument, NULL, 'f'}, 805 {"from", a_argument, NULL, 'f'},
922 case 'l': scan_ldpath = 1; break; 922 case 'l': scan_ldpath = 1; break;
923 case 'p': scan_envpath = 1; break; 923 case 'p': scan_envpath = 1; break;
924 case 'R': dir_recurse = 1; break; 924 case 'R': dir_recurse = 1; break;
925 case 'm': dir_crossmount = 0; break; 925 case 'm': dir_crossmount = 0; break;
926 case 'x': show_pax = 1; break; 926 case 'x': show_pax = 1; break;
927 case 'e': show_stack = 1; break; 927 case 'e': show_phdr = 1; break;
928 case 't': show_textrel = 1; break; 928 case 't': show_textrel = 1; break;
929 case 'r': show_rpath = 1; break; 929 case 'r': show_rpath = 1; break;
930 case 'n': show_needed = 1; break; 930 case 'n': show_needed = 1; break;
931 case 'i': show_interp = 1; break; 931 case 'i': show_interp = 1; break;
932 case 'b': show_bind = 1; break; 932 case 'b': show_bind = 1; break;
933 case 'q': be_quiet = 1; break; 933 case 'q': be_quiet = 1; break;
934 case 'v': be_verbose = (be_verbose % 20) + 1; break; 934 case 'v': be_verbose = (be_verbose % 20) + 1; break;
935 case 'a': show_pax = show_stack = show_textrel = show_rpath = \ 935 case 'a': show_pax = show_phdr = show_textrel = show_rpath = \
936 show_needed = show_interp = show_bind = 1; break; 936 show_needed = show_interp = show_bind = 1; break;
937 937
938 case ':': 938 case ':':
939 err("Option missing parameter\n"); 939 err("Option missing parameter\n");
940 case '?': 940 case '?':
944 } 944 }
945 } 945 }
946 946
947 /* let the format option override all other options */ 947 /* let the format option override all other options */
948 if (out_format) { 948 if (out_format) {
949 show_pax = show_stack = show_textrel = show_rpath = \ 949 show_pax = show_phdr = show_textrel = show_rpath = \
950 show_needed = show_interp = show_bind = 0; 950 show_needed = show_interp = show_bind = 0;
951 for (i = 0; out_format[i]; ++i) { 951 for (i = 0; out_format[i]; ++i) {
952 if (!IS_MODIFIER(out_format[i])) continue; 952 if (!IS_MODIFIER(out_format[i])) continue;
953 953
954 switch (out_format[++i]) { 954 switch (out_format[++i]) {
959 case 'f': break; 959 case 'f': break;
960 case 's': break; 960 case 's': break;
961 case 'N': break; 961 case 'N': break;
962 case 'o': break; 962 case 'o': break;
963 case 'x': show_pax = 1; break; 963 case 'x': show_pax = 1; break;
964 case 'e': show_stack = 1; break; 964 case 'e': show_phdr = 1; break;
965 case 't': show_textrel = 1; break; 965 case 't': show_textrel = 1; break;
966 case 'r': show_rpath = 1; break; 966 case 'r': show_rpath = 1; break;
967 case 'n': show_needed = 1; break; 967 case 'n': show_needed = 1; break;
968 case 'i': show_interp = 1; break; 968 case 'i': show_interp = 1; break;
969 case 'b': show_bind = 1; break; 969 case 'b': show_bind = 1; break;
977 } else { 977 } else {
978 size_t fmt_len = 30; 978 size_t fmt_len = 30;
979 out_format = (char*)xmalloc(sizeof(char) * fmt_len); 979 out_format = (char*)xmalloc(sizeof(char) * fmt_len);
980 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len); 980 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len);
981 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len); 981 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len);
982 if (show_stack) xstrcat(&out_format, "%e ", &fmt_len); 982 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len);
983 if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len); 983 if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len);
984 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len); 984 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len);
985 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len); 985 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len);
986 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len); 986 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len);
987 if (show_bind) xstrcat(&out_format, "%b ", &fmt_len); 987 if (show_bind) xstrcat(&out_format, "%b ", &fmt_len);

Legend:
Removed from v.1.72  
changed lines
  Added in v.1.73

  ViewVC Help
Powered by ViewVC 1.1.20