/[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.104 Revision 1.105
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.104 2006/01/13 11:31:55 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.105 2006/01/13 12:12:52 vapier 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.104 2006/01/13 11:31:55 vapier Exp $"; 12static const char *rcsid = "$Id: scanelf.c,v 1.105 2006/01/13 12:12:52 vapier 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
18 18
19/* prototypes */ 19/* prototypes */
20static int scanelf_elf(const char *filename);
21static int scanelf_archive(const char *filename);
20static void scanelf_file(const char *filename); 22static void scanelf_file(const char *filename);
21static void scanelf_dir(const char *path); 23static void scanelf_dir(const char *path);
22static void scanelf_ldpath(); 24static void scanelf_ldpath();
23static void scanelf_envpath(); 25static void scanelf_envpath();
24static void usage(int status); 26static void usage(int status);
32/* variables to control behavior */ 34/* variables to control behavior */
33static char *ldpaths[256]; 35static char *ldpaths[256];
34static char scan_ldpath = 0; 36static char scan_ldpath = 0;
35static char scan_envpath = 0; 37static char scan_envpath = 0;
36static char scan_symlink = 1; 38static char scan_symlink = 1;
39static char scan_archives = 0;
37static char dir_recurse = 0; 40static char dir_recurse = 0;
38static char dir_crossmount = 1; 41static char dir_crossmount = 1;
39static char show_pax = 0; 42static char show_pax = 0;
40static char show_phdr = 0; 43static char show_phdr = 0;
41static char show_textrel = 0; 44static char show_textrel = 0;
845 else 848 else
846 return (char *)" - "; 849 return (char *)" - ";
847} 850}
848/* scan an elf file and show all the fun stuff */ 851/* scan an elf file and show all the fun stuff */
849#define prints(str) write(fileno(stdout), str, strlen(str)) 852#define prints(str) write(fileno(stdout), str, strlen(str))
850static void scanelf_file(const char *filename) 853static int scanelf_elf(const char *filename)
851{ 854{
852 unsigned long i; 855 unsigned long i;
853 char found_pax, found_phdr, found_relro, found_load, found_textrel, 856 char found_pax, found_phdr, found_relro, found_load, found_textrel,
854 found_rpath, found_needed, found_interp, found_bind, found_soname, 857 found_rpath, found_needed, found_interp, found_bind, found_soname,
855 found_sym, found_lib, found_file, found_textrels; 858 found_sym, found_lib, found_file, found_textrels;
856 elfobj *elf; 859 elfobj *elf;
857 struct stat st;
858 static char *out_buffer = NULL; 860 static char *out_buffer = NULL;
859 static size_t out_len; 861 static size_t out_len;
860
861 /* make sure 'filename' exists */
862 if (lstat(filename, &st) == -1) {
863 if (be_verbose > 2) printf("%s: does not exist\n", filename);
864 return;
865 }
866 /* always handle regular files and handle symlinked files if no -y */
867 if (S_ISLNK(st.st_mode)) {
868 if (!scan_symlink) return;
869 stat(filename, &st);
870 }
871 if (!S_ISREG(st.st_mode)) {
872 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
873 return;
874 }
875 862
876 found_pax = found_phdr = found_relro = found_load = found_textrel = \ 863 found_pax = found_phdr = found_relro = found_load = found_textrel = \
877 found_rpath = found_needed = found_interp = found_bind = found_soname = \ 864 found_rpath = found_needed = found_interp = found_bind = found_soname = \
878 found_sym = found_lib = found_file = found_textrels = 0; 865 found_sym = found_lib = found_file = found_textrels = 0;
879 866
880 /* verify this is real ELF */ 867 /* verify this is real ELF */
881 if ((elf = _readelf(filename, !fix_elf)) == NULL) { 868 if ((elf = _readelf(filename, !fix_elf)) == NULL) {
882 /* if it isn't an ELF, maybe it's an .a archive */
883 archive_handle *ar = ar_open(filename);
884 if (be_verbose > 2) printf("%s: not an ELF\n", filename); 869 if (be_verbose > 2) printf("%s: not an ELF\n", filename);
885 return; 870 return 1;
886 } 871 }
887 872
888 if (be_verbose > 1) 873 if (be_verbose > 1)
889 printf("%s: scanning file {%s,%s}\n", filename, 874 printf("%s: scanning file {%s,%s}\n", filename,
890 get_elfeitype(EI_CLASS, elf->elf_class), 875 get_elfeitype(EI_CLASS, elf->elf_class),
1013 puts(out_buffer); 998 puts(out_buffer);
1014 fflush(stdout); 999 fflush(stdout);
1015 } 1000 }
1016 1001
1017 unreadelf(elf); 1002 unreadelf(elf);
1003
1004 return 0;
1005}
1006
1007/* scan an archive of elfs */
1008static int scanelf_archive(const char *filename)
1009{
1010 archive_handle *ar = ar_open(filename);
1011 archive_member *m;
1012 while ((m=ar_next(ar)) != NULL)
1013 printf("%o %i:%i %s\n", m->mode, m->uid, m->gid, m->name);
1014 return 0;
1015}
1016
1017/* scan a file which may be an elf or an archive or some other magical beast */
1018static void scanelf_file(const char *filename)
1019{
1020 struct stat st;
1021
1022 /* make sure 'filename' exists */
1023 if (lstat(filename, &st) == -1) {
1024 if (be_verbose > 2) printf("%s: does not exist\n", filename);
1025 return;
1026 }
1027
1028 /* always handle regular files and handle symlinked files if no -y */
1029 if (S_ISLNK(st.st_mode)) {
1030 if (!scan_symlink) return;
1031 stat(filename, &st);
1032 }
1033 if (!S_ISREG(st.st_mode)) {
1034 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
1035 return;
1036 }
1037
1038 if (scanelf_elf(filename) == 1 && scan_archives)
1039 /* if it isn't an ELF, maybe it's an .a archive */
1040 scanelf_archive(filename);
1018} 1041}
1019 1042
1020/* scan a directory for ET_EXEC files and print when we find one */ 1043/* scan a directory for ET_EXEC files and print when we find one */
1021static void scanelf_dir(const char *path) 1044static void scanelf_dir(const char *path)
1022{ 1045{
1161 free(path); 1184 free(path);
1162} 1185}
1163 1186
1164 1187
1165/* usage / invocation handling functions */ 1188/* usage / invocation handling functions */
1166#define PARSE_FLAGS "plRmyXxetrnLibSs:gN:TaqvF:f:o:BhV" 1189#define PARSE_FLAGS "plRmyAXxetrnLibSs:gN:TaqvF:f:o:BhV"
1167#define a_argument required_argument 1190#define a_argument required_argument
1168static struct option const long_opts[] = { 1191static struct option const long_opts[] = {
1169 {"path", no_argument, NULL, 'p'}, 1192 {"path", no_argument, NULL, 'p'},
1170 {"ldpath", no_argument, NULL, 'l'}, 1193 {"ldpath", no_argument, NULL, 'l'},
1171 {"recursive", no_argument, NULL, 'R'}, 1194 {"recursive", no_argument, NULL, 'R'},
1172 {"mount", no_argument, NULL, 'm'}, 1195 {"mount", no_argument, NULL, 'm'},
1173 {"symlink", no_argument, NULL, 'y'}, 1196 {"symlink", no_argument, NULL, 'y'},
1197 {"archives", no_argument, NULL, 'A'},
1198 {"ldcache", no_argument, NULL, 'L'},
1174 {"fix", no_argument, NULL, 'X'}, 1199 {"fix", no_argument, NULL, 'X'},
1175 {"pax", no_argument, NULL, 'x'}, 1200 {"pax", no_argument, NULL, 'x'},
1176 {"header", no_argument, NULL, 'e'}, 1201 {"header", no_argument, NULL, 'e'},
1177 {"textrel", no_argument, NULL, 't'}, 1202 {"textrel", no_argument, NULL, 't'},
1178 {"rpath", no_argument, NULL, 'r'}, 1203 {"rpath", no_argument, NULL, 'r'},
1179 {"needed", no_argument, NULL, 'n'}, 1204 {"needed", no_argument, NULL, 'n'},
1180 {"ldcache", no_argument, NULL, 'L'},
1181 {"interp", no_argument, NULL, 'i'}, 1205 {"interp", no_argument, NULL, 'i'},
1182 {"bind", no_argument, NULL, 'b'}, 1206 {"bind", no_argument, NULL, 'b'},
1183 {"soname", no_argument, NULL, 'S'}, 1207 {"soname", no_argument, NULL, 'S'},
1184 {"symbol", a_argument, NULL, 's'}, 1208 {"symbol", a_argument, NULL, 's'},
1185 {"lib", a_argument, NULL, 'N'}, 1209 {"lib", a_argument, NULL, 'N'},
1201 "Scan all directories in PATH environment", 1225 "Scan all directories in PATH environment",
1202 "Scan all directories in /etc/ld.so.conf", 1226 "Scan all directories in /etc/ld.so.conf",
1203 "Scan directories recursively", 1227 "Scan directories recursively",
1204 "Don't recursively cross mount points", 1228 "Don't recursively cross mount points",
1205 "Don't scan symlinks", 1229 "Don't scan symlinks",
1230 "Scan archives (.a files)",
1231 "Utilize ld.so.cache information (use with -r/-n)",
1206 "Try and 'fix' bad things (use with -r/-e)\n", 1232 "Try and 'fix' bad things (use with -r/-e)\n",
1207 "Print PaX markings", 1233 "Print PaX markings",
1208 "Print GNU_STACK/PT_LOAD markings", 1234 "Print GNU_STACK/PT_LOAD markings",
1209 "Print TEXTREL information", 1235 "Print TEXTREL information",
1210 "Print RPATH information", 1236 "Print RPATH information",
1211 "Print NEEDED information", 1237 "Print NEEDED information",
1212 "Utilize ld.so.cache information (use with -r/-n)",
1213 "Print INTERP information", 1238 "Print INTERP information",
1214 "Print BIND information", 1239 "Print BIND information",
1215 "Print SONAME information", 1240 "Print SONAME information",
1216 "Find a specified symbol", 1241 "Find a specified symbol",
1217 "Find a specified library", 1242 "Find a specified library",
1232/* display usage and exit */ 1257/* display usage and exit */
1233static void usage(int status) 1258static void usage(int status)
1234{ 1259{
1235 unsigned long i; 1260 unsigned long i;
1236 printf("* Scan ELF binaries for stuff\n\n" 1261 printf("* Scan ELF binaries for stuff\n\n"
1237 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0); 1262 "Usage: %s [options] <dir1/file1> [dir2 dirN file2 fileN ...]\n\n", argv0);
1238 printf("Options: -[%s]\n", PARSE_FLAGS); 1263 printf("Options: -[%s]\n", PARSE_FLAGS);
1239 for (i = 0; long_opts[i].name; ++i) 1264 for (i = 0; long_opts[i].name; ++i)
1240 if (long_opts[i].has_arg == no_argument) 1265 if (long_opts[i].has_arg == no_argument)
1241 printf(" -%c, --%-13s* %s\n", long_opts[i].val, 1266 printf(" -%c, --%-13s* %s\n", long_opts[i].val,
1242 long_opts[i].name, opts_help[i]); 1267 long_opts[i].name, opts_help[i]);
1309 } 1334 }
1310 1335
1311 case 'g': gmatch = 1; /* break; any reason we dont breal; here ? */ 1336 case 'g': gmatch = 1; /* break; any reason we dont breal; here ? */
1312 case 'L': use_ldcache = 1; break; 1337 case 'L': use_ldcache = 1; break;
1313 case 'y': scan_symlink = 0; break; 1338 case 'y': scan_symlink = 0; break;
1339 case 'A': scan_archives = 1; break;
1314 case 'B': show_banner = 0; break; 1340 case 'B': show_banner = 0; break;
1315 case 'l': scan_ldpath = 1; break; 1341 case 'l': scan_ldpath = 1; break;
1316 case 'p': scan_envpath = 1; break; 1342 case 'p': scan_envpath = 1; break;
1317 case 'R': dir_recurse = 1; break; 1343 case 'R': dir_recurse = 1; break;
1318 case 'm': dir_crossmount = 0; break; 1344 case 'm': dir_crossmount = 0; break;

Legend:
Removed from v.1.104  
changed lines
  Added in v.1.105

  ViewVC Help
Powered by ViewVC 1.1.20