summaryrefslogtreecommitdiff
blob: 216b89aa13beffa03941bd975b902d0e086cd648 (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
# Copyright 1999-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/pax-utils.eclass,v 1.15 2011/08/22 04:46:32 vapier Exp $

# @ECLASS: pax-utils.eclass
# @MAINTAINER:
# The Gentoo Linux Hardened Team <hardened@gentoo.org>
# @AUTHOR:
# Original Author: Kevin F. Quinn <kevquinn@gentoo.org>
# Modifications for bug #365825, @ ECLASS markup: Anthony G. Basile <blueness@gentoo.org>
# Modifications for XT_PAX markings: Anthony G. Basile <blueness@gentoo.org>
# @BLURB: functions to provide pax markings
# @DESCRIPTION:
# This eclass provides support for manipulating PaX markings on ELF binaries,
# wrapping the use of the paxctl-ng utilities.
#
# To control what markings are made, set PAX_MARKINGS in /etc/make.conf to
# contain either "XT", "PT" or "none".
#
# If PAX_MARKINGS is set to "XT" and paxctl-ng is installed, then both XT_PAX
# and PT_PAX markings will be made, where possible: XT_PAX will not be made if
# the file system doesn't support extended attributes and PT_PAX will not be
# made if the ELF binary doesn't have a PT_PAX header.
#
# If PAX_MARKINGS is setto "PT" and paxctl is installed, then only PT_PAX
# markings will be made.
#
# Finally, if neither utility is found, or PAX_MARKINGS is set to "none",
# then no markings will be made.
#
# Note: unlike the original pax-utils.eclass, we will not try to use paxctl -c
# or paxctl -C to convert or create a PT_PAX program header.  Nor will we fall
# back on scanelf.

inherit eutils

RDEPEND="=sys-apps/elfix-0.3.2"

# Default to XT markings.
PAX_MARKINGS=${PAX_MARKINGS:="XT"}

# @FUNCTION: pax-mark
# @USAGE: <flags> {<ELF files>}
# @RETURN: Shell true if we succeed, shell false otherwise
# @DESCRIPTION:
# Marks <ELF files> with provided PaX <flags>
#
# Flags are passed directly to the utilities unchanged.  Possible flags at the
# time of writing, taken from /usr/sbin/paxctl-ng, are:
#
#	p: disable PAGEEXEC		P: enable PAGEEXEC
#	e: disable EMUTRMAP		E: enable EMUTRMAP
#	m: disable MPROTECT		M: enable MPROTECT
#	r: disable RANDMMAP		R: enable RANDMMAP
#	s: disable SEGMEXEC		S: enable SEGMEXEC
#
# Default flags are 'PeMRS', which are the most restrictive settings.
# Do not use the obsolete flag 'x'/'X'.
pax-mark() {
	local f flags fail=0 failures="" zero_load_alignment
	# Remove all dashes from the flags
	flags=${1//-}
	shift
	if type -p paxctl-ng > /dev/null && has XT ${PAX_MARKINGS}; then
		elog "XT PaX marking -${flags}"
		_pax_list_files elog "$@"
		for f in "$@"; do
			paxctl-ng -C "${f}"
			paxctl-ng -${flags} "${f}" && continue
			fail=1
			failures="${failures} ${f}"
		done
	elif type -p paxctl > /dev/null && has PT ${PAX_MARKINGS}; then
		elog "PT PaX marking -${flags}"
		_pax_list_files elog "$@"
		for f in "$@"; do
			paxctl -q${flags} "${f}" && continue
			fail=1
			failures="${failures} ${f}"
		done
	elif [[ ${PAX_MARKINGS} != "none" ]]; then
		failures="$*"
		fail=1
	fi
	if [[ ${fail} == 1 ]]; then
		ewarn "Failed to set PaX markings -${flags} for:"
		_pax_list_files ewarn ${failures}
		ewarn "Executables may be killed by PaX kernels."
	fi
	return ${fail}
}

# @FUNCTION: list-paxables
# @USAGE: {<files>}
# @RETURN: Subset of {<files>} which are ELF executables or shared objects
# @DESCRIPTION:
# Print to stdout all of the <files> that are suitable to have PaX flag
# markings, i.e., filter out the ELF executables or shared objects from a list
# of files.  This is useful for passing wild-card lists to pax-mark, although
# in general it is preferable for ebuilds to list precisely which ELFS are to
# be marked.  Often not all the ELF installed by a package need remarking.
# @EXAMPLE:
# pax-mark -m $(list-paxables ${S}/{,usr/}bin/*)
list-paxables() {
	file "$@" 2> /dev/null | grep -E 'ELF.*(executable|shared object)' | sed -e 's/: .*$//'
}

# @FUNCTION: host-is-pax
# @RETURN: Shell true if the build process is PaX enabled, shell false otherwise
# @DESCRIPTION:
# This is intended for use where the build process must be modified conditionally
# depending on whether the host is PaX enabled or not.  It is not intedened to
# determine whether the final binaries need PaX markings.  Note: if procfs is
# not mounted on /proc, this returns shell false (e.g. Gentoo/FBSD).
host-is-pax() {
	grep -qs ^PaX: /proc/self/status
}


# INTERNAL FUNCTIONS
# ------------------
#
# These functions are for use internally by the eclass - do not use
# them elsewhere as they are not supported (i.e. they may be removed
# or their function may change arbitratily).

# Display a list of things, one per line, indented a bit, using the
# display command in $1.
_pax_list_files() {
	local f cmd
	cmd=$1
	shift
	for f in "$@"; do
		${cmd} "     ${f}"
	done
}