update buildroot to 2017.02.11
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
From 146b58d11fddbef15b888906e3be4f33900c416f Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue, 29 Mar 2016 12:57:56 +0200
|
||||
Subject: [PATCH 1/1] CVE-2016-3075: Stack overflow in _nss_dns_getnetbyname_r [BZ #19879]
|
||||
|
||||
The defensive copy is not needed because the name may not alias the
|
||||
output buffer.
|
||||
|
||||
(cherry picked from commit 317b199b4aff8cfa27f2302ab404d2bb5032b9a4)
|
||||
(cherry picked from commit 883dceebc8f11921a9890211a4e202e5be17562f)
|
||||
|
||||
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
||||
(downloaded from upstream git repo and removed changes to files
|
||||
Changelog and NEWS:
|
||||
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=146b58d11fddbef15b888906e3be4f33900c416f;hp=0eb234232eaf925fe4dca3bd60a3e1b4a7ab2882)
|
||||
---
|
||||
ChangeLog | 7 +++++++
|
||||
NEWS | 10 ++++++++--
|
||||
resolv/nss_dns/dns-network.c | 5 +----
|
||||
3 files changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
|
||||
index 2eb2f67..8f301a7 100644
|
||||
--- a/resolv/nss_dns/dns-network.c
|
||||
+++ b/resolv/nss_dns/dns-network.c
|
||||
@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
|
||||
} net_buffer;
|
||||
querybuf *orig_net_buffer;
|
||||
int anslen;
|
||||
- char *qbuf;
|
||||
enum nss_status status;
|
||||
|
||||
if (__res_maybe_init (&_res, 0) == -1)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
- qbuf = strdupa (name);
|
||||
-
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
- anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
+ anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
|
||||
if (anslen < 0)
|
||||
{
|
||||
--
|
||||
1.7.1
|
||||
|
||||
88
bsp/buildroot-2017.02.11/package/glibc/2.23/0002-gcc6.patch
Normal file
88
bsp/buildroot-2017.02.11/package/glibc/2.23/0002-gcc6.patch
Normal file
@@ -0,0 +1,88 @@
|
||||
From 5769d5d17cdb4770f1e08167b76c1684ad4e1f73 Mon Sep 17 00:00:00 2001
|
||||
From: Yvan Roux <yvan.roux@linaro.org>
|
||||
Date: Fri, 15 Apr 2016 13:29:26 +0200
|
||||
Subject: [PATCH 1/1] Suppress GCC 6 warning about ambiguous 'else' with -Wparentheses
|
||||
|
||||
(cherry picked from commit df1cf48777fe4cd81ad7fb09ecbe5b31432b7c1c)
|
||||
|
||||
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
||||
(downloaded from upstream git repo and removed changes to Changelog:
|
||||
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5769d5d17cdb4770f1e08167b76c1684ad4e1f73;hp=f1e182acaaa84e844eb96462a92ba532e1c1fff4)
|
||||
---
|
||||
ChangeLog | 5 +++++
|
||||
nis/nis_call.c | 20 +++++++++++---------
|
||||
stdlib/setenv.c | 26 ++++++++++++++------------
|
||||
3 files changed, 30 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/nis/nis_call.c b/nis/nis_call.c
|
||||
index 3fa37e4..cb7839a 100644
|
||||
--- a/nis/nis_call.c
|
||||
+++ b/nis/nis_call.c
|
||||
@@ -680,16 +680,18 @@ nis_server_cache_add (const_nis_name name, int search_parent,
|
||||
/* Choose which entry should be evicted from the cache. */
|
||||
loc = &nis_server_cache[0];
|
||||
if (*loc != NULL)
|
||||
- for (i = 1; i < 16; ++i)
|
||||
- if (nis_server_cache[i] == NULL)
|
||||
- {
|
||||
+ {
|
||||
+ for (i = 1; i < 16; ++i)
|
||||
+ if (nis_server_cache[i] == NULL)
|
||||
+ {
|
||||
+ loc = &nis_server_cache[i];
|
||||
+ break;
|
||||
+ }
|
||||
+ else if ((*loc)->uses > nis_server_cache[i]->uses
|
||||
+ || ((*loc)->uses == nis_server_cache[i]->uses
|
||||
+ && (*loc)->expires > nis_server_cache[i]->expires))
|
||||
loc = &nis_server_cache[i];
|
||||
- break;
|
||||
- }
|
||||
- else if ((*loc)->uses > nis_server_cache[i]->uses
|
||||
- || ((*loc)->uses == nis_server_cache[i]->uses
|
||||
- && (*loc)->expires > nis_server_cache[i]->expires))
|
||||
- loc = &nis_server_cache[i];
|
||||
+ }
|
||||
old = *loc;
|
||||
*loc = new;
|
||||
|
||||
diff --git a/stdlib/setenv.c b/stdlib/setenv.c
|
||||
index da61ee0..e66045f 100644
|
||||
--- a/stdlib/setenv.c
|
||||
+++ b/stdlib/setenv.c
|
||||
@@ -278,18 +278,20 @@ unsetenv (const char *name)
|
||||
ep = __environ;
|
||||
if (ep != NULL)
|
||||
while (*ep != NULL)
|
||||
- if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
- {
|
||||
- /* Found it. Remove this pointer by moving later ones back. */
|
||||
- char **dp = ep;
|
||||
-
|
||||
- do
|
||||
- dp[0] = dp[1];
|
||||
- while (*dp++);
|
||||
- /* Continue the loop in case NAME appears again. */
|
||||
- }
|
||||
- else
|
||||
- ++ep;
|
||||
+ {
|
||||
+ if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
+ {
|
||||
+ /* Found it. Remove this pointer by moving later ones back. */
|
||||
+ char **dp = ep;
|
||||
+
|
||||
+ do
|
||||
+ dp[0] = dp[1];
|
||||
+ while (*dp++);
|
||||
+ /* Continue the loop in case NAME appears again. */
|
||||
+ }
|
||||
+ else
|
||||
+ ++ep;
|
||||
+ }
|
||||
|
||||
UNLOCK;
|
||||
|
||||
--
|
||||
1.7.1
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
From 43c2948756bb6e144c7b871e827bba37d61ad3a3 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Sat, 18 Jun 2016 19:11:23 +0200
|
||||
Subject: [PATCH] MIPS, SPARC: fix wrong vfork aliases in libpthread.so
|
||||
|
||||
With recent binutils versions the GNU libc fails to build on at least
|
||||
MISP and SPARC, with this kind of error:
|
||||
|
||||
/home/aurel32/glibc/glibc-build/nptl/libpthread.so:(*IND*+0x0): multiple definition of `vfork@GLIBC_2.0'
|
||||
/home/aurel32/glibc/glibc-build/nptl/libpthread.so::(.text+0xee50): first defined here
|
||||
|
||||
It appears that on these architectures pt-vfork.S includes vfork.S
|
||||
(through the alpha version of pt-vfork.S) and that the __vfork aliases
|
||||
are not conditionalized on IS_IN (libc) like on other architectures.
|
||||
Therefore the aliases are also wrongly included in libpthread.so.
|
||||
|
||||
Fix this by properly conditionalizing the aliases like on other
|
||||
architectures.
|
||||
|
||||
Changelog:
|
||||
* sysdeps/unix/sysv/linux/mips/vfork.S (__vfork): Conditionalize
|
||||
hidden_def, weak_alias and strong_alias on [IS_IN (libc)].
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise.
|
||||
|
||||
[Vincent: do not patch ChangeLog]
|
||||
|
||||
Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
|
||||
---
|
||||
sysdeps/unix/sysv/linux/mips/vfork.S | 2 ++
|
||||
sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S | 2 ++
|
||||
sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S | 2 ++
|
||||
3 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/vfork.S b/sysdeps/unix/sysv/linux/mips/vfork.S
|
||||
index 8c66151..c0c0ce6 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/vfork.S
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/vfork.S
|
||||
@@ -106,6 +106,8 @@ L(error):
|
||||
#endif
|
||||
END(__vfork)
|
||||
|
||||
+#if IS_IN (libc)
|
||||
libc_hidden_def(__vfork)
|
||||
weak_alias (__vfork, vfork)
|
||||
strong_alias (__vfork, __libc_vfork)
|
||||
+#endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
|
||||
index dc32e0a..94f2c8d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
|
||||
@@ -44,6 +44,8 @@ ENTRY(__vfork)
|
||||
nop
|
||||
END(__vfork)
|
||||
|
||||
+#if IS_IN (libc)
|
||||
libc_hidden_def (__vfork)
|
||||
weak_alias (__vfork, vfork)
|
||||
strong_alias (__vfork, __libc_vfork)
|
||||
+#endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S b/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
|
||||
index 05be3c2..a7479e9 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
|
||||
@@ -44,6 +44,8 @@ ENTRY(__vfork)
|
||||
nop
|
||||
END(__vfork)
|
||||
|
||||
+#if IS_IN (libc)
|
||||
libc_hidden_def (__vfork)
|
||||
weak_alias (__vfork, vfork)
|
||||
strong_alias (__vfork, __libc_vfork)
|
||||
+#endif
|
||||
--
|
||||
2.7.3
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
From b87c1ec3fa398646f042a68f0ce0f7d09c1348c7 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Tue, 21 Jun 2016 23:59:37 +0200
|
||||
Subject: [PATCH] MIPS, SPARC: more fixes to the vfork aliases in libpthread.so
|
||||
|
||||
Commit 43c29487 tried to fix the vfork aliases in libpthread.so on MIPS
|
||||
and SPARC, but failed to do it correctly, introducing an ABI change.
|
||||
|
||||
This patch does the remaining changes needed to align the MIPS and SPARC
|
||||
vfork implementations with the other architectures. That way the the
|
||||
alpha version of pt-vfork.S works correctly for MIPS and SPARC. The
|
||||
changes for alpha were done in 82aab97c.
|
||||
|
||||
Changelog:
|
||||
* sysdeps/unix/sysv/linux/mips/vfork.S (__vfork): Rename into
|
||||
__libc_vfork.
|
||||
(__vfork) [IS_IN (libc)]: Remove alias.
|
||||
(__libc_vfork) [IS_IN (libc)]: Define as an alias.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise.
|
||||
|
||||
[Vincent: do not patch ChangeLog]
|
||||
|
||||
Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
|
||||
---
|
||||
sysdeps/unix/sysv/linux/mips/vfork.S | 12 ++++++------
|
||||
sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S | 8 ++++----
|
||||
sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S | 8 ++++----
|
||||
3 files changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/vfork.S b/sysdeps/unix/sysv/linux/mips/vfork.S
|
||||
index c0c0ce6..1867c86 100644
|
||||
--- a/sysdeps/unix/sysv/linux/mips/vfork.S
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/vfork.S
|
||||
@@ -31,13 +31,13 @@
|
||||
LOCALSZ= 1
|
||||
FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
|
||||
GPOFF= FRAMESZ-(1*SZREG)
|
||||
-NESTED(__vfork,FRAMESZ,sp)
|
||||
+NESTED(__libc_vfork,FRAMESZ,sp)
|
||||
#ifdef __PIC__
|
||||
SETUP_GP
|
||||
#endif
|
||||
PTR_SUBU sp, FRAMESZ
|
||||
cfi_adjust_cfa_offset (FRAMESZ)
|
||||
- SETUP_GP64_REG (a5, __vfork)
|
||||
+ SETUP_GP64_REG (a5, __libc_vfork)
|
||||
#ifdef __PIC__
|
||||
SAVE_GP (GPOFF)
|
||||
#endif
|
||||
@@ -104,10 +104,10 @@ L(error):
|
||||
RESTORE_GP64_REG
|
||||
j __syscall_error
|
||||
#endif
|
||||
- END(__vfork)
|
||||
+ END(__libc_vfork)
|
||||
|
||||
#if IS_IN (libc)
|
||||
-libc_hidden_def(__vfork)
|
||||
-weak_alias (__vfork, vfork)
|
||||
-strong_alias (__vfork, __libc_vfork)
|
||||
+weak_alias (__libc_vfork, vfork)
|
||||
+strong_alias (__libc_vfork, __vfork)
|
||||
+libc_hidden_def (__vfork)
|
||||
#endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
|
||||
index 94f2c8d..0d0a3b5 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
.text
|
||||
.globl __syscall_error
|
||||
-ENTRY(__vfork)
|
||||
+ENTRY(__libc_vfork)
|
||||
ld [%g7 + PID], %o5
|
||||
cmp %o5, 0
|
||||
bne 1f
|
||||
@@ -42,10 +42,10 @@ ENTRY(__vfork)
|
||||
st %o5, [%g7 + PID]
|
||||
1: retl
|
||||
nop
|
||||
-END(__vfork)
|
||||
+END(__libc_vfork)
|
||||
|
||||
#if IS_IN (libc)
|
||||
+weak_alias (__libc_vfork, vfork)
|
||||
+strong_alias (__libc_vfork, __vfork)
|
||||
libc_hidden_def (__vfork)
|
||||
-weak_alias (__vfork, vfork)
|
||||
-strong_alias (__vfork, __libc_vfork)
|
||||
#endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S b/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
|
||||
index a7479e9..0818eba 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
.text
|
||||
.globl __syscall_error
|
||||
-ENTRY(__vfork)
|
||||
+ENTRY(__libc_vfork)
|
||||
ld [%g7 + PID], %o5
|
||||
sethi %hi(0x80000000), %o3
|
||||
cmp %o5, 0
|
||||
@@ -42,10 +42,10 @@ ENTRY(__vfork)
|
||||
st %o5, [%g7 + PID]
|
||||
1: retl
|
||||
nop
|
||||
-END(__vfork)
|
||||
+END(__libc_vfork)
|
||||
|
||||
#if IS_IN (libc)
|
||||
+weak_alias (__libc_vfork, vfork)
|
||||
+strong_alias (__libc_vfork, __vfork)
|
||||
libc_hidden_def (__vfork)
|
||||
-weak_alias (__vfork, vfork)
|
||||
-strong_alias (__vfork, __libc_vfork)
|
||||
#endif
|
||||
--
|
||||
2.7.3
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
From dbb9ecfaac8db022292791936733e0841a0aa447 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Neyman <stilor@att.net>
|
||||
Date: Wed, 8 Feb 2017 16:00:57 -0200
|
||||
Subject: [PATCH] sh: Fix building with gcc5/6
|
||||
|
||||
Build glibc for sh4-unknown-linux-gnu currently fails if one's
|
||||
using GCC5/6: in dl-conflict.c, the elf_machine_rela() function
|
||||
is called with NULL as its 3rd argument, sym. The implementation
|
||||
of that function in sysdeps/sh/dl-machine.h dereferences that pointer:
|
||||
|
||||
const Elf32_Sym *const refsym = sym;
|
||||
...
|
||||
if (map == &GL(dl_rtld_map))
|
||||
value -= map->l_addr + refsym->st_value + reloc->r_addend;
|
||||
|
||||
GCC discovers a null pointer dereference, and in accordance with
|
||||
-fdelete-null-pointer-checks (which is enabled in -O2) replaces this
|
||||
code with a trap - which, as SH does not implement a trap pattern in
|
||||
GCC, evaluates to an abort() call. This abort() call pulls many more
|
||||
objects from libc_nonshared.a, eventually resulting in link failure
|
||||
due to multiple definitions for a number of symbols.
|
||||
|
||||
As far as I see, the conditional before this code is always false in
|
||||
rtld: _dl_resolve_conflicts() is called with main_map as the first
|
||||
argument, not GL(_dl_rtld_map), but since that call is in yet another
|
||||
compilation unit, GCC does not know about it. Patch that wraps this
|
||||
conditional into !defined RESOLVE_CONFLICT_FIND_MAP attached.
|
||||
|
||||
* sysdeps/sh/dl-machine.h (elf_machine_rela): The condition
|
||||
in R_SH_DIR32 case is always false when inlined from
|
||||
dl-conflict.c. Ifdef out to prevent GCC from insertin an
|
||||
abort() call.
|
||||
|
||||
[Waldemar: backport of
|
||||
https://sourceware.org/git/?p=glibc.git;a=commit;h=d40dbe722f004f999b589de776f7e57e564dda01.]
|
||||
Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
|
||||
---
|
||||
sysdeps/sh/dl-machine.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
|
||||
index 5bb37d0..6509055 100644
|
||||
--- a/sysdeps/sh/dl-machine.h
|
||||
+++ b/sysdeps/sh/dl-machine.h
|
||||
@@ -389,7 +389,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
break;
|
||||
case R_SH_DIR32:
|
||||
{
|
||||
-#ifndef RTLD_BOOTSTRAP
|
||||
+#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
|
||||
/* This is defined in rtld.c, but nowhere in the static
|
||||
libc.a; make the reference weak so static programs can
|
||||
still link. This declaration cannot be done when
|
||||
--
|
||||
2.7.4
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon, 19 Jun 2017 17:09:55 +0200
|
||||
Subject: [PATCH] CVE-2017-1000366: Ignore LD_LIBRARY_PATH for AT_SECURE=1
|
||||
programs [BZ #21624]
|
||||
|
||||
LD_LIBRARY_PATH can only be used to reorder system search paths, which
|
||||
is not useful functionality.
|
||||
|
||||
This makes an exploitable unbounded alloca in _dl_init_paths unreachable
|
||||
for AT_SECURE=1 programs.
|
||||
|
||||
[Peter: Drop ChangeLog modification]
|
||||
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
|
||||
---
|
||||
elf/rtld.c | 3 ++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 2446a87680..2269dbec81 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -2422,7 +2422,8 @@ process_envvars (enum mode *modep)
|
||||
|
||||
case 12:
|
||||
/* The library search path. */
|
||||
- if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
|
||||
+ if (!__libc_enable_secure
|
||||
+ && memcmp (envline, "LIBRARY_PATH", 12) == 0)
|
||||
{
|
||||
library_path = &envline[13];
|
||||
break;
|
||||
--
|
||||
2.11.0
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
From 6d0ba622891bed9d8394eef1935add53003b12e8 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon, 19 Jun 2017 22:31:04 +0200
|
||||
Subject: [PATCH] ld.so: Reject overly long LD_PRELOAD path elements
|
||||
|
||||
[Peter: Drop ChangeLog modification]
|
||||
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
|
||||
---
|
||||
elf/rtld.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 72 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 2269dbec81..86ae20c83f 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -99,6 +99,35 @@ uintptr_t __pointer_chk_guard_local
|
||||
strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
|
||||
#endif
|
||||
|
||||
+/* Length limits for names and paths, to protect the dynamic linker,
|
||||
+ particularly when __libc_enable_secure is active. */
|
||||
+#ifdef NAME_MAX
|
||||
+# define SECURE_NAME_LIMIT NAME_MAX
|
||||
+#else
|
||||
+# define SECURE_NAME_LIMIT 255
|
||||
+#endif
|
||||
+#ifdef PATH_MAX
|
||||
+# define SECURE_PATH_LIMIT PATH_MAX
|
||||
+#else
|
||||
+# define SECURE_PATH_LIMIT 1024
|
||||
+#endif
|
||||
+
|
||||
+/* Check that AT_SECURE=0, or that the passed name does not contain
|
||||
+ directories and is not overly long. Reject empty names
|
||||
+ unconditionally. */
|
||||
+static bool
|
||||
+dso_name_valid_for_suid (const char *p)
|
||||
+{
|
||||
+ if (__glibc_unlikely (__libc_enable_secure))
|
||||
+ {
|
||||
+ /* Ignore pathnames with directories for AT_SECURE=1
|
||||
+ programs, and also skip overlong names. */
|
||||
+ size_t len = strlen (p);
|
||||
+ if (len >= SECURE_NAME_LIMIT || memchr (p, '/', len) != NULL)
|
||||
+ return false;
|
||||
+ }
|
||||
+ return *p != '\0';
|
||||
+}
|
||||
|
||||
/* List of auditing DSOs. */
|
||||
static struct audit_list
|
||||
@@ -718,6 +747,42 @@ static const char *preloadlist attribute_relro;
|
||||
/* Nonzero if information about versions has to be printed. */
|
||||
static int version_info attribute_relro;
|
||||
|
||||
+/* The LD_PRELOAD environment variable gives list of libraries
|
||||
+ separated by white space or colons that are loaded before the
|
||||
+ executable's dependencies and prepended to the global scope list.
|
||||
+ (If the binary is running setuid all elements containing a '/' are
|
||||
+ ignored since it is insecure.) Return the number of preloads
|
||||
+ performed. */
|
||||
+unsigned int
|
||||
+handle_ld_preload (const char *preloadlist, struct link_map *main_map)
|
||||
+{
|
||||
+ unsigned int npreloads = 0;
|
||||
+ const char *p = preloadlist;
|
||||
+ char fname[SECURE_PATH_LIMIT];
|
||||
+
|
||||
+ while (*p != '\0')
|
||||
+ {
|
||||
+ /* Split preload list at space/colon. */
|
||||
+ size_t len = strcspn (p, " :");
|
||||
+ if (len > 0 && len < sizeof (fname))
|
||||
+ {
|
||||
+ memcpy (fname, p, len);
|
||||
+ fname[len] = '\0';
|
||||
+ }
|
||||
+ else
|
||||
+ fname[0] = '\0';
|
||||
+
|
||||
+ /* Skip over the substring and the following delimiter. */
|
||||
+ p += len;
|
||||
+ if (*p != '\0')
|
||||
+ ++p;
|
||||
+
|
||||
+ if (dso_name_valid_for_suid (fname))
|
||||
+ npreloads += do_preload (fname, main_map, "LD_PRELOAD");
|
||||
+ }
|
||||
+ return npreloads;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
dl_main (const ElfW(Phdr) *phdr,
|
||||
ElfW(Word) phnum,
|
||||
@@ -1464,23 +1529,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
|
||||
if (__glibc_unlikely (preloadlist != NULL))
|
||||
{
|
||||
- /* The LD_PRELOAD environment variable gives list of libraries
|
||||
- separated by white space or colons that are loaded before the
|
||||
- executable's dependencies and prepended to the global scope
|
||||
- list. If the binary is running setuid all elements
|
||||
- containing a '/' are ignored since it is insecure. */
|
||||
- char *list = strdupa (preloadlist);
|
||||
- char *p;
|
||||
-
|
||||
HP_TIMING_NOW (start);
|
||||
-
|
||||
- /* Prevent optimizing strsep. Speed is not important here. */
|
||||
- while ((p = (strsep) (&list, " :")) != NULL)
|
||||
- if (p[0] != '\0'
|
||||
- && (__builtin_expect (! __libc_enable_secure, 1)
|
||||
- || strchr (p, '/') == NULL))
|
||||
- npreloads += do_preload (p, main_map, "LD_PRELOAD");
|
||||
-
|
||||
+ npreloads += handle_ld_preload (preloadlist, main_map);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_DIFF (diff, start, stop);
|
||||
HP_TIMING_ACCUM_NT (load_time, diff);
|
||||
--
|
||||
2.11.0
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
From 81b82fb966ffbd94353f793ad17116c6088dedd9 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon, 19 Jun 2017 22:32:12 +0200
|
||||
Subject: [PATCH] ld.so: Reject overly long LD_AUDIT path elements
|
||||
|
||||
Also only process the last LD_AUDIT entry.
|
||||
|
||||
[Peter: Drop ChangeLog modification]
|
||||
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
|
||||
---
|
||||
elf/rtld.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 105 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 86ae20c83f..65647fb1c8 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -129,13 +129,91 @@ dso_name_valid_for_suid (const char *p)
|
||||
return *p != '\0';
|
||||
}
|
||||
|
||||
-/* List of auditing DSOs. */
|
||||
+/* LD_AUDIT variable contents. Must be processed before the
|
||||
+ audit_list below. */
|
||||
+const char *audit_list_string;
|
||||
+
|
||||
+/* Cyclic list of auditing DSOs. audit_list->next is the first
|
||||
+ element. */
|
||||
static struct audit_list
|
||||
{
|
||||
const char *name;
|
||||
struct audit_list *next;
|
||||
} *audit_list;
|
||||
|
||||
+/* Iterator for audit_list_string followed by audit_list. */
|
||||
+struct audit_list_iter
|
||||
+{
|
||||
+ /* Tail of audit_list_string still needing processing, or NULL. */
|
||||
+ const char *audit_list_tail;
|
||||
+
|
||||
+ /* The list element returned in the previous iteration. NULL before
|
||||
+ the first element. */
|
||||
+ struct audit_list *previous;
|
||||
+
|
||||
+ /* Scratch buffer for returning a name which is part of
|
||||
+ audit_list_string. */
|
||||
+ char fname[SECURE_NAME_LIMIT];
|
||||
+};
|
||||
+
|
||||
+/* Initialize an audit list iterator. */
|
||||
+static void
|
||||
+audit_list_iter_init (struct audit_list_iter *iter)
|
||||
+{
|
||||
+ iter->audit_list_tail = audit_list_string;
|
||||
+ iter->previous = NULL;
|
||||
+}
|
||||
+
|
||||
+/* Iterate through both audit_list_string and audit_list. */
|
||||
+static const char *
|
||||
+audit_list_iter_next (struct audit_list_iter *iter)
|
||||
+{
|
||||
+ if (iter->audit_list_tail != NULL)
|
||||
+ {
|
||||
+ /* First iterate over audit_list_string. */
|
||||
+ while (*iter->audit_list_tail != '\0')
|
||||
+ {
|
||||
+ /* Split audit list at colon. */
|
||||
+ size_t len = strcspn (iter->audit_list_tail, ":");
|
||||
+ if (len > 0 && len < sizeof (iter->fname))
|
||||
+ {
|
||||
+ memcpy (iter->fname, iter->audit_list_tail, len);
|
||||
+ iter->fname[len] = '\0';
|
||||
+ }
|
||||
+ else
|
||||
+ /* Do not return this name to the caller. */
|
||||
+ iter->fname[0] = '\0';
|
||||
+
|
||||
+ /* Skip over the substring and the following delimiter. */
|
||||
+ iter->audit_list_tail += len;
|
||||
+ if (*iter->audit_list_tail == ':')
|
||||
+ ++iter->audit_list_tail;
|
||||
+
|
||||
+ /* If the name is valid, return it. */
|
||||
+ if (dso_name_valid_for_suid (iter->fname))
|
||||
+ return iter->fname;
|
||||
+ /* Otherwise, wrap around and try the next name. */
|
||||
+ }
|
||||
+ /* Fall through to the procesing of audit_list. */
|
||||
+ }
|
||||
+
|
||||
+ if (iter->previous == NULL)
|
||||
+ {
|
||||
+ if (audit_list == NULL)
|
||||
+ /* No pre-parsed audit list. */
|
||||
+ return NULL;
|
||||
+ /* Start of audit list. The first list element is at
|
||||
+ audit_list->next (cyclic list). */
|
||||
+ iter->previous = audit_list->next;
|
||||
+ return iter->previous->name;
|
||||
+ }
|
||||
+ if (iter->previous == audit_list)
|
||||
+ /* Cyclic list wrap-around. */
|
||||
+ return NULL;
|
||||
+ iter->previous = iter->previous->next;
|
||||
+ return iter->previous->name;
|
||||
+}
|
||||
+
|
||||
#ifndef HAVE_INLINED_SYSCALLS
|
||||
/* Set nonzero during loading and initialization of executable and
|
||||
libraries, cleared before the executable's entry point runs. This
|
||||
@@ -1305,11 +1383,13 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
|
||||
|
||||
/* If we have auditing DSOs to load, do it now. */
|
||||
- if (__glibc_unlikely (audit_list != NULL))
|
||||
+ bool need_security_init = true;
|
||||
+ if (__glibc_unlikely (audit_list != NULL)
|
||||
+ || __glibc_unlikely (audit_list_string != NULL))
|
||||
{
|
||||
- /* Iterate over all entries in the list. The order is important. */
|
||||
struct audit_ifaces *last_audit = NULL;
|
||||
- struct audit_list *al = audit_list->next;
|
||||
+ struct audit_list_iter al_iter;
|
||||
+ audit_list_iter_init (&al_iter);
|
||||
|
||||
/* Since we start using the auditing DSOs right away we need to
|
||||
initialize the data structures now. */
|
||||
@@ -1320,9 +1400,14 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
use different values (especially the pointer guard) and will
|
||||
fail later on. */
|
||||
security_init ();
|
||||
+ need_security_init = false;
|
||||
|
||||
- do
|
||||
+ while (true)
|
||||
{
|
||||
+ const char *name = audit_list_iter_next (&al_iter);
|
||||
+ if (name == NULL)
|
||||
+ break;
|
||||
+
|
||||
int tls_idx = GL(dl_tls_max_dtv_idx);
|
||||
|
||||
/* Now it is time to determine the layout of the static TLS
|
||||
@@ -1331,7 +1416,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
no DF_STATIC_TLS bit is set. The reason is that we know
|
||||
glibc will use the static model. */
|
||||
struct dlmopen_args dlmargs;
|
||||
- dlmargs.fname = al->name;
|
||||
+ dlmargs.fname = name;
|
||||
dlmargs.map = NULL;
|
||||
|
||||
const char *objname;
|
||||
@@ -1344,7 +1429,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
not_loaded:
|
||||
_dl_error_printf ("\
|
||||
ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
- al->name, err_str);
|
||||
+ name, err_str);
|
||||
if (malloced)
|
||||
free ((char *) err_str);
|
||||
}
|
||||
@@ -1448,10 +1533,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
goto not_loaded;
|
||||
}
|
||||
}
|
||||
-
|
||||
- al = al->next;
|
||||
}
|
||||
- while (al != audit_list->next);
|
||||
|
||||
/* If we have any auditing modules, announce that we already
|
||||
have two objects loaded. */
|
||||
@@ -1715,7 +1797,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
if (tcbp == NULL)
|
||||
tcbp = init_tls ();
|
||||
|
||||
- if (__glibc_likely (audit_list == NULL))
|
||||
+ if (__glibc_likely (need_security_init))
|
||||
/* Initialize security features. But only if we have not done it
|
||||
earlier. */
|
||||
security_init ();
|
||||
@@ -2346,9 +2428,7 @@ process_dl_audit (char *str)
|
||||
char *p;
|
||||
|
||||
while ((p = (strsep) (&str, ":")) != NULL)
|
||||
- if (p[0] != '\0'
|
||||
- && (__builtin_expect (! __libc_enable_secure, 1)
|
||||
- || strchr (p, '/') == NULL))
|
||||
+ if (dso_name_valid_for_suid (p))
|
||||
{
|
||||
/* This is using the local malloc, not the system malloc. The
|
||||
memory can never be freed. */
|
||||
@@ -2412,7 +2492,7 @@ process_envvars (enum mode *modep)
|
||||
break;
|
||||
}
|
||||
if (memcmp (envline, "AUDIT", 5) == 0)
|
||||
- process_dl_audit (&envline[6]);
|
||||
+ audit_list_string = &envline[6];
|
||||
break;
|
||||
|
||||
case 7:
|
||||
--
|
||||
2.11.0
|
||||
|
||||
Reference in New Issue
Block a user