summaryrefslogtreecommitdiff
blob: 3a956be648b8984f44b9eed13ea78a3dca3284af (plain)
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
Nov 22, 2011

	!!!!! DANGER WILL ROBINSON DANGER !!!!!

We're going to build a system based on some untested code.  I hope everything
will work, but if something serious breaks, you may wind up with a heap of useless
bits all over your floor.  Please, for the love of all that is (un)holy, do not
do this on a system you cannot afford to loose!

If you find a problem, please report it to blueness@gentoo.org.  You're feedback
is much appreciated and will help to make this approach to PaX robust.

--------------------------------------------------------------------------------

*Step 0. Get yourself a gentoo system.  Switch to an appropriate hardened profile
using

	eselect profile set hardened/linux/x86

but don't rebuild anything since we'll be doing that below.

--------------------------------------------------------------------------------

*Step 1.  This step builds a system where all ELF binaries lack the PT_PAX program
header. While not strictly necessary, this makes testing less suspect because you
can be sure that the kernel is not able to get the PaX flags from the PT_PAX phdr.
It does, however, mean recompiling your entire system.


1. First, lets get the overlay with the ebuilds to build an XT_PAX based system.
The goodies are in a branch of the hardened-development overlay:

	layman -L				# in case you don't have the list of overlays
	layman -a hardened-development

	cd /var/lib/layman/hardened-development/
	git checkout XT_PAX				# switch branches
	git pull origin XT_PAX				# and pull

2. Now let's emerge the stuff we'll need later:

	emerge =sys-devel/binutils-2.21.1-r2 \		# these are all masked so
		=sys-kernel/xtpax-sources-3.1.1 \	# we'll have to unmask them
		=sys-apps/elfix-0.3.2 \
		--autounmask-write

	etc-update					# accept changes the changes

	emerge =sys-devel/binutils-2.21.1-r2 \		# these are unmasked, so emerge
		=sys-kernel/xtpax-sources-3.1.1 \
		=sys-apps/elfix-0.3.2

	source /etc/profile				# for binutils, if we keep using
							# the same shell

3. Our version of binutils intentionally excluse the PT_PAX program header from
ELF binaries, so let's make sure its really gone

	echo "int main(){;return 0;}" > test.c ; gcc -o test test.c ; readelf -l test

If you see a PT_PAX header, or possibly one called LOOS+5041580 at the end of the list
(ie after GNU_RELRO), then something went wrong.


4. To be safe, let's rebuild our entire toolchain.

	emerge gcc glibc binutils

5. Then let's rebuild world

	emerge --keep-going -eq world

6. And finally, let's do any post-world rebuild cleanup:

	etc-update

