2 * This program manages various PaX related flags for ELF and a.out binaries.
3 * The flags only have effect when running the patched Linux kernel.
5 * Written by Solar Designer and placed in the public domain.
7 * Adapted to PaX by the PaX Team.
12 #include <sys/types.h>
15 #include <linux/elf.h>
16 #include <linux/a.out.h>
18 #define HF_PAX_PAGEEXEC 1 /* 0: Enforce PAGE_EXEC */
19 #define HF_PAX_EMUTRAMP 2 /* 0: Emulate trampolines */
20 #define HF_PAX_MPROTECT 4 /* 0: Restrict mprotect() */
21 #define HF_PAX_RANDMMAP 8 /* 0: Randomize mmap() base */
23 static struct elf32_hdr header_elf;
24 static struct exec header_aout;
26 static int header_size;
29 static unsigned long (*get_flags)();
30 static void (*put_flags)(unsigned long);
32 static unsigned long get_flags_elf()
34 return header_elf.e_flags;
37 static void put_flags_elf(unsigned long flags)
39 header_elf.e_flags = flags;
42 static unsigned long get_flags_aout()
44 return N_FLAGS(header_aout);
47 static void put_flags_aout(unsigned long flags)
49 N_SET_FLAGS(header_aout, flags & ~HF_PAX_RANDMMAP);
52 static int read_header(char *name, int mode)
57 if ((fd = open(name, mode)) < 0) return 1;
59 ptr = (char *)&header_elf;
60 size = sizeof(header_elf);
62 block = read(fd, ptr, size);
67 ptr += block; size -= block;
70 memcpy(&header_aout, &header_elf, sizeof(header_aout));
72 if (!strncmp(header_elf.e_ident, ELFMAG, SELFMAG)) {
73 if (header_elf.e_type != ET_EXEC && header_elf.e_type != ET_DYN) return 2;
74 if (header_elf.e_machine != EM_386) return 3;
75 header = &header_elf; header_size = sizeof(header_elf);
76 get_flags = get_flags_elf; put_flags = put_flags_elf;
78 if (N_MAGIC(header_aout) == NMAGIC ||
79 N_MAGIC(header_aout) == ZMAGIC ||
80 N_MAGIC(header_aout) == QMAGIC) {
81 if (N_MACHTYPE(header_aout) != M_386) return 3;
82 header = &header_aout; header_size = 4;
83 get_flags = get_flags_aout; put_flags = put_flags_aout;
94 if (lseek(fd, 0, SEEK_SET)) return 1;
99 block = write(fd, ptr, size);
100 if (block <= 0) break;
101 ptr += block; size -= block;
108 "Usage: %s OPTIONS FILE...\n" \
109 "Manage PaX flags for binaries\n\n" \
110 " -P\tenforce PAGE_EXEC\n" \
111 " -p\tdo not enforce PAGE_EXEC\n" \
112 " -E\temulate trampolines\n" \
113 " -e\tdo not emulate trampolines\n" \
114 " -M\trestrict mprotect()\n" \
115 " -m\tdo not restrict mprotect()\n" \
116 " -R\trandomize mmap() base [ELF only]\n" \
117 " -r\tdo not randomize mmap() base [ELF only]\n" \
118 " -v\tview current flag state\n\n" \
119 "The flags only have effect when running the patched Linux kernel.\n"
121 void usage(char *name)
123 printf(USAGE, name ? name : "chpax");
127 int main(int argc, char **argv)
134 if (argc < 3) usage(argv[0]);
135 if (strlen(argv[1]) != 2) usage(argv[0]);
136 if (argv[1][0] != '-' || !strchr("pPeEmMrRv", argv[1][1])) usage(argv[0]);
140 mode = argv[1][1] == 'v' ? O_RDONLY : O_RDWR;
141 switch (read_header(*current, mode)) {
147 printf("%s: Unknown file type\n", *current);
151 printf("%s: Wrong architecture\n", *current);
157 switch (argv[1][1]) {
159 put_flags(flags | HF_PAX_PAGEEXEC);
163 put_flags(flags & ~HF_PAX_PAGEEXEC);
167 put_flags(flags | HF_PAX_EMUTRAMP);
171 put_flags(flags & ~HF_PAX_EMUTRAMP);
175 put_flags(flags | HF_PAX_MPROTECT);
179 put_flags(flags & ~HF_PAX_MPROTECT);
183 put_flags(flags | HF_PAX_RANDMMAP);
187 put_flags(flags & ~HF_PAX_RANDMMAP);
193 "trampolines are %s, "
195 "mmap() base is %s\n", *current,
196 flags & HF_PAX_PAGEEXEC
197 ? "disabled" : "enabled",
198 flags & HF_PAX_EMUTRAMP
199 ? "emulated" : "not emulated",
200 flags & HF_PAX_MPROTECT
201 ? "not restricted" : "restricted",
202 flags & HF_PAX_RANDMMAP
203 ? "not randomized" : "randomized");
206 if (flags != get_flags())
207 if (write_header()) {
213 } while (*++current);