Lines 31-36
Link Here
|
31 |
|
31 |
|
32 |
|
32 |
|
33 |
/* prototypes */ |
33 |
/* prototypes */ |
|
|
34 |
static int file_matches_list(const char *filename, char **matchlist); |
34 |
static int scanelf_elfobj(elfobj *elf); |
35 |
static int scanelf_elfobj(elfobj *elf); |
35 |
static int scanelf_elf(const char *filename, int fd, size_t len); |
36 |
static int scanelf_elf(const char *filename, int fd, size_t len); |
36 |
static int scanelf_archive(const char *filename, int fd, size_t len); |
37 |
static int scanelf_archive(const char *filename, int fd, size_t len); |
Lines 39-44
Link Here
|
39 |
static void scanelf_ldpath(void); |
40 |
static void scanelf_ldpath(void); |
40 |
static void scanelf_envpath(void); |
41 |
static void scanelf_envpath(void); |
41 |
static void usage(int status); |
42 |
static void usage(int status); |
|
|
43 |
static char **getpathenv(const char *envvar); |
44 |
static void parseenv(void); |
42 |
static void parseargs(int argc, char *argv[]); |
45 |
static void parseargs(int argc, char *argv[]); |
43 |
static char *xstrdup(const char *s); |
46 |
static char *xstrdup(const char *s); |
44 |
static void *xmalloc(size_t size); |
47 |
static void *xmalloc(size_t size); |
Lines 78-88
Link Here
|
78 |
static char gmatch = 0; |
81 |
static char gmatch = 0; |
79 |
static char use_ldcache = 0; |
82 |
static char use_ldcache = 0; |
80 |
|
83 |
|
|
|
84 |
static char **qa_textrels = NULL; |
85 |
static char **qa_execstack = NULL; |
86 |
|
81 |
int match_bits = 0; |
87 |
int match_bits = 0; |
82 |
caddr_t ldcache = 0; |
88 |
caddr_t ldcache = 0; |
83 |
size_t ldcache_size = 0; |
89 |
size_t ldcache_size = 0; |
84 |
unsigned long setpax = 0UL; |
90 |
unsigned long setpax = 0UL; |
85 |
|
91 |
|
|
|
92 |
/* utility funcs */ |
93 |
static char *xstrdup(const char *s) |
94 |
{ |
95 |
char *ret = strdup(s); |
96 |
if (!ret) err("Could not strdup(): %s", strerror(errno)); |
97 |
return ret; |
98 |
} |
99 |
static void *xmalloc(size_t size) |
100 |
{ |
101 |
void *ret = malloc(size); |
102 |
if (!ret) err("Could not malloc() %li bytes", (unsigned long)size); |
103 |
return ret; |
104 |
} |
105 |
static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n) |
106 |
{ |
107 |
size_t new_len; |
108 |
|
109 |
new_len = strlen(*dst) + strlen(src); |
110 |
if (*curr_len <= new_len) { |
111 |
*curr_len = new_len + (*curr_len / 2); |
112 |
*dst = realloc(*dst, *curr_len); |
113 |
if (!*dst) |
114 |
err("could not realloc() %li bytes", (unsigned long)*curr_len); |
115 |
} |
116 |
|
117 |
if (n) |
118 |
strncat(*dst, src, n); |
119 |
else |
120 |
strcat(*dst, src); |
121 |
} |
122 |
static inline void xchrcat(char **dst, const char append, size_t *curr_len) |
123 |
{ |
124 |
static char my_app[2]; |
125 |
my_app[0] = append; |
126 |
my_app[1] = '\0'; |
127 |
xstrcat(dst, my_app, curr_len); |
128 |
} |
129 |
|
130 |
/* Match filename against entries in matchlist, return TRUE |
131 |
* if the file is listed */ |
132 |
static int file_matches_list(const char *filename, char **matchlist) { |
133 |
char **file; |
134 |
char *match; |
135 |
char buf[__PAX_UTILS_PATH_MAX]; |
136 |
if (matchlist!=NULL) { |
137 |
for (file=matchlist; |
138 |
*file!=NULL; |
139 |
file++) { |
140 |
if (search_path) { |
141 |
snprintf(buf,__PAX_UTILS_PATH_MAX,"%s%s",search_path,*file); |
142 |
match=buf; |
143 |
} else { |
144 |
match=file; |
145 |
} |
146 |
if (fnmatch(match, filename, 0) == 0) |
147 |
return 1; /* TRUE */ |
148 |
} |
149 |
} |
150 |
return 0; /* FALSE */ |
151 |
} |
152 |
|
86 |
/* sub-funcs for scanelf_file() */ |
153 |
/* sub-funcs for scanelf_file() */ |
87 |
static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) |
154 |
static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) |
88 |
{ |
155 |
{ |
Lines 200-208
Link Here
|
200 |
for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \ |
267 |
for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \ |
201 |
if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ |
268 |
if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ |
202 |
if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \ |
269 |
if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \ |
203 |
found = found_phdr; \ |
270 |
if (!file_matches_list(elf->filename, qa_execstack)) {\ |
204 |
offset = 0; \ |
271 |
found = found_phdr; \ |
205 |
check_flags = PF_X; \ |
272 |
offset = 0; \ |
|
|
273 |
check_flags = PF_X; \ |
274 |
} else continue; \ |
206 |
} else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \ |
275 |
} else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \ |
207 |
if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \ |
276 |
if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \ |
208 |
found = found_relro; \ |
277 |
found = found_relro; \ |
Lines 271-276
Link Here
|
271 |
else |
340 |
else |
272 |
return ret; |
341 |
return ret; |
273 |
} |
342 |
} |
|
|
343 |
|
274 |
static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel) |
344 |
static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel) |
275 |
{ |
345 |
{ |
276 |
static const char *ret = "TEXTREL"; |
346 |
static const char *ret = "TEXTREL"; |
Lines 278-283
Link Here
|
278 |
|
348 |
|
279 |
if (!show_textrel && !show_textrels) return NULL; |
349 |
if (!show_textrel && !show_textrels) return NULL; |
280 |
|
350 |
|
|
|
351 |
if (file_matches_list(elf->filename, qa_textrels)) return NULL; |
352 |
|
281 |
if (elf->phdr) { |
353 |
if (elf->phdr) { |
282 |
#define SHOW_TEXTREL(B) \ |
354 |
#define SHOW_TEXTREL(B) \ |
283 |
if (elf->elf_class == ELFCLASS ## B) { \ |
355 |
if (elf->elf_class == ELFCLASS ## B) { \ |
Lines 1253-1259
Link Here
|
1253 |
(unsigned long)len, (unsigned long)sizeof(buf)); |
1325 |
(unsigned long)len, (unsigned long)sizeof(buf)); |
1254 |
continue; |
1326 |
continue; |
1255 |
} |
1327 |
} |
1256 |
sprintf(buf, "%s/%s", path, dentry->d_name); |
1328 |
sprintf(buf, "%s%s%s", path, path[pathlen-1]=='/'?"":"/", dentry->d_name); |
1257 |
if (lstat(buf, &st) != -1) { |
1329 |
if (lstat(buf, &st) != -1) { |
1258 |
if (S_ISREG(st.st_mode)) |
1330 |
if (S_ISREG(st.st_mode)) |
1259 |
scanelf_file(buf); |
1331 |
scanelf_file(buf); |
Lines 1765-1806
Link Here
|
1765 |
|
1837 |
|
1766 |
|
1838 |
|
1767 |
|
1839 |
|
1768 |
/* utility funcs */ |
1840 |
static char **getpathenv(const char *envvar) { |
1769 |
static char *xstrdup(const char *s) |
1841 |
char **envvals=NULL; |
1770 |
{ |
1842 |
char *env=getenv(envvar); |
1771 |
char *ret = strdup(s); |
1843 |
char *saveptr=NULL; |
1772 |
if (!ret) err("Could not strdup(): %s", strerror(errno)); |
1844 |
int nentries; |
1773 |
return ret; |
1845 |
char *s; |
1774 |
} |
1846 |
int nentry; |
1775 |
static void *xmalloc(size_t size) |
1847 |
|
1776 |
{ |
1848 |
if (env==NULL) return NULL; |
1777 |
void *ret = malloc(size); |
1849 |
|
1778 |
if (!ret) err("Could not malloc() %li bytes", (unsigned long)size); |
1850 |
env=xstrdup(env); |
1779 |
return ret; |
1851 |
if (env==NULL) return NULL; |
1780 |
} |
1852 |
|
1781 |
static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n) |
1853 |
/* Count number of ":"-separated entries in env */ |
1782 |
{ |
1854 |
nentries=1; |
1783 |
size_t new_len; |
1855 |
for (s=env; *s>0; s++) |
1784 |
|
1856 |
if (*s==':') |
1785 |
new_len = strlen(*dst) + strlen(src); |
1857 |
nentries++; |
1786 |
if (*curr_len <= new_len) { |
1858 |
|
1787 |
*curr_len = new_len + (*curr_len / 2); |
1859 |
/* Allocate space for 'nentries' + 1 for terminating NULL */ |
1788 |
*dst = realloc(*dst, *curr_len); |
1860 |
envvals=(char **)xmalloc(sizeof(char *)*(nentries+1)); |
1789 |
if (!*dst) |
1861 |
if (envvals==NULL) return NULL; |
1790 |
err("could not realloc() %li bytes", (unsigned long)*curr_len); |
1862 |
|
1791 |
} |
1863 |
nentry=0; |
1792 |
|
1864 |
for (s=strtok_r(env, ":", &saveptr); |
1793 |
if (n) |
1865 |
s!=NULL; |
1794 |
strncat(*dst, src, n); |
1866 |
s=strtok_r(NULL, ":", &saveptr)) { |
1795 |
else |
1867 |
envvals[nentry++]=s; |
1796 |
strcat(*dst, src); |
1868 |
} |
1797 |
} |
1869 |
envvals[nentry]=NULL; |
1798 |
static inline void xchrcat(char **dst, const char append, size_t *curr_len) |
1870 |
/* sanity check */ |
1799 |
{ |
1871 |
assert(nentry==nentries); |
1800 |
static char my_app[2]; |
1872 |
|
1801 |
my_app[0] = append; |
1873 |
return envvals; |
1802 |
my_app[1] = '\0'; |
1874 |
} |
1803 |
xstrcat(dst, my_app, curr_len); |
1875 |
|
|
|
1876 |
static void parseenv() { |
1877 |
qa_textrels=getpathenv("QA_TEXTRELS"); |
1878 |
qa_execstack=getpathenv("QA_EXECSTACK"); |
1804 |
} |
1879 |
} |
1805 |
|
1880 |
|
1806 |
|
1881 |
|
Lines 1809-1814
Link Here
|
1809 |
{ |
1884 |
{ |
1810 |
if (argc < 2) |
1885 |
if (argc < 2) |
1811 |
usage(EXIT_FAILURE); |
1886 |
usage(EXIT_FAILURE); |
|
|
1887 |
parseenv(); |
1812 |
parseargs(argc, argv); |
1888 |
parseargs(argc, argv); |
1813 |
fclose(stdout); |
1889 |
fclose(stdout); |
1814 |
#ifdef __BOUNDS_CHECKING_ON |
1890 |
#ifdef __BOUNDS_CHECKING_ON |