1 |
commit: 0e8cea4d730a33a703c5811e69e7bf948128270c |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue May 21 15:21:13 2013 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue May 21 15:22:53 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=0e8cea4d |
7 |
|
8 |
misc/pax-utils.eclass: add a copy for the records |
9 |
|
10 |
--- |
11 |
misc/pax-utils.eclass | 218 +++++++++++++++++++++++++++++++++++++++++++++++++ |
12 |
1 files changed, 218 insertions(+), 0 deletions(-) |
13 |
|
14 |
diff --git a/misc/pax-utils.eclass b/misc/pax-utils.eclass |
15 |
new file mode 100644 |
16 |
index 0000000..547d6ac |
17 |
--- /dev/null |
18 |
+++ b/misc/pax-utils.eclass |
19 |
@@ -0,0 +1,218 @@ |
20 |
+# Copyright 1999-2013 Gentoo Foundation |
21 |
+# Distributed under the terms of the GNU General Public License v2 |
22 |
+# $Header: /var/cvsroot/gentoo-x86/eclass/pax-utils.eclass,v 1.21 2013/05/18 13:43:20 zorry Exp $ |
23 |
+ |
24 |
+# @ECLASS: pax-utils.eclass |
25 |
+# @MAINTAINER: |
26 |
+# The Gentoo Linux Hardened Team <hardened@g.o> |
27 |
+# @AUTHOR: |
28 |
+# Original Author: Kevin F. Quinn <kevquinn@g.o> |
29 |
+# Modifications for bug #365825, @ ECLASS markup: Anthony G. Basile <blueness@g.o> |
30 |
+# Modifications for bug #431092: Anthony G. Basile <blueness@g.o> |
31 |
+# @BLURB: functions to provide pax markings |
32 |
+# @DESCRIPTION: |
33 |
+# |
34 |
+# This eclass provides support for manipulating PaX markings on ELF binaries, |
35 |
+# whether the system is using legacy PT_PAX markings or the newer XATTR_PAX. |
36 |
+# The eclass wraps the use of paxctl-ng, paxctl, set/getattr and scanelf utilities, |
37 |
+# deciding which to use depending on what's installed on the build host, and |
38 |
+# whether we're working with PT_PAX, XATTR_PAX or both. |
39 |
+# |
40 |
+# To control what markings are made, set PAX_MARKINGS in /etc/portage/make.conf |
41 |
+# to contain either "PT", "XT" or "none". The default is to attempt both |
42 |
+# PT_PAX and XATTR_PAX. |
43 |
+ |
44 |
+if [[ ${___ECLASS_ONCE_PAX_UTILS} != "recur -_+^+_- spank" ]] ; then |
45 |
+___ECLASS_ONCE_PAX_UTILS="recur -_+^+_- spank" |
46 |
+ |
47 |
+# @ECLASS-VARIABLE: PAX_MARKINGS |
48 |
+# @DESCRIPTION: |
49 |
+# Control which markings are made: |
50 |
+# PT = PT_PAX markings, XT = XATTR_PAX markings |
51 |
+# Default to PT markings. |
52 |
+PAX_MARKINGS=${PAX_MARKINGS:="PT"} |
53 |
+ |
54 |
+# @FUNCTION: pax-mark |
55 |
+# @USAGE: <flags> {<ELF files>} |
56 |
+# @RETURN: Shell true if we succeed, shell false otherwise |
57 |
+# @DESCRIPTION: |
58 |
+# Marks <ELF files> with provided PaX <flags> |
59 |
+# |
60 |
+# Flags are passed directly to the utilities unchanged |
61 |
+# |
62 |
+# p: disable PAGEEXEC P: enable PAGEEXEC |
63 |
+# e: disable EMUTRAMP E: enable EMUTRAMP |
64 |
+# m: disable MPROTECT M: enable MPROTECT |
65 |
+# r: disable RANDMMAP R: enable RANDMMAP |
66 |
+# s: disable SEGMEXEC S: enable SEGMEXEC |
67 |
+# |
68 |
+# Default flags are 'PeMRS', which are the most restrictive settings. Refer |
69 |
+# to http://pax.grsecurity.net/ for details on what these flags are all about. |
70 |
+# |
71 |
+# Please confirm any relaxation of restrictions with the Gentoo Hardened team. |
72 |
+# Either ask on the gentoo-hardened mailing list, or CC/assign hardened@g.o on |
73 |
+# the bug report. |
74 |
+pax-mark() { |
75 |
+ |
76 |
+ local f # loop over paxables |
77 |
+ local flags # pax flags |
78 |
+ local pt_fail=0 pt_failures="" # record PT_PAX failures |
79 |
+ local xt_fail=0 xt_failures="" # record xattr PAX marking failures |
80 |
+ local ret=0 # overal return code of this function |
81 |
+ |
82 |
+ # Only the actual PaX flags and z are accepted |
83 |
+ # 1. The leading '-' is optional |
84 |
+ # 2. -C -c only make sense for paxctl, but are unnecessary |
85 |
+ # because we progressively do -q -qc -qC |
86 |
+ # 3. z is allowed for the default |
87 |
+ |
88 |
+ flags="${1//[!zPpEeMmRrSs]}" |
89 |
+ [[ "${flags}" ]] || return 0 |
90 |
+ shift |
91 |
+ |
92 |
+ # z = default. For XATTR_PAX, the default is no xattr field at all |
93 |
+ local dodefault="" |
94 |
+ [[ "${flags//[!z]}" ]] && dodefault="yes" |
95 |
+ |
96 |
+ if has PT ${PAX_MARKINGS}; then |
97 |
+ |
98 |
+ #First try paxctl -> this might try to create/convert program headers |
99 |
+ if type -p paxctl > /dev/null; then |
100 |
+ einfo "PT PaX marking -${flags} with paxctl" |
101 |
+ _pax_list_files einfo "$@" |
102 |
+ for f in "$@"; do |
103 |
+ # First, try modifying the existing PAX_FLAGS header |
104 |
+ paxctl -q${flags} "${f}" && continue |
105 |
+ # Second, try creating a PT_PAX header (works on ET_EXEC) |
106 |
+ # Even though this is less safe, most exes need it, eg bug #463170 |
107 |
+ paxctl -qC${flags} "${f}" && continue |
108 |
+ # Third, try stealing the (unused under PaX) PT_GNU_STACK header |
109 |
+ paxctl -qc${flags} "${f}" && continue |
110 |
+ pt_fail=1 |
111 |
+ pt_failures="${pt_failures} ${f}" |
112 |
+ done |
113 |
+ |
114 |
+ #Next try paxctl-ng -> this will not create/convert any program headers |
115 |
+ elif type -p paxctl-ng > /dev/null && paxctl-ng -L ; then |
116 |
+ einfo "PT PaX marking -${flags} with paxctl-ng" |
117 |
+ flags="${flags//z}" |
118 |
+ _pax_list_files einfo "$@" |
119 |
+ for f in "$@"; do |
120 |
+ [[ ${dodefault} == "yes" ]] && paxctl-ng -L -z "${f}" |
121 |
+ [[ "${flags}" ]] || continue |
122 |
+ paxctl-ng -L -${flags} "${f}" && continue |
123 |
+ pt_fail=1 |
124 |
+ pt_failures="${pt_failures} ${f}" |
125 |
+ done |
126 |
+ |
127 |
+ #Finally fall back on scanelf |
128 |
+ elif type -p scanelf > /dev/null && [[ ${PAX_MARKINGS} != "none" ]]; then |
129 |
+ einfo "Fallback PaX marking -${flags} with scanelf" |
130 |
+ _pax_list_files einfo "$@" |
131 |
+ scanelf -Xxz ${flags} "$@" |
132 |
+ |
133 |
+ #We failed to set PT_PAX flags |
134 |
+ elif [[ ${PAX_MARKINGS} != "none" ]]; then |
135 |
+ pt_failures="$*" |
136 |
+ pt_fail=1 |
137 |
+ fi |
138 |
+ |
139 |
+ if [[ ${pt_fail} == 1 ]]; then |
140 |
+ elog "Failed to set PT_PAX markings -${flags} for:" |
141 |
+ _pax_list_files elog ${pt_failures} |
142 |
+ ret=1 |
143 |
+ fi |
144 |
+ fi |
145 |
+ |
146 |
+ if has XT ${PAX_MARKINGS}; then |
147 |
+ |
148 |
+ flags="${flags//z}" |
149 |
+ |
150 |
+ #First try paxctl-ng |
151 |
+ if type -p paxctl-ng > /dev/null && paxctl-ng -l ; then |
152 |
+ einfo "XT PaX marking -${flags} with paxctl-ng" |
153 |
+ _pax_list_files einfo "$@" |
154 |
+ for f in "$@"; do |
155 |
+ [[ ${dodefault} == "yes" ]] && paxctl-ng -d "${f}" |
156 |
+ [[ "${flags}" ]] || continue |
157 |
+ paxctl-ng -l -${flags} "${f}" && continue |
158 |
+ xt_fail=1 |
159 |
+ xt_failures="${tx_failures} ${f}" |
160 |
+ done |
161 |
+ |
162 |
+ #Next try setfattr |
163 |
+ elif type -p setfattr > /dev/null; then |
164 |
+ [[ "${flags//[!Ee]}" ]] || flags+="e" # bug 447150 |
165 |
+ einfo "XT PaX marking -${flags} with setfattr" |
166 |
+ _pax_list_files einfo "$@" |
167 |
+ for f in "$@"; do |
168 |
+ [[ ${dodefault} == "yes" ]] && setfattr -x "user.pax.flags" "${f}" |
169 |
+ setfattr -n "user.pax.flags" -v "${flags}" "${f}" && continue |
170 |
+ xt_fail=1 |
171 |
+ xt_failures="${tx_failures} ${f}" |
172 |
+ done |
173 |
+ |
174 |
+ #We failed to set XATTR_PAX flags |
175 |
+ elif [[ ${PAX_MARKINGS} != "none" ]]; then |
176 |
+ xt_failures="$*" |
177 |
+ xt_fail=1 |
178 |
+ fi |
179 |
+ |
180 |
+ if [[ ${xt_fail} == 1 ]]; then |
181 |
+ elog "Failed to set XATTR_PAX markings -${flags} for:" |
182 |
+ _pax_list_files elog ${xt_failures} |
183 |
+ ret=1 |
184 |
+ fi |
185 |
+ fi |
186 |
+ |
187 |
+ # [[ ${ret} == 1 ]] && elog "Executables may be killed by PaX kernels." |
188 |
+ |
189 |
+ return ${ret} |
190 |
+} |
191 |
+ |
192 |
+# @FUNCTION: list-paxables |
193 |
+# @USAGE: {<files>} |
194 |
+# @RETURN: Subset of {<files>} which are ELF executables or shared objects |
195 |
+# @DESCRIPTION: |
196 |
+# Print to stdout all of the <files> that are suitable to have PaX flag |
197 |
+# markings, i.e., filter out the ELF executables or shared objects from a list |
198 |
+# of files. This is useful for passing wild-card lists to pax-mark, although |
199 |
+# in general it is preferable for ebuilds to list precisely which ELFS are to |
200 |
+# be marked. Often not all the ELF installed by a package need remarking. |
201 |
+# @EXAMPLE: |
202 |
+# pax-mark -m $(list-paxables ${S}/{,usr/}bin/*) |
203 |
+list-paxables() { |
204 |
+ file "$@" 2> /dev/null | grep -E 'ELF.*(executable|shared object)' | sed -e 's/: .*$//' |
205 |
+} |
206 |
+ |
207 |
+# @FUNCTION: host-is-pax |
208 |
+# @RETURN: Shell true if the build process is PaX enabled, shell false otherwise |
209 |
+# @DESCRIPTION: |
210 |
+# This is intended for use where the build process must be modified conditionally |
211 |
+# depending on whether the host is PaX enabled or not. It is not intedened to |
212 |
+# determine whether the final binaries need PaX markings. Note: if procfs is |
213 |
+# not mounted on /proc, this returns shell false (e.g. Gentoo/FBSD). |
214 |
+host-is-pax() { |
215 |
+ grep -qs ^PaX: /proc/self/status |
216 |
+} |
217 |
+ |
218 |
+ |
219 |
+# INTERNAL FUNCTIONS |
220 |
+# ------------------ |
221 |
+# |
222 |
+# These functions are for use internally by the eclass - do not use |
223 |
+# them elsewhere as they are not supported (i.e. they may be removed |
224 |
+# or their function may change arbitratily). |
225 |
+ |
226 |
+# Display a list of things, one per line, indented a bit, using the |
227 |
+# display command in $1. |
228 |
+_pax_list_files() { |
229 |
+ local f cmd |
230 |
+ cmd=$1 |
231 |
+ shift |
232 |
+ for f in "$@"; do |
233 |
+ ${cmd} " ${f}" |
234 |
+ done |
235 |
+} |
236 |
+ |
237 |
+fi |