Gentoo Archives: gentoo-hardened

From: Sven Vermeulen <swift@g.o>
To: gentoo-hardened@l.g.o
Subject: [gentoo-hardened] SELinux: Granting kernel_t (kdevtmpfs) manage rights on /dev/*
Date: Wed, 04 Mar 2015 20:21:12
Message-Id: 20150304202108.GA7725@gentoo.org
1 Hi all
2
3 I have a situation that I'd like to hear your opinion on.
4
5 In bug #535992 a what seems like simple problem is asking for quite some
6 work. It covers a currently cosmetic denial (i.e. SELinux is preventing
7 something but that does not seem to have any noticeable impact on the
8 system) regarding kdevtmpfs trying to work with device files.
9
10 Now you'll say - duh, that is what kdevtmpfs is for: working with the device
11 files in /dev (which is a devtmpfs mount). Exactly my thoughts. So I wanted
12 to include a policy that allows kernel_t (which is the domain that kdevtmpfs
13 works in) to manage all device nodes in /dev using the
14 dev_manage_all_dev_nodes() interface.
15
16 But here is the problem: that interface also assigns a set of attributes to
17 the (kernel_t) domain so that a number of neverallow rules are not violated.
18 Sadly, the kernel_t domain is part of the base module, meaning that it
19 cannot depend on definitions that are not part of the base module either
20 (isolation requirement). The attributes however are part of the "storage"
21 module, which is not part of base.
22
23 Simple - let's make storage part of base, right? Not that that is hard, but
24 we're in the middle of a migration between userspaces (2.3 versus 2.4) which
25 puts in some additional problems: with userspace 2.4, new policy modules are
26 loaded on priority level 400 whereas olders are at priority 100.
27
28 Now you'll say - whoah priorities? Really? What's that about?
29
30 Well, this is a new feature in the 2.4 userspace. Instead of using policy
31 module versions (which is now no longer supported in the 2.4 userspace) the
32 userspace now supports priorities. SELinux policy modules can be loaded at
33 higher priorities (and thus become active) while the lower priorities are
34 still in the SELinux store. If the higher priority module is unloaded, the
35 lower priority module becomes active again.
36
37 And this is the problem that we'll get: the older storage module (at
38 priority 100, or even at priority 400 for those using ~arch systems for a
39 while now) might still become active when we load the new policies (which no
40 longer would include the storage module). So we need to make sure that this
41 never happens, preferably by removing all modules from priority 100 to begin
42 with, and to remove the storage module when we are loading the new policies.
43
44 (╯°□°)╯︵ ┻━┻
45 -- "Screw that!"
46
47 Finally, that's a solution. And it can even be automated (the patch is
48 below), but I'm afraid that there might be situations where the automated
49 approach does not work, and we are not able to teach most Gentoo/SELinux
50 users to get at the same SELinux managing level as us SELinux-related
51 developers.
52
53 So I have the following conundrum.
54
55 1. I can temporarily ignore the issue, perhaps hiding the cosmetic denial
56 behind dontaudit statements
57 2. I can restrictively add to kernel_t those rules that do not trigger the
58 neverallow rules and ignore/dontaudit the rest
59 3. I can break isolation a bit and explicitly add kernel_t to the neverallow
60 rule exemption
61 4. I can move the necessary attributes and statements into the devices
62 module (which is part of the base)
63 5. I can move forward with the storage-becomes-base approach
64
65 Using 5 to me is the most beautiful solution, but quite intensive. The lack
66 of understanding of priorities and the entire matter might confuse users
67 currently (2.4 is too new for that).
68
69 Using 4 requires some rework which will make it harder to follow upstream
70 for the affected modules (storage and devices most likely, perhaps also kernel)
71 (as the changes involve changing existing modules, not just adding new
72 rules).
73
74 Using 3 is simpler, almost a no-brainer, but is not upstreamable (as it
75 breaks modular isolation). More for quick solutions to improve the situation
76 while working on a better solution (option 5?)
77
78 Using 2 and 1 do not really implement the solution (and thus don't resolve
79 the issue). I think that upstream will also prefer 2/1 because there is no
80 visible impact of kdevtmpfs not having all these accesses. But I personally
81 think that this is a matter of specific use cases (which we just have not
82 hit yet) and not within the expectations of the kdevtmpfs code itself.
83
84 I'll also prod upstream about the issue of course, but this I also like to
85 discuss for Gentoo in detail.
86
87 The fix for the checks on selinux-base-policy is below:
88
89
90 Index: selinux-base-policy-9999.ebuild
91 ===================================================================
92 RCS file: /var/cvsroot/gentoo-x86/sec-policy/selinux-base-policy/selinux-base-policy-9999.ebuild,v
93 retrieving revision 1.21
94 diff -u -B -r1.21 selinux-base-policy-9999.ebuild
95 --- selinux-base-policy-9999.ebuild 7 Dec 2014 13:21:06 -0000 1.21
96 +++ selinux-base-policy-9999.ebuild 4 Mar 2015 19:30:00 -0000
97 @@ -1,4 +1,4 @@
98 -# Copyright 1999-2014 Gentoo Foundation
99 +# Copyright 1999-2015 Gentoo Foundation
100 # Distributed under the terms of the GNU General Public License v2
101 # $Header: /var/cvsroot/gentoo-x86/sec-policy/selinux-base-policy/selinux-base-policy-9999.ebuild,v 1.21 2014/12/07 13:21:06 perfinion Exp $
102 EAPI="5"
103 @@ -28,7 +28,7 @@
104 PDEPEND="unconfined? ( sec-policy/selinux-unconfined )"
105 DEPEND=""
106
107 -MODS="application authlogin bootloader clock consoletype cron dmesg fstools getty hostname hotplug init iptables libraries locallogin logging lvm miscfiles modutils mount mta netutils nscd portage raid rsync selinuxutil setrans ssh staff storage su sysadm sysnetwork tmpfiles udev userdomain usermanage unprivuser xdg"
108 +MODS="application authlogin bootloader clock consoletype cron dmesg fstools getty hostname hotplug init iptables libraries locallogin logging lvm miscfiles modutils mount mta netutils nscd portage raid rsync selinuxutil setrans ssh staff su sysadm sysnetwork tmpfiles udev userdomain usermanage unprivuser xdg"
109 LICENSE="GPL-2"
110 SLOT="0"
111 S="${WORKDIR}/"
112 @@ -122,13 +122,92 @@
113 COMMAND="-i ${i}.pp ${COMMAND}"
114 done
115
116 - for i in ${POLICY_TYPES}; do
117 - einfo "Inserting the following modules, with base, into the $i module store: ${MODS}"
118 + # Check if we are using 2.4 userspace or not
119 + # Clunky check because semodule does not have a --version and we want
120 + # to check semodule's version support, not semanage or other tools.
121 + semodule --help | grep -q "priority"
122 + if [ $? -eq 0 ] ; then
123 + # Priority support found so we are using 2.4 userspace
124 + # Before continuing, check that all modules of priority=100 are gone
125 + for i in ${POLICY_TYPES} ; do
126 + semodule -s ${i} --list-modules=full | grep -q "^100 storage"
127 + if [ $? -eq 0 ] ; then
128 + # Still a storage module at priority 100 found.
129 + # Is a set already loaded at priority 400?
130 + semodule -s ${i} --list-modules=full | grep -q "^400 base"
131 + if [ $? -eq 0 ] ; then
132 + # Also a set at 400.
133 + # Let's clear those at priority 100.
134 + local CURMODLIST=$(semodule -s ${i} --priority=100 -l);
135 + ewarn "A full set of SELinux policy modules is running at priority 400 (which is good)"
136 + ewarn "but also at priority 100. The latter should be removed from the system as we"
137 + ewarn "might get into collisions (especially with the storage module). Trying to clear:"
138 + semodule -s ${i} --priority=100 -r ${CURMODLIST};
139 + if [ $? -eq 0 ] ; then
140 + # Priority 100 cleared.
141 + einfo "All modules on priority 100 have been removed. We can now continue safely."
142 + else
143 + eerror "It was not possible to remove the modules at priority 100. Please ensure that"
144 + eerror "there are no modules at this priority left. In extreme cases it might be"
145 + eerror "necessary to create an empty module to override an older one before removing"
146 + eerror "the older module."
147 + eerror "Use 'semodule --priority=100 -r modulename' to remove modules."
148 + eerror "Use 'semodule --list-modules=full' to list all modules/priority sets"
149 + die "Could not clear SELinux policy modules at priority level 100"
150 + fi
151 + else
152 + # None at priority 400 yet. We need to load the current set at priority 100 first
153 + # while removing the storage module, and then reload at priority 400,
154 + semodule -s ${i} --priority=100 -i base.pp ${COMMAND} -r storage
155 + if [ $? -ne 0 ] ; then
156 + # Failed to load at priority 100.
157 + eerror "We have detected that the storage module is loaded with priority 100 but no full"
158 + eerror "policy set yet at priority 400 (which is default for the 2.4 userspace). Recent"
159 + eerror "policies no longer contain the storage module (it has become part of the base"
160 + eerror "module) which might result in dependency problems with the currently-loaded"
161 + eerror "storage module at priority 100."
162 + eerror "Sadly we were not able to automatically resolve this. Please make sure that no"
163 + eerror "SELinux policy modules are running with priority 100 anymore."
164 + die "Could not load policies at priority 100 in order to remove the active storage module"
165 + fi
166 + fi
167 + else
168 + # No storage module at priority 100 anymore
169 + # Check if there is a storage module at priority 400.
170 + semodule -s ${i} --list-modules=full | grep -q "^400 storage"
171 + if [ $? -eq 0 ] ; then
172 + # Storage module running at priority 400
173 + # Load the new base set while removing the storage module
174 + semodule -s ${i} -i base.pp ${COMMAND} -r storage
175 + if [ $? -ne 0 ] ; then
176 + # Could not reload while removing storage module
177 + eerror "A running storage SELinux module is found but could not be removed. Recent"
178 + eerror "policies no longer contain the storage module (it has become part of the base"
179 + eerror "module) which might result in dependency problems with the currently-loaded"
180 + eerror "storage module."
181 + eerror "Sadly we were not able to automatically resolve this. Please make sure that no"
182 + eerror "SELinux policy modules are running anymore."
183 + die "Could not remove storage module from the policy store."
184 + fi
185 + fi
186 + fi
187 + # Now try to load the new set
188 + einfo "Inserting the following modules, with base, into the $i module store: ${MODS}"
189
190 - cd /usr/share/selinux/${i} || die "Could not enter /usr/share/selinux/${i}"
191 + cd /usr/share/selinux/${i} || die "Could not enter /usr/share/selinux/${i}"
192
193 - semodule -s ${i} -b base.pp ${COMMAND} || die "Failed to load in base and modules ${MODS} in the $i policy store"
194 - done
195 + semodule -s ${i} -i base.pp ${COMMAND} || die "Failed to load in base and modules \"${MODS}\" in the $i policy store"
196 + done
197 + else
198 + # No priority support so not using 2.4 userspace
199 + for i in ${POLICY_TYPES}; do
200 + einfo "Inserting the following modules, with base, into the $i module store: ${MODS}"
201 +
202 + cd /usr/share/selinux/${i} || die "Could not enter /usr/share/selinux/${i}"
203 +
204 + semodule -s ${i} -b base.pp ${COMMAND} || die "Failed to load in base and modules ${MODS} in the $i policy store"
205 + done
206 + fi
207
208 # Relabel depending packages
209 local PKGSET="";

Replies