1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
|
diff -urp paxctl-0.3/ChangeLog paxctl-0.4/ChangeLog
--- paxctl-0.3/ChangeLog 2005-05-03 20:04:30.000000000 +0100
+++ paxctl-0.4/ChangeLog 2005-05-29 13:01:11.000000000 +0100
@@ -1,3 +1,6 @@
+2005.05.29 PaX Team <pageexec@freemail.hu>>
+ cleaned up error code reporting, thanks to Kevin F. Quinn <co@kevquinn.com>
+
2005.05.03 PaX Team <pageexec@freemail.hu>>
added -c option to convert PT_GNU_STACK into PT_PAX_FLAGS
minor typo fixes in the code/manpage
diff -urp paxctl-0.3/Makefile paxctl-0.4/Makefile
--- paxctl-0.3/Makefile 2004-02-25 15:20:44.000000000 +0000
+++ paxctl-0.4/Makefile 2005-05-29 12:46:27.000000000 +0100
@@ -1,8 +1,8 @@
CC:=gcc
CP:=cp
-CFLAGS:=-Wall -W -O2# -fPIC
+CFLAGS:=-O2 -Wall -W -Wcast-qual -Wcast-align -Wbad-function-cast -Wsign-compare -Wshadow -Wwrite-strings -Wnested-externs -Winline -Wredundant-decls -Waggregate-return -Wno-format-y2k -Wno-format-extra-args -Wformat-nonliteral -Wformat-security -Wformat=2 -Wdisabled-optimization -Werror -Wpointer-arith -Wconversion -Wmissing-declarations -Wmissing-prototypes -Wunreachable-code
DESTDIR:=
-LDFLAGS:=#-Wl,-pie
+LDFLAGS:=
MANDIR:=/usr/share/man/man1
MKDIR:=mkdir -p
PROG:=paxctl
diff -urp paxctl-0.3/paxctl.c paxctl-0.4/paxctl.c
--- paxctl-0.3/paxctl.c 2005-05-03 21:11:06.000000000 +0100
+++ paxctl-0.4/paxctl.c 2005-05-29 13:03:37.000000000 +0100
@@ -64,7 +64,7 @@ static void * elf32_map_phdr(const int f
return mmap(NULL, size, flags, MAP_SHARED, fd, (off_t)0);
}
-static void elf32_modify_phdr(unsigned char * const map, const struct pax_state * const state)
+static int elf32_modify_phdr(unsigned char * const map, const struct pax_state * const state)
{
unsigned int i, gnu_stack = state->ops->phnum._32, pax_flags = state->ops->phnum._32;
Elf32_Phdr * const phdr = (Elf32_Phdr *)(map + state->ops->phoff._32);
@@ -81,7 +81,7 @@ static void elf32_modify_phdr(unsigned c
if (gnu_stack == state->ops->phnum._32) {
if (!state->quiet)
fprintf(stderr, "file %s does not have a PT_GNU_STACK program header, conversion failed\n", state->argv[state->files]);
- return;
+ return EXIT_FAILURE;
}
phdr[gnu_stack].p_type = PT_PAX_FLAGS;
phdr[gnu_stack].p_flags = PF_NORANDEXEC | PF_NOEMUTRAMP;
@@ -89,7 +89,7 @@ static void elf32_modify_phdr(unsigned c
} else {
if (!state->quiet)
fprintf(stderr, "file %s does not have a PT_PAX_FLAGS program header\n", state->argv[state->files]);
- return;
+ return EXIT_FAILURE;
}
}
@@ -106,6 +106,7 @@ static void elf32_modify_phdr(unsigned c
phdr[pax_flags].p_flags |= state->flags_on;
}
}
+ return EXIT_SUCCESS;
}
static void * elf64_map_phdr(const int fd, const struct pax_state * const state)
@@ -116,7 +117,7 @@ static void * elf64_map_phdr(const int f
return mmap(NULL, size, flags, MAP_SHARED, fd, (off_t)0);
}
-static void elf64_modify_phdr(unsigned char * const map, const struct pax_state * const state)
+static int elf64_modify_phdr(unsigned char * const map, const struct pax_state * const state)
{
unsigned int i, gnu_stack = state->ops->phnum._64, pax_flags = state->ops->phnum._64;;
Elf64_Phdr * const phdr = (Elf64_Phdr *)(map + state->ops->phoff._64);
@@ -133,7 +134,7 @@ static void elf64_modify_phdr(unsigned c
if (gnu_stack == state->ops->phnum._64) {
if (!state->quiet)
fprintf(stderr, "file %s does not have a PT_GNU_STACK program header, conversion failed\n", state->argv[state->files]);
- return;
+ return EXIT_FAILURE;
}
phdr[gnu_stack].p_type = PT_PAX_FLAGS;
phdr[gnu_stack].p_flags = PF_NORANDEXEC | PF_NOEMUTRAMP;
@@ -141,7 +142,7 @@ static void elf64_modify_phdr(unsigned c
} else {
if (!state->quiet)
fprintf(stderr, "file %s does not have a PT_PAX_FLAGS program header\n", state->argv[state->files]);
- return;
+ return EXIT_FAILURE;
}
}
@@ -158,6 +159,7 @@ static void elf64_modify_phdr(unsigned c
phdr[pax_flags].p_flags |= state->flags_on;
}
}
+ return EXIT_SUCCESS;
}
static struct elf_ops elf32 = {
@@ -193,7 +195,7 @@ static void usage(void)
"\t-q: suppress error messages\t-Q: report flags in short format\n"
"\t-c: convert PT_GNU_STACK into PT_PAX_FLAGS (see manpage!)\n"
);
- exit(EXIT_SUCCESS);
+ exit(EXIT_FAILURE);
}
static int is_elf32(const void * const map, off_t size, struct pax_state * const state)
@@ -257,41 +259,41 @@ static int is_elf64(const void * const m
static int pax_verify_file(struct pax_state * const state)
{
int fd;
- const void * map;
+ void * map;
size_t size = sizeof(Elf64_Ehdr);
struct stat st;
fd = open(state->argv[state->files], O_RDONLY);
if (0 > fd) {
if (!state->quiet)
- perror("open: ");
- return -1;
+ perror(state->argv[state->files]);
+ return EXIT_FAILURE;
}
if (-1 == fstat(fd, &st)) {
close(fd);
if (!state->quiet)
- perror("fstat: ");
- return -1;
+ perror(state->argv[state->files]);
+ return EXIT_FAILURE;
}
map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, (off_t)0);
close(fd);
if (MAP_FAILED == map) {
if (!state->quiet)
- perror("mmap: ");
- return -1;
+ perror(state->argv[state->files]);
+ return EXIT_FAILURE;
}
if (st.st_size < 0 || (!is_elf32(map, st.st_size, state) && !is_elf64(map, st.st_size, state))) {
- munmap((void *)map, size);
+ munmap(map, size);
if (!state->quiet)
fprintf(stderr, "file %s is not a valid ELF executable\n", state->argv[state->files]);
- return -1;
+ return EXIT_FAILURE;
}
- munmap((void *)map, size);
- return 0;
+ munmap(map, size);
+ return EXIT_SUCCESS;
}
static int pax_modify_file(const struct pax_state * const state)
@@ -303,8 +305,8 @@ static int pax_modify_file(const struct
fd = open(state->argv[state->files], (state->flags_on | state->flags_off | state->convert) ? O_RDWR : O_RDONLY);
if (0 > fd) {
if (!state->quiet)
- perror("open: ");
- return -1;
+ perror(state->argv[state->files]);
+ return EXIT_FAILURE;
}
/* mmap file */
@@ -312,36 +314,35 @@ static int pax_modify_file(const struct
close(fd);
if (MAP_FAILED == map) {
if (!state->quiet)
- perror("mmap: ");
- return -1;
+ perror(state->argv[state->files]);
+ return EXIT_FAILURE;
}
/* report/modify flags */
- state->ops->modify_phdr(map, state);
- return 0;
+ return state->ops->modify_phdr(map, state);
}
static int pax_process_file(struct pax_state * const state)
{
/* get/verify ELF header */
- if (0 > pax_verify_file(state))
- return -1;
-
- /* report/modify program header */
- if (0 > pax_modify_file(state))
- return -1;
+ if (EXIT_SUCCESS == pax_verify_file(state))
+ /* report/modify program header */
+ return pax_modify_file(state);
- return 0;
+ return EXIT_FAILURE;
}
static int pax_process_files(struct pax_state * const state)
{
+ int status = EXIT_SUCCESS;
+
while (state->argv[state->files]) {
- pax_process_file(state);
+ if (EXIT_SUCCESS != pax_process_file(state))
+ status = EXIT_FAILURE;
++state->files;
}
- return 0;
+ return status;
}
static int pax_parse_args(int argc, struct pax_state * const state)
@@ -350,31 +351,31 @@ static int pax_parse_args(int argc, stru
switch(getopt(argc, state->argv, "pPsSmMeErRxXvqQzc")) {
case -1:
state->files = optind;
- return optind < argc ? 0 : -1;
+ return optind < argc ? EXIT_SUCCESS : EXIT_FAILURE;
case '?':
- return -1;
+ return EXIT_FAILURE;
#define parse_flag(option1, option2, flag) \
- case option1: \
- state->flags_on &= ~PF_##flag; \
- state->flags_on |= PF_NO##flag; \
- state->flags_off &= ~PF_NO##flag; \
- state->flags_off |= PF_##flag; \
- break; \
- case option2: \
- state->flags_on &= ~PF_NO##flag; \
- state->flags_on |= PF_##flag; \
- state->flags_off &= ~PF_##flag; \
- state->flags_off |= PF_NO##flag; \
- break;
-
- parse_flag('p', 'P', PAGEEXEC);
- parse_flag('s', 'S', SEGMEXEC);
- parse_flag('m', 'M', MPROTECT);
- parse_flag('e', 'E', EMUTRAMP);
- parse_flag('r', 'R', RANDMMAP);
- parse_flag('x', 'X', RANDEXEC);
+ case option1: \
+ state->flags_on &= ~PF_##flag; \
+ state->flags_on |= PF_NO##flag; \
+ state->flags_off &= ~PF_NO##flag; \
+ state->flags_off |= PF_##flag; \
+ break; \
+ case option2: \
+ state->flags_on &= ~PF_NO##flag; \
+ state->flags_on |= PF_##flag; \
+ state->flags_off &= ~PF_##flag; \
+ state->flags_off |= PF_NO##flag; \
+ break;
+
+ parse_flag('p', 'P', PAGEEXEC);
+ parse_flag('s', 'S', SEGMEXEC);
+ parse_flag('m', 'M', MPROTECT);
+ parse_flag('e', 'E', EMUTRAMP);
+ parse_flag('r', 'R', RANDMMAP);
+ parse_flag('x', 'X', RANDEXEC);
#undef parse_flag
@@ -420,15 +421,12 @@ int main(int argc, char * argv[])
usage();
/* parse arguments */
- if (0 > pax_parse_args(argc, &state))
- return -1;
+ if (EXIT_SUCCESS != pax_parse_args(argc, &state))
+ return EXIT_FAILURE;
if (state.view)
banner();
/* process files */
- if (0 > pax_process_files(&state))
- return -2;
-
- return 0;
+ return pax_process_files(&state);
}
diff -urp paxctl-0.3/paxctl.h paxctl-0.4/paxctl.h
--- paxctl-0.3/paxctl.h 2005-05-02 22:21:39.000000000 +0100
+++ paxctl-0.4/paxctl.h 2005-05-29 12:41:03.000000000 +0100
@@ -3,13 +3,13 @@
#include <elf.h>
-#define PAXCTL_VERSION "0.3"
+#define PAXCTL_VERSION "0.4"
struct pax_state;
struct elf_ops {
void * (* const map_phdr)(const int, const struct pax_state * const);
- void (* const modify_phdr)(unsigned char * const, const struct pax_state * const);
+ int (* const modify_phdr)(unsigned char * const, const struct pax_state * const);
union {
Elf32_Off _32;
Elf64_Off _64;
@@ -40,18 +40,18 @@ struct pax_state {
#define PT_PAX_FLAGS 0x65041580
-#define PF_PAGEEXEC (1 << 4) /* Enable PAGEEXEC */
-#define PF_NOPAGEEXEC (1 << 5) /* Disable PAGEEXEC */
-#define PF_SEGMEXEC (1 << 6) /* Enable SEGMEXEC */
-#define PF_NOSEGMEXEC (1 << 7) /* Disable SEGMEXEC */
-#define PF_MPROTECT (1 << 8) /* Enable MPROTECT */
-#define PF_NOMPROTECT (1 << 9) /* Disable MPROTECT */
-#define PF_RANDEXEC (1 << 10) /* Enable RANDEXEC */
-#define PF_NORANDEXEC (1 << 11) /* Disable RANDEXEC */
-#define PF_EMUTRAMP (1 << 12) /* Enable EMUTRAMP */
-#define PF_NOEMUTRAMP (1 << 13) /* Disable EMUTRAMP */
-#define PF_RANDMMAP (1 << 14) /* Enable RANDMMAP */
-#define PF_NORANDMMAP (1 << 15) /* Disable RANDMMAP */
+#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
+#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
+#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
+#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
+#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
+#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
+#define PF_RANDEXEC (1U << 10) /* Enable RANDEXEC */
+#define PF_NORANDEXEC (1U << 11) /* Disable RANDEXEC */
+#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
+#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
+#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
+#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
#endif
|