/[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.126 Revision 1.127
1/* 1/*
2 * Copyright 2003-2006 Gentoo Foundation 2 * Copyright 2003-2006 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.126 2006/02/16 05:47:23 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.127 2006/02/17 07:13:54 solar Exp $
5 * 5 *
6 * Copyright 2003-2006 Ned Ludd - <solar@gentoo.org> 6 * Copyright 2003-2006 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2006 Mike Frysinger - <vapier@gentoo.org> 7 * Copyright 2004-2006 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.126 2006/02/16 05:47:23 vapier Exp $"; 12static const char *rcsid = "$Id: scanelf.c,v 1.127 2006/02/17 07:13:54 solar Exp $";
13#define argv0 "scanelf" 13#define argv0 "scanelf"
14 14
15#define IS_MODIFIER(c) (c == '%' || c == '#') 15#define IS_MODIFIER(c) (c == '%' || c == '#')
16 16
17 17
51static char show_soname = 0; 51static char show_soname = 0;
52static char show_textrels = 0; 52static char show_textrels = 0;
53static char show_banner = 1; 53static char show_banner = 1;
54static char be_quiet = 0; 54static char be_quiet = 0;
55static char be_verbose = 0; 55static char be_verbose = 0;
56static char be_very_quiet = 0; 56static char be_wewy_wewy_quiet = 0;
57static char *find_sym = NULL, *versioned_symname = NULL; 57static char *find_sym = NULL, *versioned_symname = NULL;
58static char *find_lib = NULL; 58static char *find_lib = NULL;
59static char *find_section = NULL; 59static char *find_section = NULL;
60static char *out_format = NULL; 60static char *out_format = NULL;
61static char *search_path = NULL; 61static char *search_path = NULL;
64static char use_ldcache = 0; 64static char use_ldcache = 0;
65 65
66int match_bits = 0; 66int match_bits = 0;
67caddr_t ldcache = 0; 67caddr_t ldcache = 0;
68size_t ldcache_size = 0; 68size_t ldcache_size = 0;
69unsigned long setpax = 0UL;
69 70
70/* sub-funcs for scanelf_file() */ 71/* sub-funcs for scanelf_file() */
71static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) 72static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab)
72{ 73{
73 /* find the best SHT_DYNSYM and SHT_STRTAB sections */ 74 /* find the best SHT_DYNSYM and SHT_STRTAB sections */
92 } \ 93 } \
93 } 94 }
94 GET_SYMTABS(32) 95 GET_SYMTABS(32)
95 GET_SYMTABS(64) 96 GET_SYMTABS(64)
96} 97}
98
97static char *scanelf_file_pax(elfobj *elf, char *found_pax) 99static char *scanelf_file_pax(elfobj *elf, char *found_pax)
98{ 100{
99 static char ret[7]; 101 static char ret[7];
100 unsigned long i, shown; 102 unsigned long i, shown;
101 103
110 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 112 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
111 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 113 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
112 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 114 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
113 if (EGET(phdr[i].p_type) != PT_PAX_FLAGS) \ 115 if (EGET(phdr[i].p_type) != PT_PAX_FLAGS) \
114 continue; \ 116 continue; \
117 if (fix_elf && setpax) { \
118 /* set the paxctl flags */ \
119 ESET(phdr[i].p_flags, setpax); \
120 } \
115 if (be_quiet && (EGET(phdr[i].p_flags) == 10240)) \ 121 if (be_quiet && (EGET(phdr[i].p_flags) == 10240)) \
116 continue; \ 122 continue; \
117 memcpy(ret, pax_short_pf_flags(EGET(phdr[i].p_flags)), 6); \ 123 memcpy(ret, pax_short_pf_flags(EGET(phdr[i].p_flags)), 6); \
118 *found_pax = 1; \ 124 *found_pax = 1; \
119 ++shown; \ 125 ++shown; \
125 } 131 }
126 132
127 /* fall back to EI_PAX if no PT_PAX was found */ 133 /* fall back to EI_PAX if no PT_PAX was found */
128 if (!*ret) { 134 if (!*ret) {
129 static char *paxflags; 135 static char *paxflags;
136
137 if (fix_elf && setpax) {
138 /* set the chpax settings */
139 // ESET(EHDR ## B (elf->ehdr)->e_ident[EI_PAX]), setpax);
140 }
141
130 paxflags = pax_short_hf_flags(EI_PAX_FLAGS(elf)); 142 paxflags = pax_short_hf_flags(EI_PAX_FLAGS(elf));
131 if (!be_quiet || (be_quiet && EI_PAX_FLAGS(elf))) { 143 if (!be_quiet || (be_quiet && EI_PAX_FLAGS(elf))) {
132 *found_pax = 1; 144 *found_pax = 1;
133 return (be_very_quiet ? NULL : paxflags); 145 return (be_wewy_wewy_quiet ? NULL : paxflags);
134 } 146 }
135 strncpy(ret, paxflags, sizeof(ret)); 147 strncpy(ret, paxflags, sizeof(ret));
136 } 148 }
137 149
138 if (be_very_quiet || (be_quiet && !shown)) 150 if (be_wewy_wewy_quiet || (be_quiet && !shown))
139 return NULL; 151 return NULL;
140 else 152 else
141 return ret; 153 return ret;
142} 154}
143 155
231 } \ 243 } \
232 } 244 }
233 SHOW_PHDR(32) 245 SHOW_PHDR(32)
234 SHOW_PHDR(64) 246 SHOW_PHDR(64)
235 247
236 if (be_very_quiet || (be_quiet && !shown)) 248 if (be_wewy_wewy_quiet || (be_quiet && !shown))
237 return NULL; 249 return NULL;
238 else 250 else
239 return ret; 251 return ret;
240} 252}
241static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel) 253static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel)
259 dyn = DYN ## B (elf->data + offset); \ 271 dyn = DYN ## B (elf->data + offset); \
260 while (EGET(dyn->d_tag) != DT_NULL) { \ 272 while (EGET(dyn->d_tag) != DT_NULL) { \
261 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \ 273 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \
262 *found_textrel = 1; \ 274 *found_textrel = 1; \
263 /*if (dyn->d_un.d_val & DF_TEXTREL)*/ \ 275 /*if (dyn->d_un.d_val & DF_TEXTREL)*/ \
264 return (be_very_quiet ? NULL : ret); \ 276 return (be_wewy_wewy_quiet ? NULL : ret); \
265 } \ 277 } \
266 ++dyn; \ 278 ++dyn; \
267 } \ 279 } \
268 } } 280 } }
269 SHOW_TEXTREL(32) 281 SHOW_TEXTREL(32)
270 SHOW_TEXTREL(64) 282 SHOW_TEXTREL(64)
271 } 283 }
272 284
273 if (be_quiet || be_very_quiet) 285 if (be_quiet || be_wewy_wewy_quiet)
274 return NULL; 286 return NULL;
275 else 287 else
276 return " - "; 288 return " - ";
277} 289}
278static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel) 290static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel)
526 } } 538 } }
527 SHOW_RPATH(32) 539 SHOW_RPATH(32)
528 SHOW_RPATH(64) 540 SHOW_RPATH(64)
529 } 541 }
530 542
531 if (be_very_quiet) return; 543 if (be_wewy_wewy_quiet) return;
532 544
533 if (rpath && runpath) { 545 if (rpath && runpath) {
534 if (!strcmp(rpath, runpath)) { 546 if (!strcmp(rpath, runpath)) {
535 xstrcat(ret, runpath, ret_len); 547 xstrcat(ret, runpath, ret_len);
536 } else { 548 } else {
665 ++dyn; \ 677 ++dyn; \
666 continue; \ 678 continue; \
667 } \ 679 } \
668 needed = (char*)(elf->data + offset); \ 680 needed = (char*)(elf->data + offset); \
669 if (op == 0) { \ 681 if (op == 0) { \
670 if (!be_very_quiet) { \ 682 if (!be_wewy_wewy_quiet) { \
671 if (*found_needed) xchrcat(ret, ',', ret_len); \ 683 if (*found_needed) xchrcat(ret, ',', ret_len); \
672 if (use_ldcache) \ 684 if (use_ldcache) \
673 if ((p = lookup_cache_lib(elf, needed)) != NULL) \ 685 if ((p = lookup_cache_lib(elf, needed)) != NULL) \
674 needed = p; \ 686 needed = p; \
675 xstrcat(ret, needed, ret_len); \ 687 xstrcat(ret, needed, ret_len); \
676 } \ 688 } \
677 *found_needed = 1; \ 689 *found_needed = 1; \
678 } else { \ 690 } else { \
679 if (!strncmp(find_lib, needed, strlen( !gmatch ? needed : find_lib))) { \ 691 if (!strncmp(find_lib, needed, strlen( !gmatch ? needed : find_lib))) { \
680 *found_lib = 1; \ 692 *found_lib = 1; \
681 return (be_very_quiet ? NULL : needed); \ 693 return (be_wewy_wewy_quiet ? NULL : needed); \
682 } \ 694 } \
683 } \ 695 } \
684 } \ 696 } \
685 ++dyn; \ 697 ++dyn; \
686 } \ 698 } \
704 if (strtbl_void) { 716 if (strtbl_void) {
705#define SHOW_INTERP(B) \ 717#define SHOW_INTERP(B) \
706 if (elf->elf_class == ELFCLASS ## B) { \ 718 if (elf->elf_class == ELFCLASS ## B) { \
707 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 719 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
708 *found_interp = 1; \ 720 *found_interp = 1; \
709 return (be_very_quiet ? NULL : elf->data + EGET(strtbl->sh_offset)); \ 721 return (be_wewy_wewy_quiet ? NULL : elf->data + EGET(strtbl->sh_offset)); \
710 } 722 }
711 SHOW_INTERP(32) 723 SHOW_INTERP(32)
712 SHOW_INTERP(64) 724 SHOW_INTERP(64)
713 } 725 }
714 return NULL; 726 return NULL;
736 if (EGET(dyn->d_tag) == DT_BIND_NOW || \ 748 if (EGET(dyn->d_tag) == DT_BIND_NOW || \
737 (EGET(dyn->d_tag) == DT_FLAGS && EGET(dyn->d_un.d_val) & DF_BIND_NOW)) \ 749 (EGET(dyn->d_tag) == DT_FLAGS && EGET(dyn->d_un.d_val) & DF_BIND_NOW)) \
738 { \ 750 { \
739 if (be_quiet) return NULL; \ 751 if (be_quiet) return NULL; \
740 *found_bind = 1; \ 752 *found_bind = 1; \
741 return (char *)(be_very_quiet ? NULL : "NOW"); \ 753 return (char *)(be_wewy_wewy_quiet ? NULL : "NOW"); \
742 } \ 754 } \
743 ++dyn; \ 755 ++dyn; \
744 } \ 756 } \
745 } \ 757 } \
746 } 758 }
747 SHOW_BIND(32) 759 SHOW_BIND(32)
748 SHOW_BIND(64) 760 SHOW_BIND(64)
749 761
750 if (be_very_quiet) return NULL; 762 if (be_wewy_wewy_quiet) return NULL;
751 763
752 if (be_quiet && !fstat(elf->fd, &s) && !(s.st_mode & S_ISUID || s.st_mode & S_ISGID)) { 764 if (be_quiet && !fstat(elf->fd, &s) && !(s.st_mode & S_ISUID || s.st_mode & S_ISGID)) {
753 return NULL; 765 return NULL;
754 } else { 766 } else {
755 *found_bind = 1; 767 *found_bind = 1;
789 ++dyn; \ 801 ++dyn; \
790 continue; \ 802 continue; \
791 } \ 803 } \
792 soname = (char*)(elf->data + offset); \ 804 soname = (char*)(elf->data + offset); \
793 *found_soname = 1; \ 805 *found_soname = 1; \
794 return (be_very_quiet ? NULL : soname); \ 806 return (be_wewy_wewy_quiet ? NULL : soname); \
795 } \ 807 } \
796 ++dyn; \ 808 ++dyn; \
797 } \ 809 } \
798 } } 810 } }
799 SHOW_SONAME(32) 811 SHOW_SONAME(32)
860 FIND_SYM(32) 872 FIND_SYM(32)
861 FIND_SYM(64) 873 FIND_SYM(64)
862 } 874 }
863 875
864break_out: 876break_out:
865 if (be_very_quiet) return NULL; 877 if (be_wewy_wewy_quiet) return NULL;
866 878
867 if (*find_sym != '*' && *found_sym) 879 if (*find_sym != '*' && *found_sym)
868 return ret; 880 return ret;
869 if (be_quiet) 881 if (be_quiet)
870 return NULL; 882 return NULL;
887 } 899 }
888 FIND_SECTION(32) 900 FIND_SECTION(32)
889 FIND_SECTION(64) 901 FIND_SECTION(64)
890 902
891 903
892 if (be_very_quiet) return NULL; 904 if (be_wewy_wewy_quiet) return NULL;
893 905
894 if (*found_section) 906 if (*found_section)
895 return find_section; 907 return find_section;
896 908
897 if (be_quiet) 909 if (be_quiet)
971 xchrcat(&out_buffer, out_format[i], &out_len); 983 xchrcat(&out_buffer, out_format[i], &out_len);
972 continue; 984 continue;
973 } 985 }
974 986
975 out = NULL; 987 out = NULL;
976 be_very_quiet = (out_format[i] == '#'); 988 be_wewy_wewy_quiet = (out_format[i] == '#');
977 switch (out_format[++i]) { 989 switch (out_format[++i]) {
978 case '%': 990 case '%':
979 case '#': 991 case '#':
980 xchrcat(&out_buffer, out_format[i], &out_len); break; 992 xchrcat(&out_buffer, out_format[i], &out_len); break;
981 case 'F': 993 case 'F':
982 found_file = 1; 994 found_file = 1;
983 if (be_very_quiet) break; 995 if (be_wewy_wewy_quiet) break;
984 xstrcat(&out_buffer, elf->filename, &out_len); 996 xstrcat(&out_buffer, elf->filename, &out_len);
985 break; 997 break;
986 case 'p': 998 case 'p':
987 found_file = 1; 999 found_file = 1;
988 if (be_very_quiet) break; 1000 if (be_wewy_wewy_quiet) break;
989 tmp = elf->filename; 1001 tmp = elf->filename;
990 if (search_path) { 1002 if (search_path) {
991 ssize_t len_search = strlen(search_path); 1003 ssize_t len_search = strlen(search_path);
992 ssize_t len_file = strlen(elf->filename); 1004 ssize_t len_file = strlen(elf->filename);
993 if (!strncmp(elf->filename, search_path, len_search) && \ 1005 if (!strncmp(elf->filename, search_path, len_search) && \
997 } 1009 }
998 xstrcat(&out_buffer, tmp, &out_len); 1010 xstrcat(&out_buffer, tmp, &out_len);
999 break; 1011 break;
1000 case 'f': 1012 case 'f':
1001 found_file = 1; 1013 found_file = 1;
1002 if (be_very_quiet) break; 1014 if (be_wewy_wewy_quiet) break;
1003 tmp = strrchr(elf->filename, '/'); 1015 tmp = strrchr(elf->filename, '/');
1004 tmp = (tmp == NULL ? elf->filename : tmp+1); 1016 tmp = (tmp == NULL ? elf->filename : tmp+1);
1005 xstrcat(&out_buffer, tmp, &out_len); 1017 xstrcat(&out_buffer, tmp, &out_len);
1006 break; 1018 break;
1007 case 'o': out = get_elfetype(elf); break; 1019 case 'o': out = get_elfetype(elf); break;
1321 } 1333 }
1322 1334
1323 free(path); 1335 free(path);
1324} 1336}
1325 1337
1326
1327/* usage / invocation handling functions */ 1338/* usage / invocation handling functions */
1328#define PARSE_FLAGS "plRmyAXxetrnLibSs:k:gN:TaqvF:f:o:M:E:BhV" 1339#define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:BhV"
1329#define a_argument required_argument 1340#define a_argument required_argument
1330static struct option const long_opts[] = { 1341static struct option const long_opts[] = {
1331 {"path", no_argument, NULL, 'p'}, 1342 {"path", no_argument, NULL, 'p'},
1332 {"ldpath", no_argument, NULL, 'l'}, 1343 {"ldpath", no_argument, NULL, 'l'},
1333 {"recursive", no_argument, NULL, 'R'}, 1344 {"recursive", no_argument, NULL, 'R'},
1334 {"mount", no_argument, NULL, 'm'}, 1345 {"mount", no_argument, NULL, 'm'},
1335 {"symlink", no_argument, NULL, 'y'}, 1346 {"symlink", no_argument, NULL, 'y'},
1336 {"archives", no_argument, NULL, 'A'}, 1347 {"archives", no_argument, NULL, 'A'},
1337 {"ldcache", no_argument, NULL, 'L'}, 1348 {"ldcache", no_argument, NULL, 'L'},
1338 {"fix", no_argument, NULL, 'X'}, 1349 {"fix", no_argument, NULL, 'X'},
1350 {"setpax", a_argument, NULL, 'z'},
1339 {"pax", no_argument, NULL, 'x'}, 1351 {"pax", no_argument, NULL, 'x'},
1340 {"header", no_argument, NULL, 'e'}, 1352 {"header", no_argument, NULL, 'e'},
1341 {"textrel", no_argument, NULL, 't'}, 1353 {"textrel", no_argument, NULL, 't'},
1342 {"rpath", no_argument, NULL, 'r'}, 1354 {"rpath", no_argument, NULL, 'r'},
1343 {"needed", no_argument, NULL, 'n'}, 1355 {"needed", no_argument, NULL, 'n'},
1369 "Scan directories recursively", 1381 "Scan directories recursively",
1370 "Don't recursively cross mount points", 1382 "Don't recursively cross mount points",
1371 "Don't scan symlinks", 1383 "Don't scan symlinks",
1372 "Scan archives (.a files)", 1384 "Scan archives (.a files)",
1373 "Utilize ld.so.cache information (use with -r/-n)", 1385 "Utilize ld.so.cache information (use with -r/-n)",
1374 "Try and 'fix' bad things (use with -r/-e)\n", 1386 "Try and 'fix' bad things (use with -r/-e)",
1387 "Sets EI_PAX/PT_PAX_FLAGS to <arg> (use with -Xx)\n",
1375 "Print PaX markings", 1388 "Print PaX markings",
1376 "Print GNU_STACK/PT_LOAD markings", 1389 "Print GNU_STACK/PT_LOAD markings",
1377 "Print TEXTREL information", 1390 "Print TEXTREL information",
1378 "Print RPATH information", 1391 "Print RPATH information",
1379 "Print NEEDED information", 1392 "Print NEEDED information",
1487 case 'F': { 1500 case 'F': {
1488 if (out_format) warn("You prob don't want to specify -F twice"); 1501 if (out_format) warn("You prob don't want to specify -F twice");
1489 out_format = optarg; 1502 out_format = optarg;
1490 break; 1503 break;
1491 } 1504 }
1505 case 'z': {
1506 unsigned long flags = 10240;
1507 size_t x;
1492 1508
1509#define do_state(option, flag) \
1510 if (islower(option)) { \
1511 flags &= ~PF_##flag; \
1512 flags |= PF_NO##flag; \
1513 } else { \
1514 flags &= ~PF_NO##flag; \
1515 flags |= PF_##flag; \
1516 }
1517
1518 for (x = 0 ; x < strlen(optarg); x++) {
1519 switch(optarg[x]) {
1520 case 'p':
1521 case 'P':
1522 do_state(optarg[x], PAGEEXEC);
1523 break;
1524 case 's':
1525 case 'S':
1526 do_state(optarg[x], SEGMEXEC);
1527 break;
1528 case 'm':
1529 case 'M':
1530 do_state(optarg[x], MPROTECT);
1531 break;
1532 case 'e':
1533 case 'E':
1534 do_state(optarg[x], EMUTRAMP);
1535 break;
1536 case 'r':
1537 case 'R':
1538 do_state(optarg[x], RANDMMAP);
1539 break;
1540 case 'x':
1541 case 'X':
1542 do_state(optarg[x], RANDEXEC);
1543 break;
1544 default:
1545 break;
1546 }
1547 }
1548 if (!(((flags & PF_PAGEEXEC) && (flags & PF_NOPAGEEXEC)) ||
1549 ((flags & PF_SEGMEXEC) && (flags & PF_NOSEGMEXEC)) ||
1550 ((flags & PF_RANDMMAP) && (flags & PF_NORANDMMAP)) ||
1551 ((flags & PF_RANDEXEC) && (flags & PF_NORANDEXEC)) ||
1552 ((flags & PF_EMUTRAMP) && (flags & PF_NOEMUTRAMP)) ||
1553 ((flags & PF_RANDMMAP) && (flags & PF_NORANDMMAP))))
1554 setpax = flags;
1555 break;
1556 }
1493 case 'g': gmatch = 1; break; 1557 case 'g': gmatch = 1; break;
1494 case 'L': use_ldcache = 1; break; 1558 case 'L': use_ldcache = 1; break;
1495 case 'y': scan_symlink = 0; break; 1559 case 'y': scan_symlink = 0; break;
1496 case 'A': scan_archives = 1; break; 1560 case 'A': scan_archives = 1; break;
1497 case 'B': show_banner = 0; break; 1561 case 'B': show_banner = 0; break;

Legend:
Removed from v.1.126  
changed lines
  Added in v.1.127

  ViewVC Help
Powered by ViewVC 1.1.20