vapier 17/02/09 11:38:18
Modified: README.history
Added:
00_all_0039-Bug-11941-ld.so-Improper-assert-map-l_init_called-in.patch
00_all_0040-localedata-bs_BA-fix-yesexpr-noexpr-BZ-20974.patch
00_all_0041-powerpc-Fix-write-after-destroy-in-lock-elision-BZ-2.patch
00_all_0042-Drop-GLIBC_TUNABLES-in-setxid-processes.patch
00_all_0043-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
Log:
more upstream fixes
Revision Changes Path
1.4 src/patchsets/glibc/2.24/README.history
file :
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/README.history?rev=1.4&view=markup
plain:
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/README.history?rev=1.4&content-type=text/plain
diff :
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/README.history?r1=1.3&r2=1.4
Index: README.history
===================================================================
RCS file: /var/cvsroot/gentoo/src/patchsets/glibc/2.24/README.history,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- README.history 8 Dec 2016 19:28:42 -0000 1.3
+++ README.history 9 Feb 2017 11:38:18 -0000 1.4
@@ -1,3 +1,10 @@
+4 09 Feb 2017
+ + 00_all_0039-Bug-11941-ld.so-Improper-assert-map-l_init_called-in.patch
+ + 00_all_0040-localedata-bs_BA-fix-yesexpr-noexpr-BZ-20974.patch
+ + 00_all_0041-powerpc-Fix-write-after-destroy-in-lock-elision-BZ-2.patch
+ + 00_all_0042-Drop-GLIBC_TUNABLES-in-setxid-processes.patch
+ + 00_all_0043-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
+
3 08 Dec 2016
+ 00_all_0030-Fix-writes-past-the-allocated-array-bounds-in-execvp.patch
+ 00_all_0031-MIPS-Add-.insn-to-ensure-a-text-label-is-defined-as-.patch
1.1
src/patchsets/glibc/2.24/00_all_0039-Bug-11941-ld.so-Improper-assert-map-l_init_called-in.patch
file :
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0039-Bug-11941-ld.so-Improper-assert-map-l_init_called-in.patch?rev=1.1&view=markup
plain:
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0039-Bug-11941-ld.so-Improper-assert-map-l_init_called-in.patch?rev=1.1&content-type=text/plain
Index: 00_all_0039-Bug-11941-ld.so-Improper-assert-map-l_init_called-in.patch
===================================================================
>From 88849c6b0ff4cb1c7840a7071bc9f6fa3c984d3e Mon Sep 17 00:00:00 2001
From: Carlos O'Donell <[email protected]>
Date: Fri, 23 Dec 2016 13:30:22 -0500
Subject: [PATCH] Bug 11941: ld.so: Improper assert map->l_init_called in
dlclose
There is at least one use case where during exit a library destructor
might call dlclose() on a valid handle and have it fail with an
assertion. We must allow this case, it is a valid handle, and dlclose()
should not fail with an assert. In the future we might be able to return
an error that the dlclose() could not be completed because the opened
library has already been unloaded and destructors have run as part of
exit processing.
For more details see:
https://www.sourceware.org/ml/libc-alpha/2016-12/msg00859.html
(cherry picked from commit 57707b7fcc38855869321f8c7827bfe21d729f37)
(cherry picked from commit e9e69e468039fcd57276f783a16aa771a8e4214e)
---
elf/Makefile | 15 ++++++-
elf/dl-close.c | 30 ++++++++++---
elf/tst-nodelete-dlclose-dso.c | 90 +++++++++++++++++++++++++++++++++++++++
elf/tst-nodelete-dlclose-plugin.c | 40 +++++++++++++++++
elf/tst-nodelete-dlclose.c | 36 ++++++++++++++++
5 files changed, 203 insertions(+), 8 deletions(-)
create mode 100644 elf/tst-nodelete-dlclose-dso.c
create mode 100644 elf/tst-nodelete-dlclose-plugin.c
create mode 100644 elf/tst-nodelete-dlclose.c
diff --git a/elf/Makefile b/elf/Makefile
index 68c5d82a7094..d51e2c631b6b 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -149,7 +149,8 @@ tests += loadtest restest1 preloadtest loadfail multiload
origtest resolvfail \
tst-nodelete) \
tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
- tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error
+ tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error \
+ tst-nodelete-dlclose
# reldep9
ifeq ($(build-hardcoded-path-in-tests),yes)
tests += tst-dlopen-aout
@@ -223,7 +224,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4
testobj5 testobj6 \
tst-array5dep tst-null-argv-lib \
tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \
tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12
+ tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
+ tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin
ifeq (yes,$(have-mtls-dialect-gnu2))
tests += tst-gnu2-tls1
modules-names += tst-gnu2-tls1mod
@@ -1267,3 +1269,12 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh
$(objpfx)ldconfig
$(evaluate-test)
$(objpfx)tst-dlsym-error: $(libdl)
+
+# The application depends on the DSO, and the DSO loads the plugin.
+# The plugin also depends on the DSO. This creates the circular
+# dependency via dlopen that we're testing to make sure works.
+$(objpfx)tst-nodelete-dlclose-dso.so: $(libdl)
+$(objpfx)tst-nodelete-dlclose-plugin.so: $(objpfx)tst-nodelete-dlclose-dso.so
+$(objpfx)tst-nodelete-dlclose: $(objpfx)tst-nodelete-dlclose-dso.so
+$(objpfx)tst-nodelete-dlclose.out: $(objpfx)tst-nodelete-dlclose-dso.so \
+ $(objpfx)tst-nodelete-dlclose-plugin.so
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 687d7de874c5..9f93ab762882 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -805,19 +805,37 @@ _dl_close (void *_map)
{
struct link_map *map = _map;
- /* First see whether we can remove the object at all. */
+ /* We must take the lock to examine the contents of map and avoid
+ concurrent dlopens. */
+ __rtld_lock_lock_recursive (GL(dl_load_lock));
+
+ /* At this point we are guaranteed nobody else is touching the list of
+ loaded maps, but a concurrent dlclose might have freed our map
+ before we took the lock. There is no way to detect this (see below)
+ so we proceed assuming this isn't the case. First see whether we
+ can remove the object at all. */
if (__glibc_unlikely (map->l_flags_1 & DF_1_NODELETE))
{
- assert (map->l_init_called);
/* Nope. Do nothing. */
+ __rtld_lock_unlock_recursive (GL(dl_load_lock));
return;
}
+ /* At present this is an unreliable check except in the case where the
+ caller has recursively called dlclose and we are sure the link map
+ has not been freed. In a non-recursive dlclose the map itself
+ might have been freed and this access is potentially a data race
+ with whatever other use this memory might have now, or worse we
+ might silently corrupt memory if it looks enough like a link map.
+ POSIX has language in dlclose that appears to guarantee that this
+ should be a detectable case and given that dlclose should be threadsafe
+ we need this to be a reliable detection.
+ This is bug 20990. */
if (__builtin_expect (map->l_direct_opencount, 1) == 0)
- GLRO(dl_signal_error) (0, map->l_name, NULL, N_("shared object not open"));
-
- /* Acquire the lock. */
- __rtld_lock_lock_recursive (GL(dl_load_lock));
+ {
+ __rtld_lock_unlock_recursive (GL(dl_load_lock));
+ _dl_signal_error (0, map->l_name, NULL, N_("shared object not open"));
+ }
_dl_close_worker (map, false);
diff --git a/elf/tst-nodelete-dlclose-dso.c b/elf/tst-nodelete-dlclose-dso.c
new file mode 100644
index 000000000000..dd930f99cce3
--- /dev/null
+++ b/elf/tst-nodelete-dlclose-dso.c
@@ -0,0 +1,90 @@
+/* Bug 11941: Improper assert map->l_init_called in dlclose.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This is the primary DSO that is loaded by the appliation. This DSO
+ then loads a plugin with RTLD_NODELETE. This plugin depends on this
+ DSO. This dependency chain means that at application shutdown the
+ plugin will be destructed first. Thus by the time this DSO is
+ destructed we will be calling dlclose on an object that has already
+ been destructed. It is allowed to call dlclose in this way and
+ should not assert. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+/* Plugin to load. */
+static void *plugin_lib = NULL;
+/* Plugin function. */
+static void (*plugin_func) (void);
+#define LIB_PLUGIN "tst-nodelete-dlclose-plugin.so"
+
+/* This function is never called but the plugin references it.
+ We do this to avoid any future --as-needed from removing the
+ plugin's DT_NEEDED on this DSO (required for the test). */
+void
+primary_reference (void)
+{
+ printf ("INFO: Called primary_reference function.\n");
+}
+
+void
+primary (void)
+{
+ char *error;
+
+ plugin_lib = dlopen (LIB_PLUGIN, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
+ if (plugin_lib == NULL)
+ {
+ printf ("ERROR: Unable to load plugin library.\n");
+ exit (EXIT_FAILURE);
+ }
+ dlerror ();
+
+ plugin_func = (void (*) (void)) dlsym (plugin_lib, "plugin_func");
+ error = dlerror ();
+ if (error != NULL)
+ {
+ printf ("ERROR: Unable to find symbol with error \"%s\".",
+ error);
+ exit (EXIT_FAILURE);
+ }
+
+ return;
+}
+
+__attribute__ ((destructor))
+static void
+primary_dtor (void)
+{
+ int ret;
+
+ printf ("INFO: Calling primary destructor.\n");
+
+ /* The destructor runs in the test driver also, which
+ hasn't called primary, in that case do nothing. */
+ if (plugin_lib == NULL)
+ return;
+
+ ret = dlclose (plugin_lib);
+ if (ret != 0)
+ {
+ printf ("ERROR: Calling dlclose failed with \"%s\"\n",
+ dlerror ());
+ exit (EXIT_FAILURE);
+ }
+}
diff --git a/elf/tst-nodelete-dlclose-plugin.c
b/elf/tst-nodelete-dlclose-plugin.c
new file mode 100644
index 000000000000..8b295c1718fc
--- /dev/null
+++ b/elf/tst-nodelete-dlclose-plugin.c
@@ -0,0 +1,40 @@
+/* Bug 11941: Improper assert map->l_init_called in dlclose.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This DSO simulates a plugin with a dependency on the
+ primary DSO loaded by the appliation. */
+#include <stdio.h>
+
+extern void primary_reference (void);
+
+void
+plugin_func (void)
+{
+ printf ("INFO: Calling plugin function.\n");
+ /* Need a reference to the DSO to ensure that a potential --as-needed
+ doesn't remove the DT_NEEDED entry which we rely upon to ensure
+ destruction ordering. */
+ primary_reference ();
+}
+
+__attribute__ ((destructor))
+static void
+plugin_dtor (void)
+{
+ printf ("INFO: Calling plugin destructor.\n");
+}
diff --git a/elf/tst-nodelete-dlclose.c b/elf/tst-nodelete-dlclose.c
new file mode 100644
index 000000000000..b3d07e184980
--- /dev/null
+++ b/elf/tst-nodelete-dlclose.c
@@ -0,0 +1,36 @@
+/* Bug 11941: Improper assert map->l_init_called in dlclose.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This simulates an application using the primary DSO which loads the
+ plugin DSO. */
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void primary (void);
+
+static int
+do_test (void)
+{
+ printf ("INFO: Starting application.\n");
+ primary ();
+ printf ("INFO: Exiting application.\n");
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
--
2.11.0
1.1
src/patchsets/glibc/2.24/00_all_0040-localedata-bs_BA-fix-yesexpr-noexpr-BZ-20974.patch
file :
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0040-localedata-bs_BA-fix-yesexpr-noexpr-BZ-20974.patch?rev=1.1&view=markup
plain:
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0040-localedata-bs_BA-fix-yesexpr-noexpr-BZ-20974.patch?rev=1.1&content-type=text/plain
Index: 00_all_0040-localedata-bs_BA-fix-yesexpr-noexpr-BZ-20974.patch
===================================================================
>From 5a855ded1c38d27e016aeff54cfd283d337237a9 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <[email protected]>
Date: Thu, 15 Dec 2016 18:34:05 -0500
Subject: [PATCH] localedata: bs_BA: fix yesexpr/noexpr [BZ #20974]
Both regexes end with a "*." which means the previous match can be
omitted, and then the . allows them to match any input at all.
This means tools like coreutils' `rm -i` will always delete things
when prompted because the yesexpr regex matches all inputs (even
the negative ones).
(cherry picked from commit a035eb6928bc63fb798dcc1421529f933122d74f)
(cherry picked from commit 7e4405c50fc374d5e80141554c7887a52d1f9118)
---
localedata/locales/bs_BA | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/localedata/locales/bs_BA b/localedata/locales/bs_BA
index a47f87eb373d..68c2f9471a09 100644
--- a/localedata/locales/bs_BA
+++ b/localedata/locales/bs_BA
@@ -148,8 +148,8 @@ copy "en_DK"
END LC_CTYPE
LC_MESSAGES
-yesexpr
"<U005E><U005B><U002B><U0031><U0064><U0044><U0079><U0059><U005D><U002A><U002E>"
-noexpr "<U005E><U005B><U002D><U0030><U006E><U004E><U005D><U002A><U002E>"
+yesexpr "<U005E><U005B><U002B><U0031><U0064><U0044><U0079><U0059><U005D>"
+noexpr "<U005E><U005B><U002D><U0030><U006E><U004E><U005D>"
yesstr "<U0064><U0061>"
nostr "<U006E><U0065>"
END LC_MESSAGES
--
2.11.0
1.1
src/patchsets/glibc/2.24/00_all_0041-powerpc-Fix-write-after-destroy-in-lock-elision-BZ-2.patch
file :
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0041-powerpc-Fix-write-after-destroy-in-lock-elision-BZ-2.patch?rev=1.1&view=markup
plain:
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0041-powerpc-Fix-write-after-destroy-in-lock-elision-BZ-2.patch?rev=1.1&content-type=text/plain
Index: 00_all_0041-powerpc-Fix-write-after-destroy-in-lock-elision-BZ-2.patch
===================================================================
>From 4adce1bf311f30d584a97a25d34a2e77fa9a0bab Mon Sep 17 00:00:00 2001
From: Tulio Magno Quites Machado Filho <[email protected]>
Date: Mon, 23 Jan 2017 14:39:47 -0200
Subject: [PATCH] powerpc: Fix write-after-destroy in lock elision [BZ #20822]
The update of *adapt_count after the release of the lock causes a race
condition when thread A unlocks, thread B continues and destroys the
mutex, and thread A writes to *adapt_count.
(cherry picked from commit e9a96ea1aca4ebaa7c86e8b83b766f118d689d0f)
(with changes from commit eb1321f291515dae75c83a40c39e775fdd38e97a)
(cherry picked from commit 2762a7145bba9681b30ed5d4aed0c5d1df4329c8)
---
sysdeps/unix/sysv/linux/powerpc/elision-lock.c | 10 +++++++---
sysdeps/unix/sysv/linux/powerpc/elision-trylock.c | 7 ++++---
sysdeps/unix/sysv/linux/powerpc/elision-unlock.c | 15 +++++++++------
3 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
b/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
index dd1e4c3b17a3..7dd3d835b6ab 100644
--- a/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
+++ b/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
@@ -45,7 +45,9 @@
int
__lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
{
- if (*adapt_count > 0)
+ /* adapt_count is accessed concurrently but is just a hint. Thus,
+ use atomic accesses but relaxed MO is sufficient. */
+ if (atomic_load_relaxed (adapt_count) > 0)
{
goto use_lock;
}
@@ -67,7 +69,8 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG
int pshared)
if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
{
if (aconf.skip_lock_internal_abort > 0)
- *adapt_count = aconf.skip_lock_internal_abort;
+ atomic_store_relaxed (adapt_count,
+ aconf.skip_lock_internal_abort);
goto use_lock;
}
}
@@ -75,7 +78,8 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG
int pshared)
/* Fall back to locks for a bit if retries have been exhausted */
if (aconf.try_tbegin > 0 && aconf.skip_lock_out_of_tbegin_retries > 0)
- *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
+ atomic_store_relaxed (adapt_count,
+ aconf.skip_lock_out_of_tbegin_retries);
use_lock:
return LLL_LOCK ((*lock), pshared);
diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
b/sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
index 0807a6a4323b..606185670dc3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
+++ b/sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
@@ -34,7 +34,7 @@ __lll_trylock_elision (int *futex, short *adapt_count)
__libc_tabort (_ABORT_NESTED_TRYLOCK);
/* Only try a transaction if it's worth it. */
- if (*adapt_count > 0)
+ if (atomic_load_relaxed (adapt_count) > 0)
{
goto use_lock;
}
@@ -49,7 +49,7 @@ __lll_trylock_elision (int *futex, short *adapt_count)
__libc_tend (0);
if (aconf.skip_lock_busy > 0)
- *adapt_count = aconf.skip_lock_busy;
+ atomic_store_relaxed (adapt_count, aconf.skip_lock_busy);
}
else
{
@@ -59,7 +59,8 @@ __lll_trylock_elision (int *futex, short *adapt_count)
result in another failure. Use normal locking now and
for the next couple of calls. */
if (aconf.skip_trylock_internal_abort > 0)
- *adapt_count = aconf.skip_trylock_internal_abort;
+ atomic_store_relaxed (adapt_count,
+ aconf.skip_trylock_internal_abort);
}
}
diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
b/sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
index 43c5a67df2a4..51d7018e4c0a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
+++ b/sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
@@ -28,13 +28,16 @@ __lll_unlock_elision (int *lock, short *adapt_count, int
pshared)
__libc_tend (0);
else
{
- lll_unlock ((*lock), pshared);
+ /* Update adapt_count in the critical section to prevent a
+ write-after-destroy error as mentioned in BZ 20822. The
+ following update of adapt_count has to be contained within
+ the critical region of the fall-back lock in order to not violate
+ the mutex destruction requirements. */
+ short __tmp = atomic_load_relaxed (adapt_count);
+ if (__tmp > 0)
+ atomic_store_relaxed (adapt_count, __tmp - 1);
- /* Update the adapt count AFTER completing the critical section.
- Doing this here prevents unneeded stalling when entering
- a critical section. Saving about 8% runtime on P8. */
- if (*adapt_count > 0)
- (*adapt_count)--;
+ lll_unlock ((*lock), pshared);
}
return 0;
}
--
2.11.0
1.1
src/patchsets/glibc/2.24/00_all_0042-Drop-GLIBC_TUNABLES-in-setxid-processes.patch
file :
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0042-Drop-GLIBC_TUNABLES-in-setxid-processes.patch?rev=1.1&view=markup
plain:
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0042-Drop-GLIBC_TUNABLES-in-setxid-processes.patch?rev=1.1&content-type=text/plain
Index: 00_all_0042-Drop-GLIBC_TUNABLES-in-setxid-processes.patch
===================================================================
>From a0c7c4ebeea470eb00dcd1c8200a902a00b5470b Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <[email protected]>
Date: Thu, 2 Feb 2017 16:15:45 +0530
Subject: [PATCH] Drop GLIBC_TUNABLES in setxid processes
Drop the GLIBC_TUNABLES environment variable from the environment of
setxid processes to avoid passing it on to non-setxid children. This
prevents potentially insecure tunables in the GLIBC_TUNABLES envvar
from crossing over into a child that may use a libc that has tunables
support.
* sysdeps/generic/unsecvars.h: Add GLIBC_TUNABLES.
(cherry picked from commit 537a06fbdeb9a6c2184c745c15ef3346681f5eeb)
---
sysdeps/generic/unsecvars.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/sysdeps/generic/unsecvars.h b/sysdeps/generic/unsecvars.h
index d5b8119c9cb5..3e56538b51c4 100644
--- a/sysdeps/generic/unsecvars.h
+++ b/sysdeps/generic/unsecvars.h
@@ -4,6 +4,7 @@
#define UNSECURE_ENVVARS \
"GCONV_PATH\0" \
"GETCONF_DIR\0" \
+ "GLIBC_TUNABLES\0" \
"HOSTALIASES\0" \
"LD_AUDIT\0" \
"LD_DEBUG\0" \
--
2.11.0
1.1
src/patchsets/glibc/2.24/00_all_0043-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
file :
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0043-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch?rev=1.1&view=markup
plain:
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0043-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch?rev=1.1&content-type=text/plain
Index: 00_all_0043-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
===================================================================
>From 20f534e0abd81149c71cef082c8c058bb9d953af Mon Sep 17 00:00:00 2001
From: Florian Weimer <[email protected]>
Date: Sat, 31 Dec 2016 20:22:09 +0100
Subject: [PATCH] CVE-2015-5180: resolv: Fix crash with internal QTYPE [BZ
#18784]
Also rename T_UNSPEC because an upcoming public header file
update will use that name.
(cherry picked from commit fc82b0a2dfe7dbd35671c10510a8da1043d746a5)
(cherry picked from commit b3b37f1a5559a7620e31c8053ed1b44f798f2b6d)
---
include/arpa/nameser_compat.h | 6 +-
resolv/Makefile | 5 ++
resolv/nss_dns/dns-host.c | 2 +-
resolv/res_mkquery.c | 4 +
resolv/res_query.c | 6 +-
resolv/tst-resolv-qtypes.c | 185 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 201 insertions(+), 7 deletions(-)
create mode 100644 resolv/tst-resolv-qtypes.c
diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h
index 2e735ede4c0e..7c0deed9aed4 100644
--- a/include/arpa/nameser_compat.h
+++ b/include/arpa/nameser_compat.h
@@ -1,8 +1,8 @@
#ifndef _ARPA_NAMESER_COMPAT_
#include <resolv/arpa/nameser_compat.h>
-/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e.,
- T_A and T_AAAA). */
-#define T_UNSPEC 62321
+/* The number is outside the 16-bit RR type range and is used
+ internally by the implementation. */
+#define T_QUERY_A_AND_AAAA 439963904
#endif
diff --git a/resolv/Makefile b/resolv/Makefile
index 8be41d3ae141..a4c86b976257 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -40,6 +40,9 @@ ifeq ($(have-thread-library),yes)
extra-libs += libanl
routines += gai_sigqueue
tests += tst-res_hconf_reorder
+
+# This test sends millions of packets and is rather slow.
+xtests += tst-resolv-qtypes
endif
extra-libs-others = $(extra-libs)
libresolv-routines := gethnamaddr res_comp res_debug \
@@ -117,3 +120,5 @@ tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace
$(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@; \
$(evaluate-test)
+
+$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 5f9e35701b2a..d16fa4b8edf6 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -323,7 +323,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct
gaih_addrtuple **pat,
int olderr = errno;
enum nss_status status;
- int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
+ int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA,
host_buffer.buf->buf, 2048, &host_buffer.ptr,
&ans2p, &nans2p, &resplen2, &ans2p_malloced);
if (n >= 0)
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 12f9730199f8..d80b5318e5e0 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -103,6 +103,10 @@ res_nmkquery(res_state statp,
int n;
u_char *dnptrs[20], **dpp, **lastdnptr;
+ if (class < 0 || class > 65535
+ || type < 0 || type > 65535)
+ return -1;
+
#ifdef DEBUG
if (statp->options & RES_DEBUG)
printf(";; res_nmkquery(%s, %s, %s, %s)\n",
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 944d1a90f57e..07dc6f658386 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -122,7 +122,7 @@ __libc_res_nquery(res_state statp,
int n, use_malloc = 0;
u_int oflags = statp->_flags;
- size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE;
+ size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE;
u_char *buf = alloca (bufsize);
u_char *query1 = buf;
int nquery1 = -1;
@@ -137,7 +137,7 @@ __libc_res_nquery(res_state statp,
printf(";; res_query(%s, %d, %d)\n", name, class, type);
#endif
- if (type == T_UNSPEC)
+ if (type == T_QUERY_A_AND_AAAA)
{
n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL,
query1, bufsize);
@@ -190,7 +190,7 @@ __libc_res_nquery(res_state statp,
if (__builtin_expect (n <= 0, 0) && !use_malloc) {
/* Retry just in case res_nmkquery failed because of too
short buffer. Shouldn't happen. */
- bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET;
+ bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET;
buf = malloc (bufsize);
if (buf != NULL) {
query1 = buf;
diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c
new file mode 100644
index 000000000000..b3e60c693bf2
--- /dev/null
+++ b/resolv/tst-resolv-qtypes.c
@@ -0,0 +1,185 @@
+/* Exercise low-level query functions with different QTYPEs.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <resolv.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/resolv_test.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <support/xmemstream.h>
+
+/* If ture, the response function will send the actual response packet
+ over TCP instead of UDP. */
+static volatile bool force_tcp;
+
+/* Send back a fake resource record matching the QTYPE. */
+static void
+response (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b,
+ const char *qname, uint16_t qclass, uint16_t qtype)
+{
+ if (force_tcp && ctx->tcp)
+ {
+ resolv_response_init (b, (struct resolv_response_flags) { .tc = 1 });
+ resolv_response_add_question (b, qname, qclass, qtype);
+ return;
+ }
+
+ resolv_response_init (b, (struct resolv_response_flags) { });
+ resolv_response_add_question (b, qname, qclass, qtype);
+ resolv_response_section (b, ns_s_an);
+ resolv_response_open_record (b, qname, qclass, qtype, 0);
+ resolv_response_add_data (b, &qtype, sizeof (qtype));
+ resolv_response_close_record (b);
+}
+
+static const const char *domain = "www.example.com";
+
+static int
+wrap_res_query (int type, unsigned char *answer, int answer_length)
+{
+ return res_query (domain, C_IN, type, answer, answer_length);
+}
+
+static int
+wrap_res_search (int type, unsigned char *answer, int answer_length)
+{
+ return res_query (domain, C_IN, type, answer, answer_length);
+}
+
+static int
+wrap_res_querydomain (int type, unsigned char *answer, int answer_length)
+{
+ return res_querydomain ("www", "example.com", C_IN, type,
+ answer, answer_length);
+}
+
+static int
+wrap_res_send (int type, unsigned char *answer, int answer_length)
+{
+ unsigned char buf[512];
+ int ret = res_mkquery (QUERY, domain, C_IN, type,
+ (const unsigned char *) "", 0, NULL,
+ buf, sizeof (buf));
+ if (type < 0 || type >= 65536)
+ {
+ /* res_mkquery fails for out-of-range record types. */
+ TEST_VERIFY_EXIT (ret == -1);
+ return -1;
+ }
+ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */
+ return res_send (buf, ret, answer, answer_length);
+}
+
+static int
+wrap_res_nquery (int type, unsigned char *answer, int answer_length)
+{
+ return res_nquery (&_res, domain, C_IN, type, answer, answer_length);
+}
+
+static int
+wrap_res_nsearch (int type, unsigned char *answer, int answer_length)
+{
+ return res_nquery (&_res, domain, C_IN, type, answer, answer_length);
+}
+
+static int
+wrap_res_nquerydomain (int type, unsigned char *answer, int answer_length)
+{
+ return res_nquerydomain (&_res, "www", "example.com", C_IN, type,
+ answer, answer_length);
+}
+
+static int
+wrap_res_nsend (int type, unsigned char *answer, int answer_length)
+{
+ unsigned char buf[512];
+ int ret = res_nmkquery (&_res, QUERY, domain, C_IN, type,
+ (const unsigned char *) "", 0, NULL,
+ buf, sizeof (buf));
+ if (type < 0 || type >= 65536)
+ {
+ /* res_mkquery fails for out-of-range record types. */
+ TEST_VERIFY_EXIT (ret == -1);
+ return -1;
+ }
+ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */
+ return res_nsend (&_res, buf, ret, answer, answer_length);
+}
+
+static void
+test_function (const char *fname,
+ int (*func) (int type,
+ unsigned char *answer, int answer_length))
+{
+ unsigned char buf[512];
+ for (int tcp = 0; tcp < 2; ++tcp)
+ {
+ force_tcp = tcp;
+ for (unsigned int type = 1; type <= 65535; ++type)
+ {
+ if (test_verbose)
+ printf ("info: sending QTYPE %d with %s (tcp=%d)\n",
+ type, fname, tcp);
+ int ret = func (type, buf, sizeof (buf));
+ if (ret != 47)
+ FAIL_EXIT1 ("%s tcp=%d qtype=%d return value %d",
+ fname,tcp, type, ret);
+ /* One question, one answer record. */
+ TEST_VERIFY (memcmp (buf + 4, "\0\1\0\1\0\0\0\0", 8) == 0);
+ /* Question section. */
+ static const char qname[] = "\3www\7example\3com";
+ size_t qname_length = sizeof (qname);
+ TEST_VERIFY (memcmp (buf + 12, qname, qname_length) == 0);
+ /* RDATA part of answer. */
+ uint16_t type16 = type;
+ TEST_VERIFY (memcmp (buf + ret - 2, &type16, sizeof (type16)) == 0);
+ }
+ }
+
+ TEST_VERIFY (func (-1, buf, sizeof (buf) == -1));
+ TEST_VERIFY (func (65536, buf, sizeof (buf) == -1));
+}
+
+static int
+do_test (void)
+{
+ struct resolv_redirect_config config =
+ {
+ .response_callback = response,
+ };
+ struct resolv_test *obj = resolv_test_start (config);
+
+ test_function ("res_query", &wrap_res_query);
+ test_function ("res_search", &wrap_res_search);
+ test_function ("res_querydomain", &wrap_res_querydomain);
+ test_function ("res_send", &wrap_res_send);
+
+ test_function ("res_nquery", &wrap_res_nquery);
+ test_function ("res_nsearch", &wrap_res_nsearch);
+ test_function ("res_nquerydomain", &wrap_res_nquerydomain);
+ test_function ("res_nsend", &wrap_res_nsend);
+
+ resolv_test_end (obj);
+ return 0;
+}
+
+#define TIMEOUT 300
+#include <support/test-driver.c>
--
2.11.0