/[gentoo-x86]/eclass/pax-utils.eclass
Gentoo

Diff of /eclass/pax-utils.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.1 Revision 1.7
1# Copyright 1999-2006 Gentoo Foundation 1# Copyright 1999-2006 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/pax-utils.eclass,v 1.1 2006/01/22 14:18:48 kevquinn Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/pax-utils.eclass,v 1.7 2007/05/07 09:24:16 kevquinn Exp $
4 4
5# Author: 5# Author:
6# Kevin F. Quinn <kevquinn@gentoo.org> 6# Kevin F. Quinn <kevquinn@gentoo.org>
7# 7#
8# This eclass provides support for manipulating PaX markings on ELF 8# This eclass provides support for manipulating PaX markings on ELF
9# binaries, wrapping the use of the chpax and paxctl utilities. 9# binaries, wrapping the use of the chpaxi, paxctl and scanelf utilities.
10# Currently it decides which to use depending on what is installed on the
11# build host; this may change in the future to use a control variable
12# (which would also mean modifying DEPEND to bring in sys-apps/paxctl etc).
13#
14#
15# CONTROL
16# -------
17#
18# To control what markings are set, assign PAX_MARKINGS in
19# /etc/make.conf to contain the strings "EI" and/or "PT".
20# If EI is present in PAX_MARKINGS (and the chpax utility
21# is present), the legacy 'chpax' style markings will be
22# set. If PT is present in PAX_MARKINGS (and the paxctl
23# utility is present), the 'paxctl' markings will be set.
24# Default is to try to do both. Set it to "NONE" to prevent
25# any markings being made.
26#
27#
28# PROVIDED FUNCTIONS
29# ------------------
30#
31#### pax-mark <flags> {<ELF files>}
32# Marks files <files> with provided PaX flags <flags>
33#
34# Please confirm any relaxation of restrictions with the
35# Gentoo Hardened team; either ask on the gentoo-hardened
36# mailing list, or CC/assign hardened@g.o on a bug.
37#
38# Flags are passed directly to the utilities unchanged. Possible
39# flags at the time of writing, taken from /sbin/paxctl, are:
40#
41# p: disable PAGEEXEC P: enable PAGEEXEC
42# e: disable EMUTRMAP E: enable EMUTRMAP
43# m: disable MPROTECT M: enable MPROTECT
44# r: disable RANDMMAP R: enable RANDMMAP
45# s: disable SEGMEXEC S: enable SEGMEXEC
46#
47# Default flags are 'PeMRS', which are the most restrictive
48# settings. Refer to http://pax.grsecurity.net/ for details
49# on what these flags are all about. There is an obsolete
50# flag 'x'/'X' which has been removed from PaX.
51#
52# If chpax is not installed, the legacy EI flags (which are
53# not strip-safe, and strictly speaking violate the ELF spec)
54# will not be set. If paxctl is not installed, it falls back
55# to scanelf. scanelf is always present, but currently doesn't
56# quite do all that paxctl can do.
57# Returns fail if one or more files could not be marked.
58#
59#
60#### list-paxables {<files>}
61# Prints to stdout all of <files> that are suitable to having PaX
62# flags (i.e. filter to just ELF files). Useful for passing wild-card
63# lists of files to pax-mark, although in general it is preferable
64# for ebuilds to list precisely which executables are to be marked.
65# Use like:
66# pax-mark -m $(list-paxables ${S}/{,usr/}bin/*)
67#
68#
69#### host-is-pax
70# Returns true if the host has a PaX-enabled kernel, false otherwise.
71# Intended for use where the build process must be modified conditionally
72# in order to satisfy PaX. Note; it is _not_ intended to indicate
73# whether the final executables should satisfy PaX - executables should
74# always be marked appropriately even if they're only going to be
75# installed on a non-PaX system.
10 76
11inherit eutils 77inherit eutils
12 78
13##### pax-mark #### 79# Default to both EI and PT markings.
14# Mark a file for PaX with the given flags. 80PAX_MARKINGS=${PAX_MARKINGS:="EI PT"}
15# Tries chpax (EI_FLAGS) and paxctl (PT_FLAGS) if they are installed. 81
16# If neither are installed, returns 0 (i.e. has no effect on non-PaX 82# pax-mark <flags> {<ELF files>}
17# systems unless the owner has installed chpax and/or paxctl). 83pax-mark() {
18# Deliberately does _not_ check whether the build system is PaX or not. 84 local f flags fail=0 failures="" zero_load_alignment
85 # Ignore '-' characters - in particular so that it doesn't matter if
86 # the caller prefixes with -
87 flags=${1//-}
88 shift
89 # Try chpax, for (deprecated) EI legacy marking.
90 if type -p chpax > /dev/null && hasq EI ${PAX_MARKINGS}; then
91 elog "Legacy EI PaX marking -${flags}"
92 _pax_list_files elog "$@"
93 for f in "$@"; do
94 chpax -${flags} "${f}" && continue
95 fail=1
96 failures="${failures} ${f}"
97 done
98 fi
99 # Try paxctl, then scanelf - paxctl takes precedence
100 # over scanelf.
101 if type -p paxctl > /dev/null && hasq PT ${PAX_MARKINGS}; then
102 # Try paxctl, the upstream supported tool.
103 elog "PT PaX marking -${flags}"
104 _pax_list_files elog "$@"
105 for f in "$@"; do
106 # First, try modifying the existing PAX_FLAGS header
107 paxctl -q${flags} "${f}" && continue
108 # Second, try stealing the (unused under PaX) PT_GNU_STACK header
109 paxctl -qc${flags} "${f}" && continue
110 # Third, try pulling the base down a page, to create space and
111 # insert a PT_GNU_STACK header (works on ET_EXEC)
112 paxctl -qC${flags} "${f}" && continue
113 # Fourth - check if it loads to 0 (probably an ET_DYN) and if so,
114 # try rebasing with prelink first to give paxctl some space to
115 # grow downwards into.
116 if type -p objdump > /dev/null && type -p prelink > /dev/null; then
117 zero_load_alignment=$(objdump -p "${f}" | \
118 grep -E '^[[:space:]]*LOAD[[:space:]]*off[[:space:]]*0x0+[[:space:]]' | \
119 sed -e 's/.*align\(.*\)/\1/')
120 if [[ ${zero_load_alignment} != "" ]]; then
121 prelink -r $(( 2*(${zero_load_alignment}) )) &&
122 paxctl -qC${flags} "${f}" && continue
123 fi
124 fi
125 fail=1
126 failures="${failures} ${f}"
127 done
128 elif type -p scanelf > /dev/null && [[ ${PAX_MARKINGS} != "none" ]]; then
129 # Try scanelf, the Gentoo swiss-army knife ELF utility
130 # Currently this sets EI and PT if it can, no option to
131 # control what it does.
132 elog "Fallback PaX marking -${flags}"
133 _pax_list_files elog "$@"
134 scanelf -Xxz ${flags} "$@"
135 elif [[ ${PAX_MARKINGS} != "none" ]]; then
136 # Out of options!
137 failures="$*"
138 fail=1
139 fi
140 if [[ ${fail} == 1 ]]; then
141 ewarn "Failed to set PaX markings -${flags} for:"
142 _pax_list_files ewarn ${failures}
143 ewarn "Executables may be killed by PaX kernels."
144 fi
145 return ${fail}
146}
147
148# list-paxables {<files>}
149list-paxables() {
150 file "$@" 2> /dev/null | grep -E 'ELF.*(executable|shared object)' | sed -e 's/: .*$//'
151}
152
153# host-is-pax
154# Note: if procfs is not on /proc, this returns False (e.g. Gentoo/FBSD).
155host-is-pax() {
156 grep -qs ^PaX: /proc/self/status
157}
158
159
160# INTERNAL FUNCTIONS
161# ------------------
19# 162#
20# Syntax: 163# These functions are for use internally by the eclass - do not use
21# pax-mark [-q] {<flags>} [{<files>}] 164# them elsewhere as they are not supported (i.e. they may be removed
22# 165# or their function may change arbitratily).
23# -q: do things quietly (no einfo/ewarn)
24#
25# There must be at least one <flags>, and can include:
26# -execstack equivalent to -E
27# -execheap equivalent to -m
28# -unrestricted equivalent to -psmxer
29# -{[pPsSmMxXeErR]} as used direcly by chpax/paxctl
30#
31# Where more than one flag is given they are concatenated.
32#
33# {<files>} may be empty, so it's safe to use for example the results
34# of a find that may not return any results.
35#
36# Return codes:
37# 0: for all files, all installed utilities succeed.
38# 1: No flags specified
39# >1: bit 2 => chpax failed, bit 3 => paxctl failed
40 166
41pax-mark() { 167# Display a list of things, one per line, indented a bit, using the
42 local flags ret quiet 168# display command in $1.
43 # Fail if no parameters at all (especially no flags) 169_pax_list_files() {
44 [[ -z $1 ]] && return 1 170 local f cmd
45 flags= 171 cmd=$1
46 ret=0
47 quiet=
48 while [[ ${1:0:1} == "-" ]]; do
49 case ${1} in
50 -execstack)
51 flags="${flags}E"
52 ;;
53 -execheap)
54 flags="${flags}m"
55 ;;
56 -unrestricted)
57 flags="${flags}psmxer"
58 ;;
59 -q)
60 quiet="/bin/false "
61 ;;
62 *)
63 flags="${flags}${1:1}"
64 ;;
65 esac
66 shift 172 shift
173 for f in "$@"; do
174 ${cmd} " ${f}"
67 done 175 done
68 # Fail if no flags given
69 [[ -z ${flags} ]] && return 1
70 # Quietly exit if no files given
71 [[ -z $1 ]] && return 0
72 if [[ -x /sbin/chpax ]]; then
73 if /sbin/chpax -${flags} $*; then
74 ${quiet} einfo "PaX EI flags set to ${flags} on $*"
75 else
76 ${quiet} ewarn "Failed to set EI flags to ${flags} on $*"
77 (( ret=${ret}|2 ))
78 fi
79 fi
80 if [[ -x /sbin/paxctl ]]; then
81 # Steal PT_GNU_STACK if paxctl supports it
82 /sbin/paxctl -v 2>&1 | grep PT_GNU_STACK > /dev/null && \
83 flags="c${flags}"
84 if /sbin/paxctl -${flags} $*; then
85 ${quiet} einfo "PaX PT flags set to ${flags} on $*"
86 else
87 ${quiet} ewarn "Failed to set PT flags to ${flags} on $*"
88 (( ret=${ret}|4))
89 fi
90 fi
91 return ${ret}
92} 176}
177

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.7

  ViewVC Help
Powered by ViewVC 1.1.20