/[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.141 Revision 1.142
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.141 2006/04/23 15:24:38 flameeyes Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.142 2006/05/10 22:45:08 kevquinn 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
13#endif 13#endif
14#if defined(__FreeBSD__) || defined(__DragonFly__) 14#if defined(__FreeBSD__) || defined(__DragonFly__)
15 #include <elf-hints.h> 15 #include <elf-hints.h>
16#endif 16#endif
17 17
18static const char *rcsid = "$Id: scanelf.c,v 1.141 2006/04/23 15:24:38 flameeyes Exp $"; 18static const char *rcsid = "$Id: scanelf.c,v 1.142 2006/05/10 22:45:08 kevquinn Exp $";
19#define argv0 "scanelf" 19#define argv0 "scanelf"
20 20
21#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+') 21#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+')
22 22
23#define do_state(option, flag) \ 23#define do_state(option, flag) \
29 flags |= PF_##flag; \ 29 flags |= PF_##flag; \
30 } 30 }
31 31
32 32
33/* prototypes */ 33/* prototypes */
34static int file_matches_list(const char *filename, char **matchlist);
34static int scanelf_elfobj(elfobj *elf); 35static int scanelf_elfobj(elfobj *elf);
35static int scanelf_elf(const char *filename, int fd, size_t len); 36static int scanelf_elf(const char *filename, int fd, size_t len);
36static int scanelf_archive(const char *filename, int fd, size_t len); 37static int scanelf_archive(const char *filename, int fd, size_t len);
37static void scanelf_file(const char *filename); 38static void scanelf_file(const char *filename);
38static void scanelf_dir(const char *path); 39static void scanelf_dir(const char *path);
39static void scanelf_ldpath(void); 40static void scanelf_ldpath(void);
40static void scanelf_envpath(void); 41static void scanelf_envpath(void);
41static void usage(int status); 42static void usage(int status);
43static char **get_split_env(const char *envvar);
44static void parseenv(void);
42static void parseargs(int argc, char *argv[]); 45static void parseargs(int argc, char *argv[]);
43static char *xstrdup(const char *s); 46static char *xstrdup(const char *s);
44static void *xmalloc(size_t size); 47static void *xmalloc(size_t size);
48static void *xrealloc(void *ptr, size_t size);
45static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n); 49static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n);
46#define xstrcat(dst,src,curr_len) xstrncat(dst,src,curr_len,0) 50#define xstrcat(dst,src,curr_len) xstrncat(dst,src,curr_len,0)
47static inline void xchrcat(char **dst, const char append, size_t *curr_len); 51static inline void xchrcat(char **dst, const char append, size_t *curr_len);
48 52
49/* variables to control behavior */ 53/* variables to control behavior */
76static char *search_path = NULL; 80static char *search_path = NULL;
77static char fix_elf = 0; 81static char fix_elf = 0;
78static char gmatch = 0; 82static char gmatch = 0;
79static char use_ldcache = 0; 83static char use_ldcache = 0;
80 84
85static char **qa_textrels = NULL;
86static char **qa_execstack = NULL;
87
81int match_bits = 0; 88int match_bits = 0;
82caddr_t ldcache = 0; 89caddr_t ldcache = 0;
83size_t ldcache_size = 0; 90size_t ldcache_size = 0;
84unsigned long setpax = 0UL; 91unsigned long setpax = 0UL;
92
93/* utility funcs */
94static char *xstrdup(const char *s)
95{
96 char *ret = strdup(s);
97 if (!ret) err("Could not strdup(): %s", strerror(errno));
98 return ret;
99}
100static void *xmalloc(size_t size)
101{
102 void *ret = malloc(size);
103 if (!ret) err("Could not malloc() %li bytes", (unsigned long)size);
104 return ret;
105}
106static void *xrealloc(void *ptr, size_t size)
107{
108 void *ret = realloc(ptr, size);
109 if (!ret) err("Could not realloc() %li bytes", (unsigned long)size);
110 return ret;
111}
112static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n)
113{
114 size_t new_len;
115
116 new_len = strlen(*dst) + strlen(src);
117 if (*curr_len <= new_len) {
118 *curr_len = new_len + (*curr_len / 2);
119 *dst = realloc(*dst, *curr_len);
120 if (!*dst)
121 err("could not realloc() %li bytes", (unsigned long)*curr_len);
122 }
123
124 if (n)
125 strncat(*dst, src, n);
126 else
127 strcat(*dst, src);
128}
129static inline void xchrcat(char **dst, const char append, size_t *curr_len)
130{
131 static char my_app[2];
132 my_app[0] = append;
133 my_app[1] = '\0';
134 xstrcat(dst, my_app, curr_len);
135}
136
137/* Match filename against entries in matchlist, return TRUE
138 * if the file is listed */
139static int file_matches_list(const char *filename, char **matchlist) {
140 char **file;
141 char *match;
142 char buf[__PAX_UTILS_PATH_MAX];
143 if (matchlist!=NULL) {
144 for (file=matchlist;
145 *file!=NULL;
146 file++) {
147 if (search_path) {
148 snprintf(buf,__PAX_UTILS_PATH_MAX,"%s%s",search_path,*file);
149 match=buf;
150 } else {
151 match=*file;
152 }
153 if (fnmatch(match, filename, 0) == 0)
154 return 1; /* TRUE */
155 }
156 }
157 return 0; /* FALSE */
158}
85 159
86/* sub-funcs for scanelf_file() */ 160/* sub-funcs for scanelf_file() */
87static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) 161static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab)
88{ 162{
89 /* find the best SHT_DYNSYM and SHT_STRTAB sections */ 163 /* find the best SHT_DYNSYM and SHT_STRTAB sections */
198 if (elf->phdr != NULL) { \ 272 if (elf->phdr != NULL) { \
199 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 273 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
200 for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \ 274 for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \
201 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ 275 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \
202 if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \ 276 if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \
277 if (!file_matches_list(elf->filename, qa_execstack)) {\
203 found = found_phdr; \ 278 found = found_phdr; \
204 offset = 0; \ 279 offset = 0; \
205 check_flags = PF_X; \ 280 check_flags = PF_X; \
281 } else continue; \
206 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \ 282 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \
207 if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \ 283 if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \
208 found = found_relro; \ 284 found = found_relro; \
209 offset = 4; \ 285 offset = 4; \
210 check_flags = PF_X; \ 286 check_flags = PF_X; \
269 if (be_wewy_wewy_quiet || (be_quiet && !shown)) 345 if (be_wewy_wewy_quiet || (be_quiet && !shown))
270 return NULL; 346 return NULL;
271 else 347 else
272 return ret; 348 return ret;
273} 349}
350
274static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel) 351static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel)
275{ 352{
276 static const char *ret = "TEXTREL"; 353 static const char *ret = "TEXTREL";
277 unsigned long i; 354 unsigned long i;
278 355
279 if (!show_textrel && !show_textrels) return NULL; 356 if (!show_textrel && !show_textrels) return NULL;
357
358 if (file_matches_list(elf->filename, qa_textrels)) return NULL;
280 359
281 if (elf->phdr) { 360 if (elf->phdr) {
282#define SHOW_TEXTREL(B) \ 361#define SHOW_TEXTREL(B) \
283 if (elf->elf_class == ELFCLASS ## B) { \ 362 if (elf->elf_class == ELFCLASS ## B) { \
284 Elf ## B ## _Dyn *dyn; \ 363 Elf ## B ## _Dyn *dyn; \
1251 if (len >= sizeof(buf)) { 1330 if (len >= sizeof(buf)) {
1252 warnf("Skipping '%s': len > sizeof(buf); %lu > %lu\n", path, 1331 warnf("Skipping '%s': len > sizeof(buf); %lu > %lu\n", path,
1253 (unsigned long)len, (unsigned long)sizeof(buf)); 1332 (unsigned long)len, (unsigned long)sizeof(buf));
1254 continue; 1333 continue;
1255 } 1334 }
1256 sprintf(buf, "%s/%s", path, dentry->d_name); 1335 sprintf(buf, "%s%s%s", path, path[pathlen-1]=='/'?"":"/", dentry->d_name);
1257 if (lstat(buf, &st) != -1) { 1336 if (lstat(buf, &st) != -1) {
1258 if (S_ISREG(st.st_mode)) 1337 if (S_ISREG(st.st_mode))
1259 scanelf_file(buf); 1338 scanelf_file(buf);
1260 else if (dir_recurse && S_ISDIR(st.st_mode)) { 1339 else if (dir_recurse && S_ISDIR(st.st_mode)) {
1261 if (dir_crossmount || (st_top.st_dev == st.st_dev)) 1340 if (dir_crossmount || (st_top.st_dev == st.st_dev))
1761 1840
1762 if (ldcache != 0) 1841 if (ldcache != 0)
1763 munmap(ldcache, ldcache_size); 1842 munmap(ldcache, ldcache_size);
1764} 1843}
1765 1844
1845static char **get_split_env(const char *envvar) {
1846 char **envvals=NULL;
1847 char *saveptr=NULL;
1848 char *env;
1849 char *s;
1850 int nentry;
1766 1851
1852 env=getenv(envvar);
1853 if (env==NULL) return NULL;
1767 1854
1768/* utility funcs */ 1855 env=xstrdup(env);
1769static char *xstrdup(const char *s) 1856 if (env==NULL) return NULL;
1770{
1771 char *ret = strdup(s);
1772 if (!ret) err("Could not strdup(): %s", strerror(errno));
1773 return ret;
1774}
1775static void *xmalloc(size_t size)
1776{
1777 void *ret = malloc(size);
1778 if (!ret) err("Could not malloc() %li bytes", (unsigned long)size);
1779 return ret;
1780}
1781static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n)
1782{
1783 size_t new_len;
1784 1857
1785 new_len = strlen(*dst) + strlen(src); 1858 nentry=0;
1786 if (*curr_len <= new_len) { 1859 for (s=strtok_r(env, " \t\n", &saveptr);
1787 *curr_len = new_len + (*curr_len / 2); 1860 s!=NULL;
1788 *dst = realloc(*dst, *curr_len); 1861 s=strtok_r(NULL, " \t\n", &saveptr)) {
1789 if (!*dst) 1862 envvals=xrealloc(envvals, sizeof(char *)*(nentry+1));
1790 err("could not realloc() %li bytes", (unsigned long)*curr_len); 1863 if (envvals==NULL) return NULL;
1864 envvals[nentry++]=s;
1791 } 1865 }
1866 envvals[nentry]=NULL;
1792 1867
1793 if (n) 1868 return envvals;
1794 strncat(*dst, src, n);
1795 else
1796 strcat(*dst, src);
1797} 1869}
1798static inline void xchrcat(char **dst, const char append, size_t *curr_len) 1870
1799{ 1871static void parseenv() {
1800 static char my_app[2]; 1872 qa_textrels=get_split_env("QA_TEXTRELS");
1801 my_app[0] = append; 1873 qa_execstack=get_split_env("QA_EXECSTACK");
1802 my_app[1] = '\0';
1803 xstrcat(dst, my_app, curr_len);
1804} 1874}
1805 1875
1806 1876
1807 1877
1808int main(int argc, char *argv[]) 1878int main(int argc, char *argv[])
1809{ 1879{
1810 if (argc < 2) 1880 if (argc < 2)
1811 usage(EXIT_FAILURE); 1881 usage(EXIT_FAILURE);
1882 parseenv();
1812 parseargs(argc, argv); 1883 parseargs(argc, argv);
1813 fclose(stdout); 1884 fclose(stdout);
1814#ifdef __BOUNDS_CHECKING_ON 1885#ifdef __BOUNDS_CHECKING_ON
1815 warn("The calls to add/delete heap should be off by 1 due to the out_buffer not being freed in scanelf_file()"); 1886 warn("The calls to add/delete heap should be off by 1 due to the out_buffer not being freed in scanelf_file()");
1816#endif 1887#endif

Legend:
Removed from v.1.141  
changed lines
  Added in v.1.142

  ViewVC Help
Powered by ViewVC 1.1.20