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-47
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 **get_split_env(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); |
|
|
48 |
static void *xrealloc(void *ptr, size_t size); |
45 |
static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n); |
49 |
static 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) |
47 |
static inline void xchrcat(char **dst, const char append, size_t *curr_len); |
51 |
static inline void xchrcat(char **dst, const char append, size_t *curr_len); |
Lines 78-88
Link Here
|
78 |
static char gmatch = 0; |
82 |
static char gmatch = 0; |
79 |
static char use_ldcache = 0; |
83 |
static char use_ldcache = 0; |
80 |
|
84 |
|
|
|
85 |
static char **qa_textrels = NULL; |
86 |
static char **qa_execstack = NULL; |
87 |
|
81 |
int match_bits = 0; |
88 |
int match_bits = 0; |
82 |
caddr_t ldcache = 0; |
89 |
caddr_t ldcache = 0; |
83 |
size_t ldcache_size = 0; |
90 |
size_t ldcache_size = 0; |
84 |
unsigned long setpax = 0UL; |
91 |
unsigned long setpax = 0UL; |
85 |
|
92 |
|
|
|
93 |
/* utility funcs */ |
94 |
static 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 |
} |
100 |
static 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 |
} |
106 |
static 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 |
} |
112 |
static 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 |
} |
129 |
static 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 */ |
139 |
static 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 |
} |
159 |
|
86 |
/* sub-funcs for scanelf_file() */ |
160 |
/* sub-funcs for scanelf_file() */ |
87 |
static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) |
161 |
static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) |
88 |
{ |
162 |
{ |
Lines 200-208
Link Here
|
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); \ |
203 |
found = found_phdr; \ |
277 |
if (!file_matches_list(elf->filename, qa_execstack)) {\ |
204 |
offset = 0; \ |
278 |
found = found_phdr; \ |
205 |
check_flags = PF_X; \ |
279 |
offset = 0; \ |
|
|
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; \ |
Lines 271-276
Link Here
|
271 |
else |
347 |
else |
272 |
return ret; |
348 |
return ret; |
273 |
} |
349 |
} |
|
|
350 |
|
274 |
static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel) |
351 |
static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel) |
275 |
{ |
352 |
{ |
276 |
static const char *ret = "TEXTREL"; |
353 |
static const char *ret = "TEXTREL"; |
Lines 278-283
Link Here
|
278 |
|
355 |
|
279 |
if (!show_textrel && !show_textrels) return NULL; |
356 |
if (!show_textrel && !show_textrels) return NULL; |
280 |
|
357 |
|
|
|
358 |
if (file_matches_list(elf->filename, qa_textrels)) return NULL; |
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) { \ |
Lines 1253-1259
Link Here
|
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); |
Lines 1763-1806
Link Here
|
1763 |
munmap(ldcache, ldcache_size); |
1842 |
munmap(ldcache, ldcache_size); |
1764 |
} |
1843 |
} |
1765 |
|
1844 |
|
1766 |
|
1845 |
static char **get_split_env(const char *envvar) { |
1767 |
|
1846 |
char **envvals=NULL; |
1768 |
/* utility funcs */ |
1847 |
char *saveptr=NULL; |
1769 |
static char *xstrdup(const char *s) |
1848 |
char *env; |
1770 |
{ |
1849 |
char *s; |
1771 |
char *ret = strdup(s); |
1850 |
int nentry; |
1772 |
if (!ret) err("Could not strdup(): %s", strerror(errno)); |
1851 |
|
1773 |
return ret; |
1852 |
env=getenv(envvar); |
1774 |
} |
1853 |
if (env==NULL) return NULL; |
1775 |
static void *xmalloc(size_t size) |
1854 |
|
1776 |
{ |
1855 |
env=xstrdup(env); |
1777 |
void *ret = malloc(size); |
1856 |
if (env==NULL) return NULL; |
1778 |
if (!ret) err("Could not malloc() %li bytes", (unsigned long)size); |
1857 |
|
1779 |
return ret; |
1858 |
nentry=0; |
1780 |
} |
1859 |
for (s=strtok_r(env, " \t\n", &saveptr); |
1781 |
static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n) |
1860 |
s!=NULL; |
1782 |
{ |
1861 |
s=strtok_r(NULL, " \t\n", &saveptr)) { |
1783 |
size_t new_len; |
1862 |
envvals=xrealloc(envvals, sizeof(char *)*(nentry+1)); |
1784 |
|
1863 |
if (envvals==NULL) return NULL; |
1785 |
new_len = strlen(*dst) + strlen(src); |
1864 |
envvals[nentry++]=s; |
1786 |
if (*curr_len <= new_len) { |
1865 |
} |
1787 |
*curr_len = new_len + (*curr_len / 2); |
1866 |
envvals[nentry]=NULL; |
1788 |
*dst = realloc(*dst, *curr_len); |
1867 |
|
1789 |
if (!*dst) |
1868 |
return envvals; |
1790 |
err("could not realloc() %li bytes", (unsigned long)*curr_len); |
1869 |
} |
1791 |
} |
1870 |
|
1792 |
|
1871 |
static void parseenv() { |
1793 |
if (n) |
1872 |
qa_textrels=get_split_env("QA_TEXTRELS"); |
1794 |
strncat(*dst, src, n); |
1873 |
qa_execstack=get_split_env("QA_EXECSTACK"); |
1795 |
else |
|
|
1796 |
strcat(*dst, src); |
1797 |
} |
1798 |
static inline void xchrcat(char **dst, const char append, size_t *curr_len) |
1799 |
{ |
1800 |
static char my_app[2]; |
1801 |
my_app[0] = append; |
1802 |
my_app[1] = '\0'; |
1803 |
xstrcat(dst, my_app, curr_len); |
1804 |
} |
1874 |
} |
1805 |
|
1875 |
|
1806 |
|
1876 |
|
Lines 1809-1814
Link Here
|
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 |