mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
Merge pull request #4723 from MilhouseVH/glibc_exploit
[glibc] Bump to 2.23 fixing CVE-2015-7547
This commit is contained in:
commit
ee340f7398
@ -17,7 +17,7 @@
|
||||
################################################################################
|
||||
|
||||
PKG_NAME="glibc"
|
||||
PKG_VERSION="2.22"
|
||||
PKG_VERSION="2.23"
|
||||
PKG_REV="1"
|
||||
PKG_ARCH="any"
|
||||
PKG_LICENSE="GPL"
|
||||
|
@ -1,27 +0,0 @@
|
||||
From 5c8c3123652045191474a4ca85fbb6e8d9e7d2bc Mon Sep 17 00:00:00 2001
|
||||
From: Roland McGrath <roland@hack.frob.com>
|
||||
Date: Fri, 4 Sep 2015 14:37:56 -0700
|
||||
Subject: [PATCH] BZ#18921: Fix opendir inverted o_directory_works test.
|
||||
|
||||
(cherry picked from commit bd9e69abb887d78d0d6708fc089cc9f3eabf106d)
|
||||
---
|
||||
ChangeLog | 8 ++++++++
|
||||
sysdeps/posix/opendir.c | 2 +-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c
|
||||
index 6509f5c..9edf056 100644
|
||||
--- a/sysdeps/posix/opendir.c
|
||||
+++ b/sysdeps/posix/opendir.c
|
||||
@@ -105,7 +105,7 @@ need_isdir_precheck (void)
|
||||
tryopen_o_directory ();
|
||||
|
||||
/* We can skip the expensive `stat' call if O_DIRECTORY works. */
|
||||
- return o_directory_works > 0;
|
||||
+ return o_directory_works < 0;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
--
|
||||
1.9.4
|
||||
|
@ -1,206 +0,0 @@
|
||||
From 3007f797a1a596e954f44879a5a7267966186ba4 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Frysinger <vapier@gentoo.org>
|
||||
Date: Fri, 28 Aug 2015 17:08:49 -0400
|
||||
Subject: [PATCH] getmntent: fix memory corruption w/blank lines [BZ #18887]
|
||||
|
||||
The fix for BZ #17273 introduced a single byte of memory corruption when
|
||||
the line is entirely blank. It would walk back past the start of the
|
||||
buffer if the heap happened to be 0x20 or 0x09 and then write a NUL byte.
|
||||
buffer = '\n';
|
||||
end_ptr = buffer;
|
||||
while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')
|
||||
end_ptr--;
|
||||
*end_ptr = '\0';
|
||||
|
||||
Fix that and rework the tests. Adding the testcase for BZ #17273 to the
|
||||
existing \040 parser does not really make sense as it's unrelated, and
|
||||
leads to confusing behavior: it implicitly relies on the new entry being
|
||||
longer than the previous entry (since it just rewinds the FILE*). Split
|
||||
it out into its own dedicated testcase instead.
|
||||
|
||||
(cherry picked from commit b0e805fa0d6fea33745952df7b7f5442ca4c374f)
|
||||
---
|
||||
ChangeLog | 10 ++++++++
|
||||
NEWS | 2 +-
|
||||
misc/Makefile | 3 ++-
|
||||
misc/mntent_r.c | 4 +++-
|
||||
misc/tst-mntent-blank-corrupt.c | 45 ++++++++++++++++++++++++++++++++++
|
||||
misc/tst-mntent-blank-passno.c | 53 +++++++++++++++++++++++++++++++++++++++++
|
||||
misc/tst-mntent.c | 20 ----------------
|
||||
7 files changed, 114 insertions(+), 23 deletions(-)
|
||||
create mode 100644 misc/tst-mntent-blank-corrupt.c
|
||||
create mode 100644 misc/tst-mntent-blank-passno.c
|
||||
|
||||
diff --git a/misc/Makefile b/misc/Makefile
|
||||
index aecb0da..2f5edf6 100644
|
||||
--- a/misc/Makefile
|
||||
+++ b/misc/Makefile
|
||||
@@ -76,7 +76,8 @@ install-lib := libg.a
|
||||
gpl2lgpl := error.c error.h
|
||||
|
||||
tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
|
||||
- tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
|
||||
+ tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \
|
||||
+ tst-mntent-blank-corrupt tst-mntent-blank-passno
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests-special += $(objpfx)tst-error1-mem.out
|
||||
endif
|
||||
diff --git a/misc/mntent_r.c b/misc/mntent_r.c
|
||||
index 6159873..4f26998 100644
|
||||
--- a/misc/mntent_r.c
|
||||
+++ b/misc/mntent_r.c
|
||||
@@ -136,7 +136,9 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
|
||||
end_ptr = strchr (buffer, '\n');
|
||||
if (end_ptr != NULL) /* chop newline */
|
||||
{
|
||||
- while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')
|
||||
+ /* Do not walk past the start of buffer if it's all whitespace. */
|
||||
+ while (end_ptr != buffer
|
||||
+ && (end_ptr[-1] == ' ' || end_ptr[-1] == '\t'))
|
||||
end_ptr--;
|
||||
*end_ptr = '\0';
|
||||
}
|
||||
diff --git a/misc/tst-mntent-blank-corrupt.c b/misc/tst-mntent-blank-corrupt.c
|
||||
new file mode 100644
|
||||
index 0000000..92266a3
|
||||
--- /dev/null
|
||||
+++ b/misc/tst-mntent-blank-corrupt.c
|
||||
@@ -0,0 +1,45 @@
|
||||
+/* Make sure blank lines does not cause memory corruption BZ #18887.
|
||||
+
|
||||
+ Copyright (C) 2009-2015 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 <mntent.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* Make sure blank lines don't trigger memory corruption. This doesn't happen
|
||||
+ for all targets though, so it's a best effort test BZ #18887. */
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ fp = tmpfile ();
|
||||
+ fputs ("\n \n/foo\\040dir /bar\\040dir auto bind \t \n", fp);
|
||||
+ rewind (fp);
|
||||
+
|
||||
+ /* The corruption happens here ... */
|
||||
+ getmntent (fp);
|
||||
+ /* ... but trigers here. */
|
||||
+ endmntent (fp);
|
||||
+
|
||||
+ /* If the test failed, we would crash, and not hit this point. */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
diff --git a/misc/tst-mntent-blank-passno.c b/misc/tst-mntent-blank-passno.c
|
||||
new file mode 100644
|
||||
index 0000000..fc04291
|
||||
--- /dev/null
|
||||
+++ b/misc/tst-mntent-blank-passno.c
|
||||
@@ -0,0 +1,53 @@
|
||||
+/* Make sure trailing whitespace is handled properly BZ #17273.
|
||||
+
|
||||
+ Copyright (C) 2009-2015 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 <mntent.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* Check entries to make sure trailing whitespace is ignored and we return the
|
||||
+ correct passno value BZ #17273. */
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int result = 0;
|
||||
+ FILE *fp;
|
||||
+ struct mntent *mnt;
|
||||
+
|
||||
+ fp = tmpfile ();
|
||||
+ fputs ("/foo\\040dir /bar\\040dir auto bind \t \n", fp);
|
||||
+ rewind (fp);
|
||||
+
|
||||
+ mnt = getmntent (fp);
|
||||
+ if (strcmp (mnt->mnt_fsname, "/foo dir") != 0
|
||||
+ || strcmp (mnt->mnt_dir, "/bar dir") != 0
|
||||
+ || strcmp (mnt->mnt_type, "auto") != 0
|
||||
+ || strcmp (mnt->mnt_opts, "bind") != 0
|
||||
+ || mnt->mnt_freq != 0
|
||||
+ || mnt->mnt_passno != 0)
|
||||
+ {
|
||||
+ puts ("Error while reading entry with trailing whitespaces");
|
||||
+ result = 1;
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
diff --git a/misc/tst-mntent.c b/misc/tst-mntent.c
|
||||
index 876c89f..820b354 100644
|
||||
--- a/misc/tst-mntent.c
|
||||
+++ b/misc/tst-mntent.c
|
||||
@@ -73,26 +73,6 @@ main (int argc, char *argv[])
|
||||
puts ("Error while reading written entry back in");
|
||||
result = 1;
|
||||
}
|
||||
-
|
||||
- /* Part III: Entry with whitespaces at the end of a line. */
|
||||
- rewind (fp);
|
||||
-
|
||||
- fputs ("/foo\\040dir /bar\\040dir auto bind \t \n", fp);
|
||||
-
|
||||
- rewind (fp);
|
||||
-
|
||||
- mnt = getmntent (fp);
|
||||
-
|
||||
- if (strcmp (mnt->mnt_fsname, "/foo dir") != 0
|
||||
- || strcmp (mnt->mnt_dir, "/bar dir") != 0
|
||||
- || strcmp (mnt->mnt_type, "auto") != 0
|
||||
- || strcmp (mnt->mnt_opts, "bind") != 0
|
||||
- || mnt->mnt_freq != 0
|
||||
- || mnt->mnt_passno != 0)
|
||||
- {
|
||||
- puts ("Error while reading entry with trailing whitespaces");
|
||||
- result = 1;
|
||||
- }
|
||||
}
|
||||
|
||||
return result;
|
||||
--
|
||||
1.9.4
|
||||
|
@ -1,71 +0,0 @@
|
||||
From 561a9f11a974a447acb3dd03550a05df701a900e Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schwab <schwab@suse.de>
|
||||
Date: Mon, 10 Aug 2015 14:12:47 +0200
|
||||
Subject: [PATCH] Readd O_LARGEFILE flag for openat64 (bug 18781)
|
||||
|
||||
(cherry picked from commit eb32b0d40308166c4d8f6330cc2958cb1e545075)
|
||||
---
|
||||
ChangeLog | 7 +++++++
|
||||
NEWS | 2 +-
|
||||
io/test-lfs.c | 21 ++++++++++++++++++++-
|
||||
sysdeps/unix/sysv/linux/openat.c | 5 +++++
|
||||
4 files changed, 33 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/io/test-lfs.c b/io/test-lfs.c
|
||||
index 539c2a2..b6ebae4 100644
|
||||
--- a/io/test-lfs.c
|
||||
+++ b/io/test-lfs.c
|
||||
@@ -144,7 +144,7 @@ test_ftello (void)
|
||||
int
|
||||
do_test (int argc, char *argv[])
|
||||
{
|
||||
- int ret;
|
||||
+ int ret, fd2;
|
||||
struct stat64 statbuf;
|
||||
|
||||
ret = lseek64 (fd, TWO_GB+100, SEEK_SET);
|
||||
@@ -195,6 +195,25 @@ do_test (int argc, char *argv[])
|
||||
error (EXIT_FAILURE, 0, "stat reported size %lld instead of %lld.",
|
||||
(long long int) statbuf.st_size, (TWO_GB + 100 + 5));
|
||||
|
||||
+ fd2 = openat64 (AT_FDCWD, name, O_RDWR);
|
||||
+ if (fd2 == -1)
|
||||
+ {
|
||||
+ if (errno == ENOSYS)
|
||||
+ {
|
||||
+ /* Silently ignore this test. */
|
||||
+ error (0, 0, "openat64 is not supported");
|
||||
+ }
|
||||
+ else
|
||||
+ error (EXIT_FAILURE, errno, "openat64 failed to open big file");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ret = close (fd2);
|
||||
+
|
||||
+ if (ret == -1)
|
||||
+ error (EXIT_FAILURE, errno, "error closing file");
|
||||
+ }
|
||||
+
|
||||
test_ftello ();
|
||||
|
||||
return 0;
|
||||
diff --git a/sysdeps/unix/sysv/linux/openat.c b/sysdeps/unix/sysv/linux/openat.c
|
||||
index 6777123..ad8e31d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/openat.c
|
||||
+++ b/sysdeps/unix/sysv/linux/openat.c
|
||||
@@ -68,6 +68,11 @@ __OPENAT (int fd, const char *file, int oflag, ...)
|
||||
va_end (arg);
|
||||
}
|
||||
|
||||
+ /* We have to add the O_LARGEFILE flag for openat64. */
|
||||
+#ifdef MORE_OFLAGS
|
||||
+ oflag |= MORE_OFLAGS;
|
||||
+#endif
|
||||
+
|
||||
return SYSCALL_CANCEL (openat, fd, file, oflag, mode);
|
||||
}
|
||||
libc_hidden_def (__OPENAT)
|
||||
--
|
||||
1.9.4
|
||||
|
@ -1,177 +0,0 @@
|
||||
From a34d1c6afc86521d6ad17662a3b5362d8481514c Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Ostapenko <m.ostapenko@partner.samsung.com>
|
||||
Date: Mon, 10 Aug 2015 10:47:54 +0300
|
||||
Subject: [PATCH] Clear DF_1_NODELETE flag only for failed to load library.
|
||||
|
||||
https://sourceware.org/bugzilla/show_bug.cgi?id=18778
|
||||
|
||||
If dlopen fails to load an object that has triggered loading libpthread it
|
||||
causes ld.so to unload libpthread because its DF_1_NODELETE flags has been
|
||||
forcefully cleared. The next call to __rtdl_unlock_lock_recursive will crash
|
||||
since pthread_mutex_unlock no longer exists.
|
||||
|
||||
This patch moves l->l_flags_1 &= ~DF_1_NODELETE out of loop through all loaded
|
||||
libraries and performs the action only on inconsistent one.
|
||||
|
||||
[BZ #18778]
|
||||
* elf/Makefile (tests): Add Add tst-nodelete2.
|
||||
(modules-names): Add tst-nodelete2mod.
|
||||
(tst-nodelete2mod.so-no-z-defs): New.
|
||||
($(objpfx)tst-nodelete2): Likewise.
|
||||
($(objpfx)tst-nodelete2.out): Likewise.
|
||||
(LDFLAGS-tst-nodelete2): Likewise.
|
||||
* elf/dl-close.c (_dl_close_worker): Move DF_1_NODELETE clearing
|
||||
out of loop through all loaded libraries.
|
||||
* elf/tst-nodelete2.c: New file.
|
||||
* elf/tst-nodelete2mod.c: Likewise.
|
||||
|
||||
(cherry picked from commit f25238ffe0455013174438376b3ee88df496f9d1)
|
||||
---
|
||||
ChangeLog | 14 +++++++++
|
||||
NEWS | 2 +-
|
||||
elf/Makefile | 11 +++++--
|
||||
elf/dl-close.c | 15 ++++-----
|
||||
elf/tst-nodelete2.c | 37 +++++++++++++++++++++++
|
||||
elf/{tst-znodelete-zlib.cc => tst-nodelete2mod.c} | 3 +-
|
||||
6 files changed, 71 insertions(+), 11 deletions(-)
|
||||
create mode 100644 elf/tst-nodelete2.c
|
||||
rename elf/{tst-znodelete-zlib.cc => tst-nodelete2mod.c} (50%)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 4ceeaf8..71a18a1 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -148,7 +148,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \
|
||||
tst-nodelete) \
|
||||
tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
|
||||
- tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened
|
||||
+ tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
|
||||
+ tst-nodelete2
|
||||
# reldep9
|
||||
ifeq ($(build-hardcoded-path-in-tests),yes)
|
||||
tests += tst-dlopen-aout
|
||||
@@ -218,7 +219,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
tst-initorder2d \
|
||||
tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
|
||||
tst-array5dep tst-null-argv-lib \
|
||||
- tst-tlsalign-lib tst-nodelete-opened-lib
|
||||
+ tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod
|
||||
ifeq (yes,$(have-protected-data))
|
||||
modules-names += tst-protected1moda tst-protected1modb
|
||||
tests += tst-protected1a tst-protected1b
|
||||
@@ -594,6 +595,7 @@ tst-auditmod9b.so-no-z-defs = yes
|
||||
tst-nodelete-uniquemod.so-no-z-defs = yes
|
||||
tst-nodelete-rtldmod.so-no-z-defs = yes
|
||||
tst-nodelete-zmod.so-no-z-defs = yes
|
||||
+tst-nodelete2mod.so-no-z-defs = yes
|
||||
|
||||
ifeq ($(build-shared),yes)
|
||||
# Build all the modules even when not actually running test programs.
|
||||
@@ -1164,6 +1166,11 @@ $(objpfx)tst-nodelete.out: $(objpfx)tst-nodelete-uniquemod.so \
|
||||
LDFLAGS-tst-nodelete = -rdynamic
|
||||
LDFLAGS-tst-nodelete-zmod.so = -Wl,--enable-new-dtags,-z,nodelete
|
||||
|
||||
+$(objpfx)tst-nodelete2: $(libdl)
|
||||
+$(objpfx)tst-nodelete2.out: $(objpfx)tst-nodelete2mod.so
|
||||
+
|
||||
+LDFLAGS-tst-nodelete2 = -rdynamic
|
||||
+
|
||||
$(objpfx)tst-initorder-cmp.out: tst-initorder.exp $(objpfx)tst-initorder.out
|
||||
cmp $^ > $@; \
|
||||
$(evaluate-test)
|
||||
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||
index 9105277..c897247 100644
|
||||
--- a/elf/dl-close.c
|
||||
+++ b/elf/dl-close.c
|
||||
@@ -144,6 +144,14 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
char done[nloaded];
|
||||
struct link_map *maps[nloaded];
|
||||
|
||||
+ /* Clear DF_1_NODELETE to force object deletion. We don't need to touch
|
||||
+ l_tls_dtor_count because forced object deletion only happens when an
|
||||
+ error occurs during object load. Destructor registration for TLS
|
||||
+ non-POD objects should not have happened till then for this
|
||||
+ object. */
|
||||
+ if (force)
|
||||
+ map->l_flags_1 &= ~DF_1_NODELETE;
|
||||
+
|
||||
/* Run over the list and assign indexes to the link maps and enter
|
||||
them into the MAPS array. */
|
||||
int idx = 0;
|
||||
@@ -153,13 +161,6 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
maps[idx] = l;
|
||||
++idx;
|
||||
|
||||
- /* Clear DF_1_NODELETE to force object deletion. We don't need to touch
|
||||
- l_tls_dtor_count because forced object deletion only happens when an
|
||||
- error occurs during object load. Destructor registration for TLS
|
||||
- non-POD objects should not have happened till then for this
|
||||
- object. */
|
||||
- if (force)
|
||||
- l->l_flags_1 &= ~DF_1_NODELETE;
|
||||
}
|
||||
assert (idx == nloaded);
|
||||
|
||||
diff --git a/elf/tst-nodelete2.c b/elf/tst-nodelete2.c
|
||||
new file mode 100644
|
||||
index 0000000..388e8af
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodelete2.c
|
||||
@@ -0,0 +1,37 @@
|
||||
+#include "../dlfcn/dlfcn.h"
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int result = 0;
|
||||
+
|
||||
+ printf ("\nOpening pthread library.\n");
|
||||
+ void *pthread = dlopen (LIBPTHREAD_SO, RTLD_LAZY);
|
||||
+
|
||||
+ /* This is a test for correct DF_1_NODELETE clearing when dlopen failure
|
||||
+ happens. We should clear DF_1_NODELETE for failed library only, because
|
||||
+ doing this for others (e.g. libpthread) might cause them to be unloaded,
|
||||
+ that may lead to some global references (e.g. __rtld_lock_unlock) to be
|
||||
+ broken. The dlopen should fail because of undefined symbols in shared
|
||||
+ library, that cause DF_1_NODELETE to be cleared. For libpthread, this
|
||||
+ flag should be set, because if not, SIGSEGV will happen in dlclose. */
|
||||
+ if (dlopen ("tst-nodelete2mod.so", RTLD_NOW) != NULL)
|
||||
+ {
|
||||
+ printf ("Unique symbols test failed\n");
|
||||
+ result = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (pthread)
|
||||
+ dlclose (pthread);
|
||||
+
|
||||
+ if (result == 0)
|
||||
+ printf ("SUCCESS\n");
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
diff --git a/elf/tst-znodelete-zlib.cc b/elf/tst-nodelete2mod.c
|
||||
similarity index 50%
|
||||
rename from elf/tst-znodelete-zlib.cc
|
||||
rename to elf/tst-nodelete2mod.c
|
||||
index 1e8f368..e88c756 100644
|
||||
--- a/elf/tst-znodelete-zlib.cc
|
||||
+++ b/elf/tst-nodelete2mod.c
|
||||
@@ -1,6 +1,7 @@
|
||||
+/* Undefined symbol. */
|
||||
extern int not_exist (void);
|
||||
|
||||
int foo (void)
|
||||
{
|
||||
- return not_exist ();
|
||||
+ return not_exist ();
|
||||
}
|
||||
--
|
||||
1.9.4
|
||||
|
@ -1,319 +0,0 @@
|
||||
From 6c84109cfa26f35c3dfed3acb97d347361bd5849 Mon Sep 17 00:00:00 2001
|
||||
From: Carlos O'Donell <carlos@systemhalted.org>
|
||||
Date: Thu, 8 Oct 2015 16:34:53 -0400
|
||||
Subject: [PATCH] strcoll: Remove incorrect STRDIFF-based optimization (Bug
|
||||
18589).
|
||||
|
||||
The optimization introduced in commit
|
||||
f13c2a8dff2329c6692a80176262ceaaf8a6f74e, causes regressions in
|
||||
sorting for languages that have digraphs that change sort order, like
|
||||
cs_CZ which sorts ch between h and i.
|
||||
|
||||
My analysis shows the fast-forwarding optimization in STRCOLL advances
|
||||
through a digraph while possibly stopping in the middle which results
|
||||
in a subsequent skipping of the digraph and incorrect sorting. The
|
||||
optimization is incorrect as implemented and because of that I'm
|
||||
removing it for 2.23, and I will also commit this fix for 2.22 where
|
||||
it was originally introduced.
|
||||
|
||||
This patch reverts the optimization, introduces a new bug-strcoll2.c
|
||||
regression test that tests both cs_CZ.UTF-8 and da_DK.ISO-8859-1 and
|
||||
ensures they sort one digraph each correctly. The optimization can't be
|
||||
applied without regressing this test.
|
||||
|
||||
Checked on x86_64, bug-strcoll2.c fails without this patch and passes
|
||||
after. This will also get a fix on 2.22 which has the same bug.
|
||||
|
||||
(cherry picked from commit 87701a58e291bd7ac3b407d10a829dac52c9c16e)
|
||||
---
|
||||
ChangeLog | 14 +++++++
|
||||
NEWS | 2 +-
|
||||
locale/C-collate.c | 4 +-
|
||||
locale/categories.def | 1 -
|
||||
locale/langinfo.h | 1 -
|
||||
locale/localeinfo.h | 8 ----
|
||||
locale/programs/ld-collate.c | 9 -----
|
||||
string/bug-strcoll2.c | 93 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
string/strcoll_l.c | 38 +-----------------
|
||||
wcsmbs/wcscoll_l.c | 1 -
|
||||
10 files changed, 110 insertions(+), 61 deletions(-)
|
||||
create mode 100644 string/bug-strcoll2.c
|
||||
|
||||
diff --git a/locale/C-collate.c b/locale/C-collate.c
|
||||
index d7f3c55..06dfdfa 100644
|
||||
--- a/locale/C-collate.c
|
||||
+++ b/locale/C-collate.c
|
||||
@@ -144,8 +144,6 @@ const struct __locale_data _nl_C_LC_COLLATE attribute_hidden =
|
||||
/* _NL_COLLATE_COLLSEQWC */
|
||||
{ .string = (const char *) collseqwc },
|
||||
/* _NL_COLLATE_CODESET */
|
||||
- { .string = _nl_C_codeset },
|
||||
- /* _NL_COLLATE_ENCODING_TYPE */
|
||||
- { .word = __cet_8bit }
|
||||
+ { .string = _nl_C_codeset }
|
||||
}
|
||||
};
|
||||
diff --git a/locale/categories.def b/locale/categories.def
|
||||
index 045489d..a8dda53 100644
|
||||
--- a/locale/categories.def
|
||||
+++ b/locale/categories.def
|
||||
@@ -58,7 +58,6 @@ DEFINE_CATEGORY
|
||||
DEFINE_ELEMENT (_NL_COLLATE_COLLSEQMB, "collate-collseqmb", std, wstring)
|
||||
DEFINE_ELEMENT (_NL_COLLATE_COLLSEQWC, "collate-collseqwc", std, wstring)
|
||||
DEFINE_ELEMENT (_NL_COLLATE_CODESET, "collate-codeset", std, string)
|
||||
- DEFINE_ELEMENT (_NL_COLLATE_ENCODING_TYPE, "collate-encoding-type", std, word)
|
||||
), NO_POSTLOAD)
|
||||
|
||||
|
||||
diff --git a/locale/langinfo.h b/locale/langinfo.h
|
||||
index ffc5c7f..a565d9d 100644
|
||||
--- a/locale/langinfo.h
|
||||
+++ b/locale/langinfo.h
|
||||
@@ -255,7 +255,6 @@ enum
|
||||
_NL_COLLATE_COLLSEQMB,
|
||||
_NL_COLLATE_COLLSEQWC,
|
||||
_NL_COLLATE_CODESET,
|
||||
- _NL_COLLATE_ENCODING_TYPE,
|
||||
_NL_NUM_LC_COLLATE,
|
||||
|
||||
/* LC_CTYPE category: character classification.
|
||||
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
|
||||
index bdab9fe..1d2ee00 100644
|
||||
--- a/locale/localeinfo.h
|
||||
+++ b/locale/localeinfo.h
|
||||
@@ -110,14 +110,6 @@ enum coll_sort_rule
|
||||
sort_mask
|
||||
};
|
||||
|
||||
-/* Collation encoding type. */
|
||||
-enum collation_encoding_type
|
||||
-{
|
||||
- __cet_other,
|
||||
- __cet_8bit,
|
||||
- __cet_utf8
|
||||
-};
|
||||
-
|
||||
/* We can map the types of the entries into a few categories. */
|
||||
enum value_type
|
||||
{
|
||||
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
|
||||
index a39a94f..dc0fe30 100644
|
||||
--- a/locale/programs/ld-collate.c
|
||||
+++ b/locale/programs/ld-collate.c
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "linereader.h"
|
||||
#include "locfile.h"
|
||||
#include "elem-hash.h"
|
||||
-#include "../localeinfo.h"
|
||||
|
||||
/* Uncomment the following line in the production version. */
|
||||
/* #define NDEBUG 1 */
|
||||
@@ -2131,8 +2130,6 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
|
||||
/* The words have to be handled specially. */
|
||||
if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB))
|
||||
add_locale_uint32 (&file, 0);
|
||||
- else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE))
|
||||
- add_locale_uint32 (&file, __cet_other);
|
||||
else
|
||||
add_locale_empty (&file);
|
||||
}
|
||||
@@ -2496,12 +2493,6 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
|
||||
add_locale_raw_data (&file, collate->mbseqorder, 256);
|
||||
add_locale_collseq_table (&file, &collate->wcseqorder);
|
||||
add_locale_string (&file, charmap->code_set_name);
|
||||
- if (strcmp (charmap->code_set_name, "UTF-8") == 0)
|
||||
- add_locale_uint32 (&file, __cet_utf8);
|
||||
- else if (charmap->mb_cur_max == 1)
|
||||
- add_locale_uint32 (&file, __cet_8bit);
|
||||
- else
|
||||
- add_locale_uint32 (&file, __cet_other);
|
||||
write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file);
|
||||
|
||||
obstack_free (&weightpool, NULL);
|
||||
diff --git a/string/bug-strcoll2.c b/string/bug-strcoll2.c
|
||||
new file mode 100644
|
||||
index 0000000..5ce2f94
|
||||
--- /dev/null
|
||||
+++ b/string/bug-strcoll2.c
|
||||
@@ -0,0 +1,93 @@
|
||||
+/* Bug 18589: sort-test.sh fails at random.
|
||||
+ Copyright (C) 1998-2015 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||
+
|
||||
+ 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 <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <locale.h>
|
||||
+
|
||||
+/* An incorrect strcoll optimization resulted in incorrect
|
||||
+ results from strcoll for cs_CZ and da_DK. */
|
||||
+
|
||||
+int
|
||||
+test_cs_CZ (void)
|
||||
+{
|
||||
+ const char t1[] = "config";
|
||||
+ const char t2[] = "choose";
|
||||
+ if (setlocale (LC_ALL, "cs_CZ.UTF-8") == NULL)
|
||||
+ {
|
||||
+ perror ("setlocale");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ /* In Czech the digraph ch sorts after c, therefore we expect
|
||||
+ config to sort before choose. */
|
||||
+ int a = strcoll (t1, t2);
|
||||
+ int b = strcoll (t2, t1);
|
||||
+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a);
|
||||
+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b);
|
||||
+ if (a < 0 && b > 0)
|
||||
+ {
|
||||
+ puts ("PASS: config < choose");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ puts ("FAIL: Wrong sorting in cz_CZ.UTF-8.");
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+test_da_DK (void)
|
||||
+{
|
||||
+ const char t1[] = "AS";
|
||||
+ const char t2[] = "AA";
|
||||
+ if (setlocale (LC_ALL, "da_DK.ISO-8859-1") == NULL)
|
||||
+ {
|
||||
+ perror ("setlocale");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ /* AA should be treated as the last letter of the Danish alphabet,
|
||||
+ hence sorting after AS. */
|
||||
+ int a = strcoll (t1, t2);
|
||||
+ int b = strcoll (t2, t1);
|
||||
+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t1, t2, a);
|
||||
+ printf ("strcoll (\"%s\", \"%s\") = %d\n", t2, t1, b);
|
||||
+ if (a < 0 && b > 0)
|
||||
+ {
|
||||
+ puts ("PASS: AS < AA");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ puts ("FAIL: Wrong sorting in da_DK.ISO-8859-1");
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int err = 0;
|
||||
+ err |= test_cs_CZ ();
|
||||
+ err |= test_da_DK ();
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
diff --git a/string/strcoll_l.c b/string/strcoll_l.c
|
||||
index 8f1225f..35bc0e4 100644
|
||||
--- a/string/strcoll_l.c
|
||||
+++ b/string/strcoll_l.c
|
||||
@@ -29,7 +29,6 @@
|
||||
# define STRING_TYPE char
|
||||
# define USTRING_TYPE unsigned char
|
||||
# define STRCOLL __strcoll_l
|
||||
-# define STRDIFF __strdiff
|
||||
# define STRCMP strcmp
|
||||
# define WEIGHT_H "../locale/weight.h"
|
||||
# define SUFFIX MB
|
||||
@@ -42,20 +41,6 @@
|
||||
#include "../locale/localeinfo.h"
|
||||
#include WEIGHT_H
|
||||
|
||||
-#define MASK_UTF8_7BIT (1 << 7)
|
||||
-#define MASK_UTF8_START (3 << 6)
|
||||
-
|
||||
-size_t
|
||||
-STRDIFF (const STRING_TYPE *s, const STRING_TYPE *t)
|
||||
-{
|
||||
- size_t n;
|
||||
-
|
||||
- for (n = 0; *s != '\0' && *s++ == *t++; ++n)
|
||||
- continue;
|
||||
-
|
||||
- return n;
|
||||
-}
|
||||
-
|
||||
/* Track status while looking for sequences in a string. */
|
||||
typedef struct
|
||||
{
|
||||
@@ -269,29 +254,9 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
|
||||
const USTRING_TYPE *extra;
|
||||
const int32_t *indirect;
|
||||
|
||||
- /* In case there is no locale specific sort order (C / POSIX). */
|
||||
if (nrules == 0)
|
||||
return STRCMP (s1, s2);
|
||||
|
||||
- /* Fast forward to the position of the first difference. Needs to be
|
||||
- encoding aware as the byte-by-byte comparison can stop in the middle
|
||||
- of a char sequence for multibyte encodings like UTF-8. */
|
||||
- uint_fast32_t encoding =
|
||||
- current->values[_NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE)].word;
|
||||
- if (encoding != __cet_other)
|
||||
- {
|
||||
- size_t diff = STRDIFF (s1, s2);
|
||||
- if (diff > 0)
|
||||
- {
|
||||
- if (encoding == __cet_utf8 && (*(s1 + diff) & MASK_UTF8_7BIT) != 0)
|
||||
- do
|
||||
- diff--;
|
||||
- while (diff > 0 && (*(s1 + diff) & MASK_UTF8_START) != MASK_UTF8_START);
|
||||
- s1 += diff;
|
||||
- s2 += diff;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Catch empty strings. */
|
||||
if (__glibc_unlikely (*s1 == '\0') || __glibc_unlikely (*s2 == '\0'))
|
||||
return (*s1 != '\0') - (*s2 != '\0');
|
||||
@@ -358,8 +323,7 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
|
||||
byte-level comparison to ensure that we don't waste time
|
||||
going through multiple passes for totally equal strings
|
||||
before proceeding to subsequent passes. */
|
||||
- if (pass == 0 && encoding == __cet_other &&
|
||||
- STRCMP (s1, s2) == 0)
|
||||
+ if (pass == 0 && STRCMP (s1, s2) == 0)
|
||||
return result;
|
||||
else
|
||||
break;
|
||||
diff --git a/wcsmbs/wcscoll_l.c b/wcsmbs/wcscoll_l.c
|
||||
index 6d9384a..87f240d 100644
|
||||
--- a/wcsmbs/wcscoll_l.c
|
||||
+++ b/wcsmbs/wcscoll_l.c
|
||||
@@ -23,7 +23,6 @@
|
||||
#define STRING_TYPE wchar_t
|
||||
#define USTRING_TYPE wint_t
|
||||
#define STRCOLL __wcscoll_l
|
||||
-#define STRDIFF __wcsdiff
|
||||
#define STRCMP __wcscmp
|
||||
#define WEIGHT_H "../locale/weightwc.h"
|
||||
#define SUFFIX WC
|
||||
--
|
||||
1.9.4
|
||||
|
Loading…
x
Reference in New Issue
Block a user