/[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.151 Revision 1.152
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.151 2006/05/14 23:17:31 kevquinn Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.152 2006/05/14 23:49:56 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.151 2006/05/14 23:17:31 kevquinn Exp $"; 12static const char *rcsid = "$Id: scanelf.c,v 1.152 2006/05/14 23:49:56 vapier 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) \
140 if (matchlist == NULL) 140 if (matchlist == NULL)
141 return 0; 141 return 0;
142 142
143 for (file = matchlist; *file != NULL; file++) { 143 for (file = matchlist; *file != NULL; file++) {
144 if (search_path) { 144 if (search_path) {
145 snprintf(buf,__PAX_UTILS_PATH_MAX, "%s%s", search_path, *file); 145 snprintf(buf, sizeof(buf), "%s%s", search_path, *file);
146 match = buf; 146 match = buf;
147 } else { 147 } else {
148 match = *file; 148 match = *file;
149 } 149 }
150 if (fnmatch(match, filename, 0) == 0) 150 if (fnmatch(match, filename, 0) == 0)
151 return 1; /* TRUE */ 151 return 1;
152 } 152 }
153 return 0; /* FALSE */ 153 return 0;
154} 154}
155
156
155 157
156/* sub-funcs for scanelf_file() */ 158/* sub-funcs for scanelf_file() */
157static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) 159static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab)
158{ 160{
159 /* find the best SHT_DYNSYM and SHT_STRTAB sections */ 161 /* find the best SHT_DYNSYM and SHT_STRTAB sections */
267 uint32_t flags, check_flags; \ 269 uint32_t flags, check_flags; \
268 if (elf->phdr != NULL) { \ 270 if (elf->phdr != NULL) { \
269 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 271 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
270 for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \ 272 for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \
271 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ 273 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \
274 if (multi_stack++) \
272 if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \ 275 warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \
273 if (!file_matches_list(elf->filename, qa_execstack)) {\ 276 if (file_matches_list(elf->filename, qa_execstack)) \
277 continue; \
274 found = found_phdr; \ 278 found = found_phdr; \
275 offset = 0; \ 279 offset = 0; \
276 check_flags = PF_X; \ 280 check_flags = PF_X; \
277 } else continue; \
278 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \ 281 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \
282 if (multi_relro++) \
279 if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \ 283 warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \
280 found = found_relro; \ 284 found = found_relro; \
281 offset = 4; \ 285 offset = 4; \
282 check_flags = PF_X; \ 286 check_flags = PF_X; \
283 } else if (EGET(phdr[i].p_type) == PT_LOAD) { \ 287 } else if (EGET(phdr[i].p_type) == PT_LOAD) { \
284 if (ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC) \ 288 if (ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC) \
289 if (multi_load++ > max_pt_load) \
285 if (multi_load++ > max_pt_load) warnf("%s: more than %i PT_LOAD's !?", elf->filename, max_pt_load); \ 290 warnf("%s: more than %i PT_LOAD's !?", elf->filename, max_pt_load); \
286 if (!file_matches_list(elf->filename, qa_wx_load)) {\ 291 if (file_matches_list(elf->filename, qa_wx_load)) \
292 continue; \
287 found = found_load; \ 293 found = found_load; \
288 offset = 8; \ 294 offset = 8; \
289 check_flags = PF_W|PF_X; \ 295 check_flags = PF_W|PF_X; \
290 } else continue; \
291 } else \ 296 } else \
292 continue; \ 297 continue; \
293 flags = EGET(phdr[i].p_flags); \ 298 flags = EGET(phdr[i].p_flags); \
294 if (be_quiet && ((flags & check_flags) != check_flags)) \ 299 if (be_quiet && ((flags & check_flags) != check_flags)) \
295 continue; \ 300 continue; \
1435static int load_ld_cache_config(int i, const char *fname) 1440static int load_ld_cache_config(int i, const char *fname)
1436{ 1441{
1437 FILE *fp = NULL; 1442 FILE *fp = NULL;
1438 char *b = NULL, *p; 1443 char *b = NULL, *p;
1439 struct elfhints_hdr hdr; 1444 struct elfhints_hdr hdr;
1440 1445
1441 if (i + 1 == ARRAY_SIZE(ldpaths)) 1446 if (i + 1 == ARRAY_SIZE(ldpaths))
1442 return i; 1447 return i;
1443 1448
1444 if ((fp = fopen(fname, "r")) == NULL) 1449 if ((fp = fopen(fname, "r")) == NULL)
1445 return i; 1450 return i;
1446 1451
1447 if ( fread(&hdr, 1, sizeof(hdr), fp) != sizeof(hdr) || 1452 if (fread(&hdr, 1, sizeof(hdr), fp) != sizeof(hdr) ||
1448 hdr.magic != ELFHINTS_MAGIC || hdr.version != 1 || 1453 hdr.magic != ELFHINTS_MAGIC || hdr.version != 1 ||
1449 fseek(fp, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 1454 fseek(fp, hdr.strtab + hdr.dirlist, SEEK_SET) == -1)
1450 ) { 1455 {
1451 fclose(fp); 1456 fclose(fp);
1452 return i; 1457 return i;
1453 } 1458 }
1454 1459
1455 b = (char*)malloc(hdr.dirlistlen+1); 1460 b = (char*)malloc(hdr.dirlistlen+1);
1456 if ( fread(b, 1, hdr.dirlistlen+1, fp) != hdr.dirlistlen+1 ) { 1461 if (fread(b, 1, hdr.dirlistlen+1, fp) != hdr.dirlistlen+1) {
1457 fclose(fp); 1462 fclose(fp);
1458 free(b); 1463 free(b);
1459 return i; 1464 return i;
1460 } 1465 }
1461 1466
1462 while ( (p = strsep(&b, ":")) ) { 1467 while ((p = strsep(&b, ":"))) {
1463 if ( *p == '\0' ) continue; 1468 if (*p == '\0') continue;
1464 ldpaths[i++] = xstrdup(p); 1469 ldpaths[i++] = xstrdup(p);
1465 1470
1466 if (i + 1 == ARRAY_SIZE(ldpaths)) 1471 if (i + 1 == ARRAY_SIZE(ldpaths))
1467 break; 1472 break;
1468 } 1473 }
1469 ldpaths[i] = NULL; 1474 ldpaths[i] = NULL;
1470 1475
1837 search_path = argv[optind++]; 1842 search_path = argv[optind++];
1838 scanelf_dir(search_path); 1843 scanelf_dir(search_path);
1839 } 1844 }
1840 1845
1841 /* clean up */ 1846 /* clean up */
1842 if (versioned_symname) free(versioned_symname); 1847 free(versioned_symname);
1843 for (i = 0; ldpaths[i]; ++i) 1848 for (i = 0; ldpaths[i]; ++i)
1844 free(ldpaths[i]); 1849 free(ldpaths[i]);
1845 1850
1846 if (ldcache != 0) 1851 if (ldcache != 0)
1847 munmap(ldcache, ldcache_size); 1852 munmap(ldcache, ldcache_size);
1848} 1853}
1849 1854
1850static char **get_split_env(const char *envvar) 1855static char **get_split_env(const char *envvar)
1851{ 1856{
1857 const char *delims = " \t\n";
1852 char **envvals = NULL; 1858 char **envvals = NULL;
1853 char *saveptr = NULL;
1854 char *env; 1859 char *env, *s;
1855 char *s;
1856 int nentry; 1860 int nentry;
1857 1861
1858 if ((env = getenv(envvar)) == NULL) 1862 if ((env = getenv(envvar)) == NULL)
1859 return NULL; 1863 return NULL;
1860 1864
1861 env = xstrdup(env); 1865 env = xstrdup(env);
1862 if (env == NULL) 1866 if (env == NULL)
1863 return NULL; 1867 return NULL;
1864 1868
1869 s = strtok(env, delims);
1870 if (s == NULL) {
1871 free(env);
1872 return NULL;
1873 }
1874
1865 nentry = 0; 1875 nentry = 0;
1866 for (s = strtok_r(env, " \t\n", &saveptr); s != NULL; s = strtok_r(NULL, " \t\n", &saveptr)) { 1876 while (s != NULL) {
1877 ++nentry;
1867 if ((envvals = xrealloc(envvals, sizeof(char *)*(nentry+1))) == NULL) 1878 envvals = xrealloc(envvals, sizeof(*envvals) * (nentry+1));
1868 return NULL;
1869 envvals[nentry++] = s; 1879 envvals[nentry-1] = s;
1880 s = strtok(NULL, delims);
1870 } 1881 }
1871 if (nentry > 0) envvals[nentry] = NULL; 1882 envvals[nentry] = NULL;
1872 1883
1884 /* don't want to free(env) as it contains the memory that backs
1885 * the envvals array of strings */
1873 return envvals; 1886 return envvals;
1874} 1887}
1875
1876static void parseenv() 1888static void parseenv()
1877{ 1889{
1878 qa_textrels = get_split_env("QA_TEXTRELS"); 1890 qa_textrels = get_split_env("QA_TEXTRELS");
1879 qa_execstack = get_split_env("QA_EXECSTACK"); 1891 qa_execstack = get_split_env("QA_EXECSTACK");
1880 qa_wx_load = get_split_env("QA_WX_LOAD"); 1892 qa_wx_load = get_split_env("QA_WX_LOAD");
1881} 1893}
1894#ifdef __PAX_UTILS_CLEANUP
1895static void cleanup()
1896{
1897 free(out_format);
1898 free(qa_textrels);
1899 free(qa_execstack);
1900 free(qa_wx_load);
1901}
1902#endif
1882 1903
1883 1904
1884 1905
1885int main(int argc, char *argv[]) 1906int main(int argc, char *argv[])
1886{ 1907{
1887 if (argc < 2) 1908 if (argc < 2)
1888 usage(EXIT_FAILURE); 1909 usage(EXIT_FAILURE);
1889 parseenv(); 1910 parseenv();
1890 parseargs(argc, argv); 1911 parseargs(argc, argv);
1891 fclose(stdout); 1912 fclose(stdout);
1892#ifdef __BOUNDS_CHECKING_ON 1913#ifdef __PAX_UTILS_CLEANUP
1893 warn("The calls to add/delete heap should be off by 1 due to the out_buffer not being freed in scanelf_file()"); 1914 cleanup();
1915 warn("The calls to add/delete heap should be off:\n"
1916 "\t- 1 due to the out_buffer not being freed in scanelf_file()\n"
1917 "\t- 1 per QA_TEXTRELS/QA_EXECSTACK/QA_WX_LOAD");
1894#endif 1918#endif
1895 return EXIT_SUCCESS; 1919 return EXIT_SUCCESS;
1896} 1920}

Legend:
Removed from v.1.151  
changed lines
  Added in v.1.152

  ViewVC Help
Powered by ViewVC 1.1.20