1 |
ssuominen 12/09/29 17:17:14 |
2 |
|
3 |
Added: glib-2.32.4-CVE-2012-3524.patch |
4 |
Log: |
5 |
Revision bump to import upstream patch for CVE-2012-3524 wrt #436028 |
6 |
|
7 |
(Portage version: 2.2.0_alpha128/cvs/Linux x86_64) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 dev-libs/glib/files/glib-2.32.4-CVE-2012-3524.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/glib/files/glib-2.32.4-CVE-2012-3524.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-libs/glib/files/glib-2.32.4-CVE-2012-3524.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: glib-2.32.4-CVE-2012-3524.patch |
16 |
=================================================================== |
17 |
From 4c2928a54482913cf236bff0e66650a8f47e17ea Mon Sep 17 00:00:00 2001 |
18 |
From: Colin Walters <walters@××××××.org> |
19 |
Date: Wed, 22 Aug 2012 18:26:11 +0000 |
20 |
Subject: CVE-2012-3524: Hardening for being run in a setuid environment |
21 |
|
22 |
Some programs attempt to use libglib (or even libgio) when setuid. |
23 |
For a long time, GTK+ simply aborted if launched in this |
24 |
configuration, but we never had a real policy for GLib. |
25 |
|
26 |
I'm not sure whether we should advertise such support. However, given |
27 |
that there are real-world programs that do this currently, we can make |
28 |
them safer with not too much effort. |
29 |
|
30 |
Better to fix a problem caused by an interaction between two |
31 |
components in *both* places if possible. |
32 |
|
33 |
This patch adds a private function g_check_setuid() which is used to |
34 |
first ensure we don't run an external dbus-launch binary if |
35 |
DBUS_SESSION_BUS_ADDRESS isn't set. |
36 |
|
37 |
Second, we also ensure the local VFS is used in this case. The |
38 |
gdaemonvfs extension point will end up talking to the session bus |
39 |
which is typically undesirable in a setuid context. |
40 |
|
41 |
Implementing g_check_setuid() is interesting - whether or not we're |
42 |
running in a privilege-escalated path is operating system specific. |
43 |
Note that GTK+'s code to check euid versus uid worked historically on |
44 |
Unix, more modern systems have filesystem capabilities and SELinux |
45 |
domain transitions, neither of which are captured by the uid |
46 |
comparison. |
47 |
|
48 |
On Linux/glibc, the way this works is that the kernel sets an |
49 |
AT_SECURE flag in the ELF auxiliary vector, and glibc looks for it on |
50 |
startup. If found, then glibc sets a public-but-undocumented |
51 |
__libc_enable_secure variable which we can use. Unfortunately, while |
52 |
it *previously* worked to check this variable, a combination of newer |
53 |
binutils and RPM break it: |
54 |
http://www.openwall.com/lists/owl-dev/2012/08/14/1 |
55 |
|
56 |
So for now on Linux/glibc, we fall back to the historical Unix version |
57 |
until we get glibc fixed. |
58 |
|
59 |
On some BSD variants, there is a issetugid() function. On other Unix |
60 |
variants, we fall back to what GTK+ has been doing. |
61 |
|
62 |
Reported-By: Sebastian Krahmer <krahmer@××××.de> |
63 |
Signed-off-by: Colin Walters <walters@××××××.org> |
64 |
--- |
65 |
diff --git a/configure.ac b/configure.ac |
66 |
index 584df1d..67ea1a9 100644 |
67 |
--- a/configure.ac |
68 |
+++ b/configure.ac |
69 |
@@ -583,9 +583,20 @@ AC_TRY_COMPILE([#include <dirent.h>], [DIR *dir;], |
70 |
# Checks for library functions. |
71 |
AC_FUNC_VPRINTF |
72 |
AC_FUNC_ALLOCA |
73 |
-AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2) |
74 |
+AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2 issetugid) |
75 |
AC_CHECK_FUNCS(atexit on_exit timegm gmtime_r) |
76 |
|
77 |
+AC_CACHE_CHECK([for __libc_enable_secure], glib_cv_have_libc_enable_secure, |
78 |
+ [AC_TRY_LINK([#include <unistd.h> |
79 |
+ extern int __libc_enable_secure;], |
80 |
+ [return __libc_enable_secure;], |
81 |
+ glib_cv_have_libc_enable_secure=yes, |
82 |
+ glib_cv_have_libc_enable_secure=no)]) |
83 |
+AS_IF([test x$glib_cv_have_libc_enable_secure = xyes], [ |
84 |
+ AC_DEFINE(HAVE_LIBC_ENABLE_SECURE, 1, |
85 |
+ [Define if you have the __libc_enable_secure variable (GNU libc, eglibc)]) |
86 |
+]) |
87 |
+ |
88 |
AC_CHECK_SIZEOF(char) |
89 |
AC_CHECK_SIZEOF(short) |
90 |
AC_CHECK_SIZEOF(long) |
91 |
@@ -984,7 +995,7 @@ AC_MSG_RESULT(unsigned $glib_size_type) |
92 |
|
93 |
# Check for some functions |
94 |
AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk memmem) |
95 |
-AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid) |
96 |
+AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid getresuid) |
97 |
AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getfsstat getvfsstat) |
98 |
# Check for high-resolution sleep functions |
99 |
AC_CHECK_FUNCS(splice) |
100 |
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c |
101 |
index 4aa13b9..96b6343 100644 |
102 |
--- a/gio/gdbusaddress.c |
103 |
+++ b/gio/gdbusaddress.c |
104 |
@@ -37,6 +37,7 @@ |
105 |
#include "giostream.h" |
106 |
#include "gasyncresult.h" |
107 |
#include "gsimpleasyncresult.h" |
108 |
+#include "glib-private.h" |
109 |
#include "gdbusprivate.h" |
110 |
#include "giomodule-priv.h" |
111 |
#include "gdbusdaemon.h" |
112 |
@@ -1023,6 +1024,14 @@ get_session_address_dbus_launch (GError **error) |
113 |
restore_dbus_verbose = FALSE; |
114 |
old_dbus_verbose = NULL; |
115 |
|
116 |
+ /* Don't run binaries as root if we're setuid. */ |
117 |
+ if (GLIB_PRIVATE_CALL (g_check_setuid) ()) |
118 |
+ { |
119 |
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, |
120 |
+ _("Cannot spawn a message bus when setuid")); |
121 |
+ goto out; |
122 |
+ } |
123 |
+ |
124 |
machine_id = _g_dbus_get_machine_id (error); |
125 |
if (machine_id == NULL) |
126 |
{ |
127 |
diff --git a/gio/gvfs.c b/gio/gvfs.c |
128 |
index dda8afb..9afbcec 100644 |
129 |
--- a/gio/gvfs.c |
130 |
+++ b/gio/gvfs.c |
131 |
@@ -23,6 +23,7 @@ |
132 |
#include "config.h" |
133 |
#include <string.h> |
134 |
#include "gvfs.h" |
135 |
+#include "glib-private.h" |
136 |
#include "glocalvfs.h" |
137 |
#include "gresourcefile.h" |
138 |
#include "giomodule-priv.h" |
139 |
@@ -191,6 +192,8 @@ g_vfs_parse_name (GVfs *vfs, |
140 |
GVfs * |
141 |
g_vfs_get_default (void) |
142 |
{ |
143 |
+ if (GLIB_PRIVATE_CALL (g_check_setuid) ()) |
144 |
+ return g_vfs_get_local (); |
145 |
return _g_io_module_get_default (G_VFS_EXTENSION_POINT_NAME, |
146 |
"GIO_USE_VFS", |
147 |
(GIOModuleVerifyFunc)g_vfs_is_active); |
148 |
diff --git a/glib/genviron.c b/glib/genviron.c |
149 |
index 59a8bbe..9525cf0 100644 |
150 |
--- a/glib/genviron.c |
151 |
+++ b/glib/genviron.c |
152 |
@@ -40,6 +40,7 @@ |
153 |
#include <windows.h> |
154 |
#endif |
155 |
|
156 |
+#include "glib-private.h" |
157 |
#include "gmem.h" |
158 |
#include "gmessages.h" |
159 |
#include "gstrfuncs.h" |
160 |
diff --git a/glib/glib-private.c b/glib/glib-private.c |
161 |
index 3946e77..3506782 100644 |
162 |
--- a/glib/glib-private.c |
163 |
+++ b/glib/glib-private.c |
164 |
@@ -38,7 +38,9 @@ glib__private__ (void) |
165 |
g_wakeup_signal, |
166 |
g_wakeup_acknowledge, |
167 |
|
168 |
- g_get_worker_context |
169 |
+ g_get_worker_context, |
170 |
+ |
171 |
+ g_check_setuid |
172 |
}; |
173 |
|
174 |
return &table; |
175 |
diff --git a/glib/glib-private.h b/glib/glib-private.h |
176 |
index fde0be8..87da6f3 100644 |
177 |
--- a/glib/glib-private.h |
178 |
+++ b/glib/glib-private.h |
179 |
@@ -25,6 +25,8 @@ |
180 |
|
181 |
G_GNUC_INTERNAL |
182 |
GMainContext * g_get_worker_context (void); |
183 |
+G_GNUC_INTERNAL |
184 |
+gboolean g_check_setuid (void); |
185 |
|
186 |
#define GLIB_PRIVATE_CALL(symbol) (glib__private__()->symbol) |
187 |
|
188 |
@@ -40,6 +42,8 @@ typedef struct { |
189 |
/* See gmain.c */ |
190 |
GMainContext * (* g_get_worker_context) (void); |
191 |
/* Add other private functions here, initialize them in glib-private.c */ |
192 |
+ |
193 |
+ gboolean (* g_check_setuid) (void); |
194 |
} GLibPrivateVTable; |
195 |
|
196 |
GLibPrivateVTable *glib__private__ (void); |
197 |
diff --git a/glib/gutils.c b/glib/gutils.c |
198 |
index 38b5e44..f8a38d1 100644 |
199 |
--- a/glib/gutils.c |
200 |
+++ b/glib/gutils.c |
201 |
@@ -2409,3 +2409,60 @@ g_get_tmp_dir (void) |
202 |
} |
203 |
|
204 |
#endif |
205 |
+ |
206 |
+/* Private API: |
207 |
+ * |
208 |
+ * Returns %TRUE if the current process was executed as setuid (or an |
209 |
+ * equivalent __libc_enable_secure is available). See: |
210 |
+ * http://osdir.com/ml/linux.lfs.hardened/2007-04/msg00032.html |
211 |
+ */ |
212 |
+gboolean |
213 |
+g_check_setuid (void) |
214 |
+{ |
215 |
+ /* TODO: get __libc_enable_secure exported from glibc. |
216 |
+ * See http://www.openwall.com/lists/owl-dev/2012/08/14/1 |
217 |
+ */ |
218 |
+#if 0 && defined(HAVE_LIBC_ENABLE_SECURE) |
219 |
+ { |
220 |
+ /* See glibc/include/unistd.h */ |
221 |
+ extern int __libc_enable_secure; |
222 |
+ return __libc_enable_secure; |
223 |
+ } |
224 |
+#elif defined(HAVE_ISSETUGID) |
225 |
+ /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */ |
226 |
+ return issetugid (); |
227 |
+#elif defined(G_OS_UNIX) |
228 |
+ uid_t ruid, euid, suid; /* Real, effective and saved user ID's */ |
229 |
+ gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */ |
230 |
+ |
231 |
+ static gsize check_setuid_initialised; |
232 |
+ static gboolean is_setuid; |
233 |
+ |
234 |
+ if (g_once_init_enter (&check_setuid_initialised)) |
235 |
+ { |
236 |
+#ifdef HAVE_GETRESUID |
237 |
+ /* These aren't in the header files, so we prototype them here. |
238 |
+ */ |
239 |
+ int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); |
240 |
+ int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); |
241 |
+ |
242 |
+ if (getresuid (&ruid, &euid, &suid) != 0 || |
243 |
+ getresgid (&rgid, &egid, &sgid) != 0) |
244 |
+#endif /* HAVE_GETRESUID */ |
245 |
+ { |
246 |
+ suid = ruid = getuid (); |
247 |
+ sgid = rgid = getgid (); |
248 |
+ euid = geteuid (); |
249 |
+ egid = getegid (); |
250 |
+ } |
251 |
+ |
252 |
+ is_setuid = (ruid != euid || ruid != suid || |
253 |
+ rgid != egid || rgid != sgid); |
254 |
+ |
255 |
+ g_once_init_leave (&check_setuid_initialised, 1); |
256 |
+ } |
257 |
+ return is_setuid; |
258 |
+#else |
259 |
+ return FALSE; |
260 |
+#endif |
261 |
+} |
262 |
-- |
263 |
cgit v0.9.0.2 |