]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/glibc/glibc-rh1025933.patch
dhcpcd: fix delay after dhcp down.
[ipfire-2.x.git] / src / patches / glibc / glibc-rh1025933.patch
CommitLineData
bb330e25
AF
1commit 0699f766b10c86912b75f35bef697106b70c1cf6
2Author: Carlos O'Donell <carlos@redhat.com>
3Date: Thu Apr 10 18:31:53 2014 -0400
4
5 nscd: Make SELinux checks dynamic.
6
7 The SELinux team has indicated to me that glibc's SELinux checks
8 in nscd are not being carried out as they would expect the API
9 to be used today. They would like to move away from static header
10 defines for class and permissions and instead use dynamic checks
11 at runtime that provide an answer which is dependent on the runtime
12 status of SELinux i.e. more dynamic.
13
14 The following patch is a minimal change that moves us forward in
15 this direction.
16
17 It does the following:
18
19 * Stop checking for SELinux headers that define NSCD__SHMEMHOST.
20 Check only for the presence or absence of the library.
21
22 * Don't encode the specific SELinux permission constants into a
23 table at build time, and instead use the symbolic name for the
24 permission as expected.
25
26 * Lookup the "What do we do if we don't know this permission?"
27 policy and use that if we find SELinux's policy is older than
28 the glibc policy e.g. we make a request for a permission that
29 SELinux doesn't know about.
30
31 * Lastly, translate the class and permission and then make
32 the permission check. This is done every time we lookup
33 a permission, and this is the expected way to use the API.
34 SELinux will optimize this for us, and we expect the network
35 latencies to hide these extra library calls.
36
37 Tested on x86, x86-64, and via Fedora Rawhide since November 2013.
38
39 See:
40 https://sourceware.org/ml/libc-alpha/2014-04/msg00179.html
41
42diff --git a/configure b/configure
43index abefcdb..8b0b222 100755
44--- a/configure
45+++ b/configure
46@@ -7774,64 +7774,10 @@ else
47 have_selinux=no
48 fi
49
50- # See if we have the SELinux header with the NSCD permissions in it.
51- if test x$have_selinux = xyes ; then
52- { $as_echo "$as_me:$LINENO: checking for NSCD Flask permissions in selinux/av_permissions.h" >&5
53-$as_echo_n "checking for NSCD Flask permissions in selinux/av_permissions.h... " >&6; }
54- cat >conftest.$ac_ext <<_ACEOF
55-/* confdefs.h. */
56-_ACEOF
57-cat confdefs.h >>conftest.$ac_ext
58-cat >>conftest.$ac_ext <<_ACEOF
59-/* end confdefs.h. */
60-#include <selinux/av_permissions.h>
61-int
62-main ()
63-{
64-#ifdef NSCD__SHMEMHOST
65- return 0;
66- #else
67- #error NSCD__SHMEMHOST not defined
68- #endif
69- ;
70- return 0;
71-}
72-_ACEOF
73-rm -f conftest.$ac_objext
74-if { (ac_try="$ac_compile"
75-case "(($ac_try" in
76- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
77- *) ac_try_echo=$ac_try;;
78-esac
79-eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
80-$as_echo "$ac_try_echo") >&5
81- (eval "$ac_compile") 2>conftest.er1
82- ac_status=$?
83- grep -v '^ *+' conftest.er1 >conftest.err
84- rm -f conftest.er1
85- cat conftest.err >&5
86- $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
87- (exit $ac_status); } && {
88- test -z "$ac_c_werror_flag" ||
89- test ! -s conftest.err
90- } && test -s conftest.$ac_objext; then
91- have_selinux=yes
92-else
93- $as_echo "$as_me: failed program was:" >&5
94-sed 's/^/| /' conftest.$ac_ext >&5
95-
96- have_selinux=no
97-fi
98-
99-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
100- { $as_echo "$as_me:$LINENO: result: $have_selinux" >&5
101-$as_echo "$have_selinux" >&6; }
102- fi
103-
104 if test x$with_selinux = xyes ; then
105 if test x$have_selinux = xno ; then
106- { { $as_echo "$as_me:$LINENO: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&5
107-$as_echo "$as_me: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&2;}
108+ { { $as_echo "$as_me:$LINENO: error: SELinux explicitly required, but SELinux library not found" >&5
109+$as_echo "$as_me: error: SELinux explicitly required, but SELinux library not found" >&2;}
110 { (exit 1); exit 1; }; }
111 fi
112 fi
113diff --git a/configure.in b/configure.in
114index 6291872..97a9591 100644
115--- a/configure.in
116+++ b/configure.in
117@@ -1945,22 +1945,9 @@ else
118 # See if we have the SELinux library
119 AC_CHECK_LIB(selinux, is_selinux_enabled,
120 have_selinux=yes, have_selinux=no)
121- # See if we have the SELinux header with the NSCD permissions in it.
122- if test x$have_selinux = xyes ; then
123- AC_MSG_CHECKING([for NSCD Flask permissions in selinux/av_permissions.h])
124- AC_TRY_COMPILE([#include <selinux/av_permissions.h>],
125- [#ifdef NSCD__SHMEMHOST
126- return 0;
127- #else
128- #error NSCD__SHMEMHOST not defined
129- #endif],
130- have_selinux=yes, have_selinux=no)
131- AC_MSG_RESULT($have_selinux)
132- fi
133-
134 if test x$with_selinux = xyes ; then
135 if test x$have_selinux = xno ; then
136- AC_MSG_ERROR([SELinux explicitly required, but sufficiently recent SELinux library not found])
137+ AC_MSG_ERROR([SELinux explicitly required, but SELinux library not found])
138 fi
139 fi
140 fi
141diff --git a/nscd/selinux.c b/nscd/selinux.c
142index 46b0ea9..9a8a5a8 100644
143--- a/nscd/selinux.c
144+++ b/nscd/selinux.c
145@@ -28,7 +28,6 @@
146 #include <syslog.h>
147 #include <unistd.h>
148 #include <sys/prctl.h>
149-#include <selinux/av_permissions.h>
150 #include <selinux/avc.h>
151 #include <selinux/flask.h>
152 #include <selinux/selinux.h>
153@@ -44,35 +43,31 @@
154 /* Global variable to tell if the kernel has SELinux support. */
155 int selinux_enabled;
156
157-/* Define mappings of access vector permissions to request types. */
158-static const access_vector_t perms[LASTREQ] =
159+/* Define mappings of request type to AVC permission name. */
160+static const char *perms[LASTREQ] =
161 {
162- [GETPWBYNAME] = NSCD__GETPWD,
163- [GETPWBYUID] = NSCD__GETPWD,
164- [GETGRBYNAME] = NSCD__GETGRP,
165- [GETGRBYGID] = NSCD__GETGRP,
166- [GETHOSTBYNAME] = NSCD__GETHOST,
167- [GETHOSTBYNAMEv6] = NSCD__GETHOST,
168- [GETHOSTBYADDR] = NSCD__GETHOST,
169- [GETHOSTBYADDRv6] = NSCD__GETHOST,
170- [GETSTAT] = NSCD__GETSTAT,
171- [SHUTDOWN] = NSCD__ADMIN,
172- [INVALIDATE] = NSCD__ADMIN,
173- [GETFDPW] = NSCD__SHMEMPWD,
174- [GETFDGR] = NSCD__SHMEMGRP,
175- [GETFDHST] = NSCD__SHMEMHOST,
176- [GETAI] = NSCD__GETHOST,
177- [INITGROUPS] = NSCD__GETGRP,
178-#ifdef NSCD__GETSERV
179- [GETSERVBYNAME] = NSCD__GETSERV,
180- [GETSERVBYPORT] = NSCD__GETSERV,
181- [GETFDSERV] = NSCD__SHMEMSERV,
182-#endif
183-#ifdef NSCD__GETNETGRP
184- [GETNETGRENT] = NSCD__GETNETGRP,
185- [INNETGR] = NSCD__GETNETGRP,
186- [GETFDNETGR] = NSCD__SHMEMNETGRP,
187-#endif
188+ [GETPWBYNAME] = "getpwd",
189+ [GETPWBYUID] = "getpwd",
190+ [GETGRBYNAME] = "getgrp",
191+ [GETGRBYGID] = "getgrp",
192+ [GETHOSTBYNAME] = "gethost",
193+ [GETHOSTBYNAMEv6] = "gethost",
194+ [GETHOSTBYADDR] = "gethost",
195+ [GETHOSTBYADDRv6] = "gethost",
196+ [SHUTDOWN] = "admin",
197+ [GETSTAT] = "getstat",
198+ [INVALIDATE] = "admin",
199+ [GETFDPW] = "shmempwd",
200+ [GETFDGR] = "shmemgrp",
201+ [GETFDHST] = "shmemhost",
202+ [GETAI] = "gethost",
203+ [INITGROUPS] = "getgrp",
204+ [GETSERVBYNAME] = "getserv",
205+ [GETSERVBYPORT] = "getserv",
206+ [GETFDSERV] = "shmemserv",
207+ [GETNETGRENT] = "getnetgrp",
208+ [INNETGR] = "getnetgrp",
209+ [GETFDNETGR] = "shmemnetgrp",
210 };
211
212 /* Store an entry ref to speed AVC decisions. */
213@@ -344,7 +339,16 @@ nscd_avc_init (void)
214
215
216 /* Check the permission from the caller (via getpeercon) to nscd.
217- Returns 0 if access is allowed, 1 if denied, and -1 on error. */
218+ Returns 0 if access is allowed, 1 if denied, and -1 on error.
219+
220+ The SELinux policy, enablement, and permission bits are all dynamic and the
221+ caching done by glibc is not entirely correct. This nscd support should be
222+ rewritten to use selinux_check_permission. A rewrite is risky though and
223+ requires some refactoring. Currently we use symbolic mappings instead of
224+ compile time constants (which SELinux upstream says are going away), and we
225+ use security_deny_unknown to determine what to do if selinux-policy* doesn't
226+ have a definition for the the permission or object class we are looking
227+ up. */
228 int
229 nscd_request_avc_has_perm (int fd, request_type req)
230 {
231@@ -354,6 +358,33 @@ nscd_request_avc_has_perm (int fd, request_type req)
232 security_id_t ssid = NULL;
233 security_id_t tsid = NULL;
234 int rc = -1;
235+ security_class_t sc_nscd;
236+ access_vector_t perm;
237+ int avc_deny_unknown;
238+
239+ /* Check if SELinux denys or allows unknown object classes
240+ and permissions. It is 0 if they are allowed, 1 if they
241+ are not allowed and -1 on error. */
242+ if ((avc_deny_unknown = security_deny_unknown ()) == -1)
243+ dbg_log (_("Error querying policy for undefined object classes "
244+ "or permissions."));
245+
246+ /* Get the security class for nscd. If this fails we will likely be
247+ unable to do anything unless avc_deny_unknown is 0. */
248+ sc_nscd = string_to_security_class ("nscd");
249+ if (perm == 0 && avc_deny_unknown == 1)
250+ dbg_log (_("Error getting security class for nscd."));
251+
252+ /* Convert permission to AVC bits. */
253+ perm = string_to_av_perm (sc_nscd, perms[req]);
254+ if (perm == 0 && avc_deny_unknown == 1)
255+ dbg_log (_("Error translating permission name "
256+ "\"%s\" to access vector bit."), perms[req]);
257+
258+ /* If the nscd security class was not found or perms were not
259+ found and AVC does not deny unknown values then allow it. */
260+ if ((sc_nscd == 0 || perm == 0) && avc_deny_unknown == 0)
261+ return 0;
262
263 if (getpeercon (fd, &scon) < 0)
264 {
265@@ -372,15 +403,13 @@ nscd_request_avc_has_perm (int fd, request_type req)
266 goto out;
267 }
268
269-#ifndef NSCD__GETSERV
270- if (perms[req] == 0)
271- {
272- dbg_log (_("compile-time support for database policy missing"));
273- goto out;
274- }
275-#endif
276-
277- rc = avc_has_perm (ssid, tsid, SECCLASS_NSCD, perms[req], &aeref, NULL) < 0;
278+ /* The SELinux API for avc_has_perm conflates access denied and error into
279+ the return code -1, while nscd_request_avs_has_perm has distinct error
280+ (-1) and denied (1) return codes. We map the avc_has_perm access denied or
281+ error into an access denied at the nscd interface level (we do accurately
282+ report error for the getpeercon, getcon, and avc_context_to_sid interfaces
283+ used above). */
284+ rc = avc_has_perm (ssid, tsid, sc_nscd, perm, &aeref, NULL) < 0;
285
286 out:
287 if (scon)