/[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.179 Revision 1.180
1/* 1/*
2 * Copyright 2003-2007 Gentoo Foundation 2 * Copyright 2003-2007 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.179 2007/06/09 18:54:44 solar Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.180 2007/06/09 21:43:53 solar Exp $
5 * 5 *
6 * Copyright 2003-2007 Ned Ludd - <solar@gentoo.org> 6 * Copyright 2003-2007 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2007 Mike Frysinger - <vapier@gentoo.org> 7 * Copyright 2004-2007 Mike Frysinger - <vapier@gentoo.org>
8 */ 8 */
9 9
10#include "paxinc.h" 10#include "paxinc.h"
11 11
12static const char *rcsid = "$Id: scanelf.c,v 1.179 2007/06/09 18:54:44 solar Exp $"; 12static const char *rcsid = "$Id: scanelf.c,v 1.180 2007/06/09 21:43:53 solar Exp $";
13#define argv0 "scanelf" 13#define argv0 "scanelf"
14 14
15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+') 15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+')
16 16
17/* prototypes */ 17/* prototypes */
43static char scan_symlink = 1; 43static char scan_symlink = 1;
44static char scan_archives = 0; 44static char scan_archives = 0;
45static char dir_recurse = 0; 45static char dir_recurse = 0;
46static char dir_crossmount = 1; 46static char dir_crossmount = 1;
47static char show_pax = 0; 47static char show_pax = 0;
48static char show_perms = 0;
48static char show_phdr = 0; 49static char show_phdr = 0;
49static char show_textrel = 0; 50static char show_textrel = 0;
50static char show_rpath = 0; 51static char show_rpath = 0;
51static char show_needed = 0; 52static char show_needed = 0;
52static char show_interp = 0; 53static char show_interp = 0;
70static char **qa_textrels = NULL; 71static char **qa_textrels = NULL;
71static char **qa_execstack = NULL; 72static char **qa_execstack = NULL;
72static char **qa_wx_load = NULL; 73static char **qa_wx_load = NULL;
73 74
74int match_bits = 0; 75int match_bits = 0;
76unsigned int match_perms = 0;
75caddr_t ldcache = 0; 77caddr_t ldcache = 0;
76size_t ldcache_size = 0; 78size_t ldcache_size = 0;
77unsigned long setpax = 0UL; 79unsigned long setpax = 0UL;
78 80
79int has_objdump = 0; 81int has_objdump = 0;
82
83static char *getstr_perms(const char *fname);
84static char *getstr_perms(const char *fname) {
85 struct stat st;
86 static char buf[8];
87
88 if ((stat(fname, &st)) == (-1))
89 return (char *) "";
90
91 snprintf(buf, sizeof(buf), "%o", st.st_mode);
92
93 return (char *) buf + 2;
94}
80 95
81/* find the path to a file by name */ 96/* find the path to a file by name */
82static char *which(const char *fname) 97static char *which(const char *fname)
83{ 98{
84 static char fullpath[BUFSIZ]; 99 static char fullpath[BUFSIZ];
362 if (be_quiet || be_wewy_wewy_quiet) 377 if (be_quiet || be_wewy_wewy_quiet)
363 return NULL; 378 return NULL;
364 else 379 else
365 return " - "; 380 return " - ";
366} 381}
382
367static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel) 383static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel)
368{ 384{
369 unsigned long s, r, rmax; 385 unsigned long s, r, rmax;
370 void *symtab_void, *strtab_void, *text_void; 386 void *symtab_void, *strtab_void, *text_void;
371 387
1134 case 's': prints("SYM "); break; 1150 case 's': prints("SYM "); break;
1135 case 'N': prints("LIB "); break; 1151 case 'N': prints("LIB "); break;
1136 case 'T': prints("TEXTRELS "); break; 1152 case 'T': prints("TEXTRELS "); break;
1137 case 'k': prints("SECTION "); break; 1153 case 'k': prints("SECTION "); break;
1138 case 'a': prints("ARCH "); break; 1154 case 'a': prints("ARCH "); break;
1155 case 'O': prints("PERM "); break;
1139 default: warnf("'%c' has no title ?", out_format[i]); 1156 default: warnf("'%c' has no title ?", out_format[i]);
1140 } 1157 }
1141 } 1158 }
1142 if (!found_file) prints("FILE "); 1159 if (!found_file) prints("FILE ");
1143 prints("\n"); 1160 prints("\n");
1194 case 'e': out = scanelf_file_phdr(elf, &found_phdr, &found_relro, &found_load); break; 1211 case 'e': out = scanelf_file_phdr(elf, &found_phdr, &found_relro, &found_load); break;
1195 case 't': out = scanelf_file_textrel(elf, &found_textrel); break; 1212 case 't': out = scanelf_file_textrel(elf, &found_textrel); break;
1196 case 'T': out = scanelf_file_textrels(elf, &found_textrels, &found_textrel); break; 1213 case 'T': out = scanelf_file_textrels(elf, &found_textrels, &found_textrel); break;
1197 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break; 1214 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break;
1198 case 'M': out = get_elfeitype(EI_CLASS, elf->data[EI_CLASS]); break; 1215 case 'M': out = get_elfeitype(EI_CLASS, elf->data[EI_CLASS]); break;
1216 case 'O': out = getstr_perms(elf->filename); break;
1199 case 'n': 1217 case 'n':
1200 case 'N': out = scanelf_file_needed_lib(elf, &found_needed, &found_lib, (out_format[i]=='N'), &out_buffer, &out_len); break; 1218 case 'N': out = scanelf_file_needed_lib(elf, &found_needed, &found_lib, (out_format[i]=='N'), &out_buffer, &out_len); break;
1201 case 'i': out = scanelf_file_interp(elf, &found_interp); break; 1219 case 'i': out = scanelf_file_interp(elf, &found_interp); break;
1202 case 'b': out = scanelf_file_bind(elf, &found_bind); break; 1220 case 'b': out = scanelf_file_bind(elf, &found_bind); break;
1203 case 'S': out = scanelf_file_soname(elf, &found_soname); break; 1221 case 'S': out = scanelf_file_soname(elf, &found_soname); break;
1318 if (!S_ISREG(st->st_mode)) { 1336 if (!S_ISREG(st->st_mode)) {
1319 if (be_verbose > 2) printf("%s: skipping non-file\n", filename); 1337 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
1320 return 1; 1338 return 1;
1321 } 1339 }
1322 1340
1341 if (match_perms) {
1342 if ((st->st_mode | match_perms) != st->st_mode)
1343 return 1;
1344 }
1323 if ((fd=open(filename, (fix_elf ? O_RDWR : O_RDONLY))) == -1) 1345 if ((fd=open(filename, (fix_elf ? O_RDWR : O_RDONLY))) == -1)
1324 return 1; 1346 return 1;
1325 1347
1326 if (scanelf_elf(filename, fd, st->st_size) == 1 && scan_archives) 1348 if (scanelf_elf(filename, fd, st->st_size) == 1 && scan_archives)
1327 /* if it isn't an ELF, maybe it's an .a archive */ 1349 /* if it isn't an ELF, maybe it's an .a archive */
1563 1585
1564 free(path); 1586 free(path);
1565} 1587}
1566 1588
1567/* usage / invocation handling functions */ 1589/* usage / invocation handling functions */
1568#define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:BhV" 1590#define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:O:BhV"
1569#define a_argument required_argument 1591#define a_argument required_argument
1570static struct option const long_opts[] = { 1592static struct option const long_opts[] = {
1571 {"path", no_argument, NULL, 'p'}, 1593 {"path", no_argument, NULL, 'p'},
1572 {"ldpath", no_argument, NULL, 'l'}, 1594 {"ldpath", no_argument, NULL, 'l'},
1573 {"recursive", no_argument, NULL, 'R'}, 1595 {"recursive", no_argument, NULL, 'R'},
1590 {"lib", a_argument, NULL, 'N'}, 1612 {"lib", a_argument, NULL, 'N'},
1591 {"gmatch", no_argument, NULL, 'g'}, 1613 {"gmatch", no_argument, NULL, 'g'},
1592 {"textrels", no_argument, NULL, 'T'}, 1614 {"textrels", no_argument, NULL, 'T'},
1593 {"etype", a_argument, NULL, 'E'}, 1615 {"etype", a_argument, NULL, 'E'},
1594 {"bits", a_argument, NULL, 'M'}, 1616 {"bits", a_argument, NULL, 'M'},
1617 {"perms", a_argument, NULL, 'O'},
1595 {"all", no_argument, NULL, 'a'}, 1618 {"all", no_argument, NULL, 'a'},
1596 {"quiet", no_argument, NULL, 'q'}, 1619 {"quiet", no_argument, NULL, 'q'},
1597 {"verbose", no_argument, NULL, 'v'}, 1620 {"verbose", no_argument, NULL, 'v'},
1598 {"format", a_argument, NULL, 'F'}, 1621 {"format", a_argument, NULL, 'F'},
1599 {"from", a_argument, NULL, 'f'}, 1622 {"from", a_argument, NULL, 'f'},
1627 "Find a specified library", 1650 "Find a specified library",
1628 "Use strncmp to match libraries. (use with -N)", 1651 "Use strncmp to match libraries. (use with -N)",
1629 "Locate cause of TEXTREL", 1652 "Locate cause of TEXTREL",
1630 "Print only ELF files matching etype ET_DYN,ET_EXEC ...", 1653 "Print only ELF files matching etype ET_DYN,ET_EXEC ...",
1631 "Print only ELF files matching numeric bits", 1654 "Print only ELF files matching numeric bits",
1655 "Print only ELF files matching octal permissions",
1632 "Print all scanned info (-x -e -t -r -b)\n", 1656 "Print all scanned info (-x -e -t -r -b)\n",
1633 "Only output 'bad' things", 1657 "Only output 'bad' things",
1634 "Be verbose (can be specified more than once)", 1658 "Be verbose (can be specified more than once)",
1635 "Use specified format for output", 1659 "Use specified format for output",
1636 "Read input stream from a filename", 1660 "Read input stream from a filename",
1693 case 'E': 1717 case 'E':
1694 strncpy(match_etypes, optarg, sizeof(match_etypes)); 1718 strncpy(match_etypes, optarg, sizeof(match_etypes));
1695 break; 1719 break;
1696 case 'M': 1720 case 'M':
1697 match_bits = atoi(optarg); 1721 match_bits = atoi(optarg);
1722 break;
1723 case 'O':
1724 if (sscanf(optarg, "%o", &match_perms) == (-1))
1725 match_bits = 0;
1698 break; 1726 break;
1699 case 'o': { 1727 case 'o': {
1700 if (freopen(optarg, "w", stdout) == NULL) 1728 if (freopen(optarg, "w", stdout) == NULL)
1701 err("Could not open output stream '%s': %s", optarg, strerror(errno)); 1729 err("Could not open output stream '%s': %s", optarg, strerror(errno));
1702 break; 1730 break;
1785 case 'b': show_bind = 1; break; 1813 case 'b': show_bind = 1; break;
1786 case 'S': show_soname = 1; break; 1814 case 'S': show_soname = 1; break;
1787 case 'T': show_textrels = 1; break; 1815 case 'T': show_textrels = 1; break;
1788 case 'q': be_quiet = 1; break; 1816 case 'q': be_quiet = 1; break;
1789 case 'v': be_verbose = (be_verbose % 20) + 1; break; 1817 case 'v': be_verbose = (be_verbose % 20) + 1; break;
1790 case 'a': show_pax = show_phdr = show_textrel = show_rpath = show_bind = 1; break; 1818 case 'a': show_perms = show_pax = show_phdr = show_textrel = show_rpath = show_bind = 1; break;
1791 1819
1792 case ':': 1820 case ':':
1793 err("Option '%c' is missing parameter", optopt); 1821 err("Option '%c' is missing parameter", optopt);
1794 case '?': 1822 case '?':
1795 err("Unknown option '%c' or argument missing", optopt); 1823 err("Unknown option '%c' or argument missing", optopt);
1803 } 1831 }
1804 /* let the format option override all other options */ 1832 /* let the format option override all other options */
1805 if (out_format) { 1833 if (out_format) {
1806 show_pax = show_phdr = show_textrel = show_rpath = \ 1834 show_pax = show_phdr = show_textrel = show_rpath = \
1807 show_needed = show_interp = show_bind = show_soname = \ 1835 show_needed = show_interp = show_bind = show_soname = \
1808 show_textrels = 0; 1836 show_textrels = show_perms = 0;
1809 for (i = 0; out_format[i]; ++i) { 1837 for (i = 0; out_format[i]; ++i) {
1810 if (!IS_MODIFIER(out_format[i])) continue; 1838 if (!IS_MODIFIER(out_format[i])) continue;
1811 1839
1812 switch (out_format[++i]) { 1840 switch (out_format[++i]) {
1813 case '+': break; 1841 case '+': break;
1820 case 's': break; 1848 case 's': break;
1821 case 'N': break; 1849 case 'N': break;
1822 case 'o': break; 1850 case 'o': break;
1823 case 'a': break; 1851 case 'a': break;
1824 case 'M': break; 1852 case 'M': break;
1853 case 'O': show_perms = 1; break;
1825 case 'x': show_pax = 1; break; 1854 case 'x': show_pax = 1; break;
1826 case 'e': show_phdr = 1; break; 1855 case 'e': show_phdr = 1; break;
1827 case 't': show_textrel = 1; break; 1856 case 't': show_textrel = 1; break;
1828 case 'r': show_rpath = 1; break; 1857 case 'r': show_rpath = 1; break;
1829 case 'n': show_needed = 1; break; 1858 case 'n': show_needed = 1; break;
1841 } else { 1870 } else {
1842 size_t fmt_len = 30; 1871 size_t fmt_len = 30;
1843 out_format = (char*)xmalloc(sizeof(char) * fmt_len); 1872 out_format = (char*)xmalloc(sizeof(char) * fmt_len);
1844 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len); 1873 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len);
1845 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len); 1874 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len);
1875 if (show_perms) xstrcat(&out_format, "%O ", &fmt_len);
1846 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len); 1876 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len);
1847 if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len); 1877 if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len);
1848 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len); 1878 if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len);
1849 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len); 1879 if (show_needed) xstrcat(&out_format, "%n ", &fmt_len);
1850 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len); 1880 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len);

Legend:
Removed from v.1.179  
changed lines
  Added in v.1.180

  ViewVC Help
Powered by ViewVC 1.1.20