/[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.70 Revision 1.71
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/scanelf.c,v 1.70 2005/06/03 23:41:59 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.71 2005/06/04 02:50:50 vapier 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.70 2005/06/03 23:41:59 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.71 2005/06/04 02:50:50 vapier 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
125 if (be_quiet && !shown) 125 if (be_quiet && !shown)
126 return NULL; 126 return NULL;
127 return ret; 127 return ret;
128 128
129} 129}
130static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro) 130static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro, char *found_load)
131{ 131{
132 static char ret[8] = "--- ---"; 132 static char ret[12];
133 char *found; 133 char *found;
134 unsigned long i, off, shown; 134 unsigned long i, off, shown, check_flags;
135 unsigned char multi_stack, multi_relro, multi_load;
135 136
136 if (!show_stack) return NULL; 137 if (!show_stack) return NULL;
137 138
139 memcpy(ret, "--- --- ---\0", 12);
140
138 shown = 0; 141 shown = 0;
142 multi_stack = multi_relro = multi_load = 0;
139 143
140 if (elf->phdr) { 144 if (elf->phdr) {
141#define SHOW_STACK(B) \ 145#define SHOW_STACK(B) \
142 if (elf->elf_class == ELFCLASS ## B) { \ 146 if (elf->elf_class == ELFCLASS ## B) { \
143 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 147 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
144 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 148 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
149 uint32_t flags; \
145 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 150 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
146 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ 151 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \
152 if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \
147 found = found_stack; \ 153 found = found_stack; \
148 off = 0; \ 154 off = 0; \
155 check_flags = PF_X; \
149 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \ 156 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \
157 if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \
150 found = found_relro; \ 158 found = found_relro; \
151 off = 4; \ 159 off = 4; \
160 check_flags = PF_X; \
161 } else if (EGET(phdr[i].p_type) == PT_LOAD) { \
162 if (multi_load++ > 2) warnf("%s: more than 2 PT_LOAD's !?", elf->filename); \
163 found = found_load; \
164 off = 8; \
165 check_flags = PF_W|PF_X; \
152 } else \ 166 } else \
153 continue; \ 167 continue; \
154 if (be_quiet && !(EGET(phdr[i].p_flags) & PF_X)) \ 168 flags = EGET(phdr[i].p_flags); \
169 if (be_quiet && ((flags & check_flags) != check_flags)) \
155 continue; \ 170 continue; \
156 memcpy(ret+off, gnu_short_stack_flags(EGET(phdr[i].p_flags)), 3); \ 171 memcpy(ret+off, gnu_short_stack_flags(flags), 3); \
157 *found = 1; \ 172 *found = 1; \
158 ++shown; \ 173 ++shown; \
159 } \ 174 } \
160 } 175 }
161 SHOW_STACK(32) 176 SHOW_STACK(32)
457/* scan an elf file and show all the fun stuff */ 472/* scan an elf file and show all the fun stuff */
458#define prints(str) write(fileno(stdout), str, strlen(str)) 473#define prints(str) write(fileno(stdout), str, strlen(str))
459static void scanelf_file(const char *filename) 474static void scanelf_file(const char *filename)
460{ 475{
461 unsigned long i; 476 unsigned long i;
462 char found_pax, found_stack, found_relro, found_textrel, 477 char found_pax, found_stack, found_relro, found_load, found_textrel,
463 found_rpath, found_needed, found_interp, found_bind, 478 found_rpath, found_needed, found_interp, found_bind,
464 found_sym, found_file; 479 found_sym, found_file;
465 elfobj *elf; 480 elfobj *elf;
466 struct stat st; 481 struct stat st;
467 static char *out_buffer = NULL; 482 static char *out_buffer = NULL;
480 if (!S_ISREG(st.st_mode)) { 495 if (!S_ISREG(st.st_mode)) {
481 if (be_verbose > 2) printf("%s: skipping non-file\n", filename); 496 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
482 return; 497 return;
483 } 498 }
484 499
485 found_pax = found_stack = found_relro = found_textrel = \ 500 found_pax = found_stack = found_relro = found_load = \
486 found_rpath = found_needed = found_interp = found_bind = \ 501 found_textrel = found_rpath = found_needed = found_interp = \
487 found_sym = found_file = 0; 502 found_bind = found_sym = found_file = 0;
488 503
489 /* verify this is real ELF */ 504 /* verify this is real ELF */
490 if ((elf = readelf(filename)) == NULL) { 505 if ((elf = readelf(filename)) == NULL) {
491 if (be_verbose > 2) printf("%s: not an ELF\n", filename); 506 if (be_verbose > 2) printf("%s: not an ELF\n", filename);
492 return; 507 return;
517 case 'F': 532 case 'F':
518 case 'p': 533 case 'p':
519 case 'f': prints("FILE "); found_file = 1; break; 534 case 'f': prints("FILE "); found_file = 1; break;
520 case 'o': prints(" TYPE "); break; 535 case 'o': prints(" TYPE "); break;
521 case 'x': prints(" PAX "); break; 536 case 'x': prints(" PAX "); break;
522 case 'e': prints("STK/REL "); break; 537 case 'e': prints("STK/REL/PTL "); break;
523 case 't': prints("TEXTREL "); break; 538 case 't': prints("TEXTREL "); break;
524 case 'r': prints("RPATH "); break; 539 case 'r': prints("RPATH "); break;
525 case 'n': prints("NEEDED "); break; 540 case 'n': prints("NEEDED "); break;
526 case 'i': prints("INTERP "); break; 541 case 'i': prints("INTERP "); break;
527 case 'b': prints("BIND "); break; 542 case 'b': prints("BIND "); break;
580 tmp = (tmp == NULL ? filename : tmp+1); 595 tmp = (tmp == NULL ? filename : tmp+1);
581 xstrcat(&out_buffer, tmp, &out_len); 596 xstrcat(&out_buffer, tmp, &out_len);
582 break; 597 break;
583 case 'o': out = get_elfetype(elf); break; 598 case 'o': out = get_elfetype(elf); break;
584 case 'x': out = scanelf_file_pax(elf, &found_pax); break; 599 case 'x': out = scanelf_file_pax(elf, &found_pax); break;
585 case 'e': out = scanelf_file_stack(elf, &found_stack, &found_relro); break; 600 case 'e': out = scanelf_file_stack(elf, &found_stack, &found_relro, &found_load); break;
586 case 't': out = scanelf_file_textrel(elf, &found_textrel); break; 601 case 't': out = scanelf_file_textrel(elf, &found_textrel); break;
587 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break; 602 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break;
588 case 'n': scanelf_file_needed(elf, &found_needed, &out_buffer, &out_len); break; 603 case 'n': scanelf_file_needed(elf, &found_needed, &out_buffer, &out_len); break;
589 case 'i': out = scanelf_file_interp(elf, &found_interp); break; 604 case 'i': out = scanelf_file_interp(elf, &found_interp); break;
590 case 'b': out = scanelf_file_bind(elf, &found_bind); break; 605 case 'b': out = scanelf_file_bind(elf, &found_bind); break;
592 } 607 }
593 if (out) xstrcat(&out_buffer, out, &out_len); 608 if (out) xstrcat(&out_buffer, out, &out_len);
594 } 609 }
595 610
596#define FOUND_SOMETHING() \ 611#define FOUND_SOMETHING() \
597 (found_pax || found_stack || found_textrel || found_rpath || \ 612 (found_pax || found_stack || found_relro || found_load || found_textrel || \
598 found_needed || found_interp || found_bind || found_sym) 613 found_rpath || found_needed || found_interp || found_bind || found_sym)
599 614
600 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) { 615 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) {
601 xchrcat(&out_buffer, ' ', &out_len); 616 xchrcat(&out_buffer, ' ', &out_len);
602 xstrcat(&out_buffer, filename, &out_len); 617 xstrcat(&out_buffer, filename, &out_len);
603 } 618 }
786 "Scan all directories in /etc/ld.so.conf", 801 "Scan all directories in /etc/ld.so.conf",
787 "Scan directories recursively", 802 "Scan directories recursively",
788 "Don't recursively cross mount points", 803 "Don't recursively cross mount points",
789 "Don't scan symlinks\n", 804 "Don't scan symlinks\n",
790 "Print PaX markings", 805 "Print PaX markings",
791 "Print GNU_STACK markings", 806 "Print GNU_STACK/PT_LOAD markings",
792 "Print TEXTREL information", 807 "Print TEXTREL information",
793 "Print RPATH information", 808 "Print RPATH information",
794 "Print NEEDED information", 809 "Print NEEDED information",
795 "Print INTERP information", 810 "Print INTERP information",
796 "Print BIND information", 811 "Print BIND information",

Legend:
Removed from v.1.70  
changed lines
  Added in v.1.71

  ViewVC Help
Powered by ViewVC 1.1.20