7. As a final test that all binaries under /bin (or /sbin or /usr/bin etc) really
have not PT_PAX header:

	paxctl-ng -v /bin/*

You should see a bunch of reports like this:

	/bin/ls:
		PT_PAX: not found
		XT_PAX: not found

--------------------------------------------------------------------------------

*Step 2. Userland is ready, now let's get kernel land going

1. Configure the kernel for XT_PAX.  It should be emerged as of the above step:

	cd /usr/src/
	rm linux
	ln -s linux-3.1.1-xtpax linux
	cd linux
	make menuconfig

Set up the kernel for your hardware/virtualware, and make sure you get the
correct grsecurity setting:

	Security options  --->
		Grsecurity  --->
			Security Level (Hardened Gentoo [server])	#or workstation

And as a check that XT_PAX was set, navigate to

	Security options  --->
		PaX  --->
			PaX Control  --->
				-*- Use filesystem extended attribute marking

Also, depending on what you're looking for.  Among other options, you may also want:

	CONFIG_PAX_SOFTMODE not configure	<- to make the kernel kill violators
	CONFIG_PAX_SEGMEXEC=y			<- to test S marking on x86
	CONFIG_PAX_EMUTRAMP=y			<- to test E marking
	CONFIG_PAX_PAGEEXEC=y			<- should default on, to test P markings
	CONFIG_PAX_MPROTECT=y			<- should default on, to test M marking
	CONFIG_PAX_RANDMMAP=y			<- should default on, to test R marking

2. Configure the kernel to support Extended File Attributes on whatever filesystem
you want to use.  I also recommend xattr support on tmpfs:

	File systems  --->
		...
		<*> The Extended 4 (ext4) filesystem		# if ext4 is your cup of tea
		[*]   Ext4 extended attributes
		...
		Pseudo filesystems  --->
			-*-   Tmpfs extended attributes
		...
		[*] Miscellaneous filesystems  --->
			<*>   SquashFS 4.0 - Squashed file system support	# optional, as an eg
			[*]     Squashfs XATTR support
		...

3. Compile the kernel and boot.

--------------------------------------------------------------------------------

*Step 3. The new system should be now be a pure XT_PAX system.  Let's test that
PaX restrictions really work.

1. First, make sure your kernel supports XATTRS else you'll get a false negative
on the tests.  Pick any file, not necessarily a binary:

	touch mytestfile.txt
	setfattr -n user.test -v "works" mytestfile.txt 

If you get

	setfattr: mytestfile.txt: Operation not supported

then you need to figure out why XATTR support is not there.  Check that you configured
your kernel correctly.  Also try adding user_xattr to your fstab:

	/dev/sda3      /     ext3     noatime,user_xattr      0 1

and reboot.

NOTE: on my x86 test I needed the user_xattr option in fstab, but with my amd64
I did not.  I didn't investigate further why.


2. The elfix package has a test suite.  Let's run it manually:

	emerge yasm						# you'll need this
	cp /usr/portage/distfiles/elfix-0.3.2.tar.gz .		# should be in your DISTDIR
	tar -xf elfix-0.3.2.tar.gz
	cd elfix-0.3.2
	./configure --enable-tests
	make check

Among the output, you should see a table that looks like this:

	make[3]: Entering directory `/root/elfix-0.3.2/tests/pxtpax'
	./dotest.sh
	xattr  process
	pemrs  pemrs
	pemrS  pemrS
	pemRs  pemRs
	pemRS  pemRS
	peMrs  no daemon
	peMrS  peMrS
	peMRs  no daemon
	peMRS  peMRS
	pEmrs  no daemon
	pEmrS  pEmrS
	pEmRs  no daemon
	pEmRS  pEmRS
	pEMrs  no daemon
	pEMrS  pEMrS
	pEMRs  no daemon
	pEMRS  pEMRS
	Pemrs  Pemrs
	PemrS  Pemrs
	PemRs  PemRs
	PemRS  PemRs
	PeMrs  PeMrs
	PeMrS  PeMrs
	PeMRs  PeMRs
	PeMRS  PeMRs
	PEmrs  PEmrs
	PEmrS  PEmrs
	PEmRs  PEmRs
	PEmRS  PEmRs
	PEMrs  PEMrs
	PEMrS  PEMrs
	PEMRs  PEMRs
	PEMRS  PEMRs

The first column of flags are the markings in the Extended Attributes of the
file on the filesystem, and the second are the flags being imposed by the kernel
on the running process.  If everything worked, the first column should be setting
the flags in the second column, and they should be equal --- well almost with
a couple of exceptions:

	1) "no daemon" means PaX killed the process

	2) On x86, where pageexec is on (P), then segmexec is always off (s) in
	the running process.  On amd64, segmexec is always off (s) since there
	is not segmentation on amd64.

	3) If you didn't enable CONFIG_PAX_EMUTRAMP, then its always off (e) in
	the running process

If however, you see the following:


	make[3]: Entering directory `/root/elfix-0.3.2/tests/pxtpax'
	./dotest.sh
	xattr  process
	pemrs  PeMRs
	pemrS  PeMRs
	pemRs  PeMRs
	pemRS  PeMRs
	peMrs  PeMRs
	peMrS  PeMRs
	peMRs  PeMRs
	... etc ...

then it didn't work.  Notice the second column is simply defaulting to PeMRs
which is what the kernel does if it doesn't find PaX markings.


3. Finally, you may want to do a generic pax test, to make sure pax is working
in general, not just whether the markings are working:

	emerge paxtest --autounmask-write
	etc-update				#accept chagnes
	paxtest blackhat

You should see output something like the following:

Executable anonymous mapping             : Killed
Executable bss                           : Killed
Executable data                          : Killed
Executable heap                          : Killed
Executable stack                         : Killed
Executable shared library bss            : Killed
Executable shared library data           : Killed
Executable anonymous mapping (mprotect)  : Killed
Executable bss (mprotect)                : Killed
Executable data (mprotect)               : Killed
Executable heap (mprotect)               : Killed
Executable stack (mprotect)              : Killed
Executable shared library bss (mprotect) : Killed
Executable shared library data (mprotect): Killed
Writable text segments                   : Killed
Anonymous mapping randomisation test     : 18 bits (guessed)
Heap randomisation test (ET_EXEC)        : 13 bits (guessed)
Heap randomisation test (PIE)            : 24 bits (guessed)
Main executable randomisation (ET_EXEC)  : No randomisation
Main executable randomisation (PIE)      : 16 bits (guessed)
Shared library randomisation test        : 18 bits (guessed)
Stack randomisation test (SEGMEXEC)      : 24 bits (guessed)
Stack randomisation test (PAGEEXEC)      : 24 bits (guessed)
Return to function (strcpy)              : Vulnerable
Return to function (memcpy)              : Vulnerable
Return to function (strcpy, PIE)         : Vulnerable
Return to function (memcpy, PIE)         : Vulnerable