/[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.163 Revision 1.164
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.163 2006/12/01 15:41:23 solar Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.164 2006/12/03 00:17:18 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.163 2006/12/01 15:41:23 solar Exp $"; 12static const char *rcsid = "$Id: scanelf.c,v 1.164 2006/12/03 00:17:18 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#define do_state(option, flag) \ 17#define do_state(option, flag) \
27/* prototypes */ 27/* prototypes */
28static int file_matches_list(const char *filename, char **matchlist); 28static int file_matches_list(const char *filename, char **matchlist);
29static int scanelf_elfobj(elfobj *elf); 29static int scanelf_elfobj(elfobj *elf);
30static int scanelf_elf(const char *filename, int fd, size_t len); 30static int scanelf_elf(const char *filename, int fd, size_t len);
31static int scanelf_archive(const char *filename, int fd, size_t len); 31static int scanelf_archive(const char *filename, int fd, size_t len);
32static void scanelf_file(const char *filename, const struct stat *st_cache); 32static int scanelf_file(const char *filename, const struct stat *st_cache);
33static void scanelf_dir(const char *path); 33static int scanelf_dir(const char *path);
34static void scanelf_ldpath(void); 34static void scanelf_ldpath(void);
35static void scanelf_envpath(void); 35static void scanelf_envpath(void);
36static void usage(int status); 36static void usage(int status);
37static char **get_split_env(const char *envvar); 37static char **get_split_env(const char *envvar);
38static void parseenv(void); 38static void parseenv(void);
39static void parseargs(int argc, char *argv[]); 39static int parseargs(int argc, char *argv[]);
40static char *xstrdup(const char *s); 40static char *xstrdup(const char *s);
41static void *xmalloc(size_t size); 41static void *xmalloc(size_t size);
42static void *xrealloc(void *ptr, size_t size); 42static void *xrealloc(void *ptr, size_t size);
43static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n); 43static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n);
44#define xstrcat(dst,src,curr_len) xstrncat(dst,src,curr_len,0) 44#define xstrcat(dst,src,curr_len) xstrncat(dst,src,curr_len,0)
1229 munmap(ar_buffer, len); 1229 munmap(ar_buffer, len);
1230 1230
1231 return 0; 1231 return 0;
1232} 1232}
1233/* scan a file which may be an elf or an archive or some other magical beast */ 1233/* scan a file which may be an elf or an archive or some other magical beast */
1234static void scanelf_file(const char *filename, const struct stat *st_cache) 1234static int scanelf_file(const char *filename, const struct stat *st_cache)
1235{ 1235{
1236 const struct stat *st = st_cache; 1236 const struct stat *st = st_cache;
1237 struct stat symlink_st; 1237 struct stat symlink_st;
1238 int fd; 1238 int fd;
1239 1239
1240 /* always handle regular files and handle symlinked files if no -y */ 1240 /* always handle regular files and handle symlinked files if no -y */
1241 if (S_ISLNK(st->st_mode)) { 1241 if (S_ISLNK(st->st_mode)) {
1242 if (!scan_symlink) return; 1242 if (!scan_symlink) return 1;
1243 stat(filename, &symlink_st); 1243 stat(filename, &symlink_st);
1244 st = &symlink_st; 1244 st = &symlink_st;
1245 } 1245 }
1246 1246
1247 if (!S_ISREG(st->st_mode)) { 1247 if (!S_ISREG(st->st_mode)) {
1248 if (be_verbose > 2) printf("%s: skipping non-file\n", filename); 1248 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
1249 return; 1249 return 1;
1250 } 1250 }
1251 1251
1252 if ((fd=open(filename, (fix_elf ? O_RDWR : O_RDONLY))) == -1) 1252 if ((fd=open(filename, (fix_elf ? O_RDWR : O_RDONLY))) == -1)
1253 return; 1253 return 1;
1254 1254
1255 if (scanelf_elf(filename, fd, st->st_size) == 1 && scan_archives) 1255 if (scanelf_elf(filename, fd, st->st_size) == 1 && scan_archives)
1256 /* if it isn't an ELF, maybe it's an .a archive */ 1256 /* if it isn't an ELF, maybe it's an .a archive */
1257 scanelf_archive(filename, fd, st->st_size); 1257 scanelf_archive(filename, fd, st->st_size);
1258 1258
1259 close(fd); 1259 close(fd);
1260 return 0;
1260} 1261}
1261 1262
1262/* scan a directory for ET_EXEC files and print when we find one */ 1263/* scan a directory for ET_EXEC files and print when we find one */
1263static void scanelf_dir(const char *path) 1264static int scanelf_dir(const char *path)
1264{ 1265{
1265 register DIR *dir; 1266 register DIR *dir;
1266 register struct dirent *dentry; 1267 register struct dirent *dentry;
1267 struct stat st_top, st; 1268 struct stat st_top, st;
1268 char buf[__PAX_UTILS_PATH_MAX]; 1269 char buf[__PAX_UTILS_PATH_MAX];
1269 size_t pathlen = 0, len = 0; 1270 size_t pathlen = 0, len = 0;
1271 int ret = 0;
1270 1272
1271 /* make sure path exists */ 1273 /* make sure path exists */
1272 if (lstat(path, &st_top) == -1) { 1274 if (lstat(path, &st_top) == -1) {
1273 if (be_verbose > 2) printf("%s: does not exist\n", path); 1275 if (be_verbose > 2) printf("%s: does not exist\n", path);
1274 return; 1276 return 1;
1275 } 1277 }
1276 1278
1277 /* ok, if it isn't a directory, assume we can open it */ 1279 /* ok, if it isn't a directory, assume we can open it */
1278 if (!S_ISDIR(st_top.st_mode)) { 1280 if (!S_ISDIR(st_top.st_mode)) {
1279 scanelf_file(path, &st_top); 1281 return scanelf_file(path, &st_top);
1280 return;
1281 } 1282 }
1282 1283
1283 /* now scan the dir looking for fun stuff */ 1284 /* now scan the dir looking for fun stuff */
1284 if ((dir = opendir(path)) == NULL) { 1285 if ((dir = opendir(path)) == NULL) {
1285 warnf("could not opendir %s: %s", path, strerror(errno)); 1286 warnf("could not opendir %s: %s", path, strerror(errno));
1286 return; 1287 return 1;
1287 } 1288 }
1288 if (be_verbose > 1) printf("%s: scanning dir\n", path); 1289 if (be_verbose > 1) printf("%s: scanning dir\n", path);
1289 1290
1290 pathlen = strlen(path); 1291 pathlen = strlen(path);
1291 while ((dentry = readdir(dir))) { 1292 while ((dentry = readdir(dir))) {
1298 continue; 1299 continue;
1299 } 1300 }
1300 snprintf(buf, sizeof(buf), "%s%s%s", path, (path[pathlen-1] == '/') ? "" : "/", dentry->d_name); 1301 snprintf(buf, sizeof(buf), "%s%s%s", path, (path[pathlen-1] == '/') ? "" : "/", dentry->d_name);
1301 if (lstat(buf, &st) != -1) { 1302 if (lstat(buf, &st) != -1) {
1302 if (S_ISREG(st.st_mode)) 1303 if (S_ISREG(st.st_mode))
1303 scanelf_file(buf, &st); 1304 ret = scanelf_file(buf, &st);
1304 else if (dir_recurse && S_ISDIR(st.st_mode)) { 1305 else if (dir_recurse && S_ISDIR(st.st_mode)) {
1305 if (dir_crossmount || (st_top.st_dev == st.st_dev)) 1306 if (dir_crossmount || (st_top.st_dev == st.st_dev))
1306 scanelf_dir(buf); 1307 ret = scanelf_dir(buf);
1307 } 1308 }
1308 } 1309 }
1309 } 1310 }
1310 closedir(dir); 1311 closedir(dir);
1312 return ret;
1311} 1313}
1312 1314
1313static int scanelf_from_file(const char *filename) 1315static int scanelf_from_file(const char *filename)
1314{ 1316{
1315 FILE *fp = NULL; 1317 FILE *fp = NULL;
1316 char *p; 1318 char *p;
1317 char path[__PAX_UTILS_PATH_MAX]; 1319 char path[__PAX_UTILS_PATH_MAX];
1320 int ret = 0;
1318 1321
1319 if (strcmp(filename, "-") == 0) 1322 if (strcmp(filename, "-") == 0)
1320 fp = stdin; 1323 fp = stdin;
1321 else if ((fp = fopen(filename, "r")) == NULL) 1324 else if ((fp = fopen(filename, "r")) == NULL)
1322 return 1; 1325 return 1;
1323 1326
1324 while ((fgets(path, __PAX_UTILS_PATH_MAX, fp)) != NULL) { 1327 while ((fgets(path, __PAX_UTILS_PATH_MAX, fp)) != NULL) {
1325 if ((p = strchr(path, '\n')) != NULL) 1328 if ((p = strchr(path, '\n')) != NULL)
1326 *p = 0; 1329 *p = 0;
1327 search_path = path; 1330 search_path = path;
1328 scanelf_dir(path); 1331 ret = scanelf_dir(path);
1329 } 1332 }
1330 if (fp != stdin) 1333 if (fp != stdin)
1331 fclose(fp); 1334 fclose(fp);
1332 return 0; 1335 return ret;
1333} 1336}
1334 1337
1335#if defined(__GLIBC__) || defined(__UCLIBC__) || defined(__NetBSD__) 1338#if defined(__GLIBC__) || defined(__UCLIBC__) || defined(__NetBSD__)
1336 1339
1337static int load_ld_cache_config(int i, const char *fname) 1340static int load_ld_cache_config(int i, const char *fname)
1600 1603
1601 exit(status); 1604 exit(status);
1602} 1605}
1603 1606
1604/* parse command line arguments and preform needed actions */ 1607/* parse command line arguments and preform needed actions */
1605static void parseargs(int argc, char *argv[]) 1608static int parseargs(int argc, char *argv[])
1606{ 1609{
1607 int i; 1610 int i;
1608 const char *from_file = NULL; 1611 const char *from_file = NULL;
1612 int ret = 0;
1609 1613
1610 opterr = 0; 1614 opterr = 0;
1611 while ((i=getopt_long(argc, argv, PARSE_FLAGS, long_opts, NULL)) != -1) { 1615 while ((i=getopt_long(argc, argv, PARSE_FLAGS, long_opts, NULL)) != -1) {
1612 switch (i) { 1616 switch (i) {
1613 1617
1798 } 1802 }
1799 if (optind == argc && !scan_ldpath && !scan_envpath && !from_file) 1803 if (optind == argc && !scan_ldpath && !scan_envpath && !from_file)
1800 err("Nothing to scan !?"); 1804 err("Nothing to scan !?");
1801 while (optind < argc) { 1805 while (optind < argc) {
1802 search_path = argv[optind++]; 1806 search_path = argv[optind++];
1803 scanelf_dir(search_path); 1807 ret = scanelf_dir(search_path);
1804 } 1808 }
1805 1809
1806 /* clean up */ 1810 /* clean up */
1807 free(versioned_symname); 1811 free(versioned_symname);
1808 for (i = 0; ldpaths[i]; ++i) 1812 for (i = 0; ldpaths[i]; ++i)
1809 free(ldpaths[i]); 1813 free(ldpaths[i]);
1810 1814
1811 if (ldcache != 0) 1815 if (ldcache != 0)
1812 munmap(ldcache, ldcache_size); 1816 munmap(ldcache, ldcache_size);
1817 return ret;
1813} 1818}
1814 1819
1815static char **get_split_env(const char *envvar) 1820static char **get_split_env(const char *envvar)
1816{ 1821{
1817 const char *delims = " \t\n"; 1822 const char *delims = " \t\n";
1863#endif 1868#endif
1864 1869
1865 1870
1866int main(int argc, char *argv[]) 1871int main(int argc, char *argv[])
1867{ 1872{
1873 int ret;
1868 if (argc < 2) 1874 if (argc < 2)
1869 usage(EXIT_FAILURE); 1875 usage(EXIT_FAILURE);
1870 parseenv(); 1876 parseenv();
1871 parseargs(argc, argv); 1877 ret = parseargs(argc, argv);
1872 fclose(stdout); 1878 fclose(stdout);
1873#ifdef __PAX_UTILS_CLEANUP 1879#ifdef __PAX_UTILS_CLEANUP
1874 cleanup(); 1880 cleanup();
1875 warn("The calls to add/delete heap should be off:\n" 1881 warn("The calls to add/delete heap should be off:\n"
1876 "\t- 1 due to the out_buffer not being freed in scanelf_file()\n" 1882 "\t- 1 due to the out_buffer not being freed in scanelf_file()\n"
1877 "\t- 1 per QA_TEXTRELS/QA_EXECSTACK/QA_WX_LOAD"); 1883 "\t- 1 per QA_TEXTRELS/QA_EXECSTACK/QA_WX_LOAD");
1878#endif 1884#endif
1879 return EXIT_SUCCESS; 1885 return ret;
1880} 1886}
1881 1887
1882 1888
1883 1889
1884/* utility funcs */ 1890/* utility funcs */

Legend:
Removed from v.1.163  
changed lines
  Added in v.1.164

  ViewVC Help
Powered by ViewVC 1.1.20