diff --git a/0001-nptl-Fix-pthread_rwlock_try-lock-stalls-Bug-23844.patch b/0001-nptl-Fix-pthread_rwlock_try-lock-stalls-Bug-23844.patch new file mode 100644 index 0000000..9a121ad --- /dev/null +++ b/0001-nptl-Fix-pthread_rwlock_try-lock-stalls-Bug-23844.patch @@ -0,0 +1,683 @@ +From 86013ef5cea322b8f4b9c22f230c22cce369e947 Mon Sep 17 00:00:00 2001 +From: Carlos O'Donell +Date: Mon, 21 Jan 2019 22:50:12 -0500 +Subject: [PATCH 01/11] nptl: Fix pthread_rwlock_try*lock stalls (Bug 23844) + +For a full analysis of both the pthread_rwlock_tryrdlock() stall +and the pthread_rwlock_trywrlock() stall see: +https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14 + +In the pthread_rwlock_trydlock() function we fail to inspect for +PTHREAD_RWLOCK_FUTEX_USED in __wrphase_futex and wake the waiting +readers. + +In the pthread_rwlock_trywrlock() function we write 1 to +__wrphase_futex and loose the setting of the PTHREAD_RWLOCK_FUTEX_USED +bit, again failing to wake waiting readers during unlock. + +The fix in the case of pthread_rwlock_trydlock() is to check for +PTHREAD_RWLOCK_FUTEX_USED and wake the readers. + +The fix in the case of pthread_rwlock_trywrlock() is to only write +1 to __wrphase_futex if we installed the write phase, since all other +readers would be spinning waiting for this step. + +We add two new tests, one exercises the stall for +pthread_rwlock_trywrlock() which is easy to exercise, and one exercises +the stall for pthread_rwlock_trydlock() which is harder to exercise. + +The pthread_rwlock_trywrlock() test fails consistently without the fix, +and passes after. The pthread_rwlock_tryrdlock() test fails roughly +5-10% of the time without the fix, and passes all the time after. + +Signed-off-by: Carlos O'Donell +Signed-off-by: Torvald Riegel +Signed-off-by: Rik Prohaska +Co-authored-by: Torvald Riegel +Co-authored-by: Rik Prohaska +(cherry picked from commit 5fc9ed4c4058bfbdf51ad6e7aac7d209b580e8c4) +--- + ChangeLog | 17 ++ + nptl/Makefile | 3 +- + nptl/pthread_rwlock_tryrdlock.c | 25 ++- + nptl/pthread_rwlock_trywrlock.c | 9 +- + nptl/tst-rwlock-tryrdlock-stall.c | 355 ++++++++++++++++++++++++++++++ + nptl/tst-rwlock-trywrlock-stall.c | 108 +++++++++ + support/Makefile | 1 + + support/xpthread_rwlock_destroy.c | 26 +++ + support/xthread.h | 1 + + 9 files changed, 534 insertions(+), 11 deletions(-) + create mode 100644 nptl/tst-rwlock-tryrdlock-stall.c + create mode 100644 nptl/tst-rwlock-trywrlock-stall.c + create mode 100644 support/xpthread_rwlock_destroy.c + +diff --git a/ChangeLog b/ChangeLog +index 59dab18463..adb4e719a6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,20 @@ ++2019-01-31 Carlos O'Donell ++ Torvald Riegel ++ Rik Prohaska ++ ++ [BZ# 23844] ++ * nptl/Makefile (tests): Add tst-rwlock-tryrdlock-stall, and ++ tst-rwlock-trywrlock-stall. ++ * nptl/pthread_rwlock_tryrdlock.c (__pthread_rwlock_tryrdlock): ++ Wake waiters if PTHREAD_RWLOCK_FUTEX_USED is set. ++ * nptl/pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock): ++ Set __wrphase_fute to 1 only if we started the write phase. ++ * nptl/tst-rwlock-tryrdlock-stall.c: New file. ++ * nptl/tst-rwlock-trywrlock-stall.c: New file. ++ * support/Makefile (libsupport-routines): Add xpthread_rwlock_destroy. ++ * support/xpthread_rwlock_destroy.c: New file. ++ * support/xthread.h: Declare xpthread_rwlock_destroy. ++ + 2019-01-31 Siddhesh Poyarekar + + * version.h (RELEASE): Set to "stable". +diff --git a/nptl/Makefile b/nptl/Makefile +index 340282c6cb..0e316edfac 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -319,7 +319,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \ + tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \ +- tst-rwlock-pwn ++ tst-rwlock-pwn \ ++ tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall + + tests-internal := tst-rwlock19 tst-rwlock20 \ + tst-sem11 tst-sem12 tst-sem13 \ +diff --git a/nptl/pthread_rwlock_tryrdlock.c b/nptl/pthread_rwlock_tryrdlock.c +index 368862ff07..2f94f17f36 100644 +--- a/nptl/pthread_rwlock_tryrdlock.c ++++ b/nptl/pthread_rwlock_tryrdlock.c +@@ -94,15 +94,22 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) + /* Same as in __pthread_rwlock_rdlock_full: + We started the read phase, so we are also responsible for + updating the write-phase futex. Relaxed MO is sufficient. +- Note that there can be no other reader that we have to wake +- because all other readers will see the read phase started by us +- (or they will try to start it themselves); if a writer started +- the read phase, we cannot have started it. Furthermore, we +- cannot discard a PTHREAD_RWLOCK_FUTEX_USED flag because we will +- overwrite the value set by the most recent writer (or the readers +- before it in case of explicit hand-over) and we know that there +- are no waiting readers. */ +- atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0); ++ We have to do the same steps as a writer would when handing over the ++ read phase to use because other readers cannot distinguish between ++ us and the writer. ++ Note that __pthread_rwlock_tryrdlock callers will not have to be ++ woken up because they will either see the read phase started by us ++ or they will try to start it themselves; however, callers of ++ __pthread_rwlock_rdlock_full just increase the reader count and then ++ check what state the lock is in, so they cannot distinguish between ++ us and a writer that acquired and released the lock in the ++ meantime. */ ++ if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) ++ & PTHREAD_RWLOCK_FUTEX_USED) != 0) ++ { ++ int private = __pthread_rwlock_get_private (rwlock); ++ futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); ++ } + } + + return 0; +diff --git a/nptl/pthread_rwlock_trywrlock.c b/nptl/pthread_rwlock_trywrlock.c +index fd37a71ce4..fae475cc70 100644 +--- a/nptl/pthread_rwlock_trywrlock.c ++++ b/nptl/pthread_rwlock_trywrlock.c +@@ -46,8 +46,15 @@ __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) + &rwlock->__data.__readers, &r, + r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED)) + { ++ /* We have become the primary writer and we cannot have shared ++ the PTHREAD_RWLOCK_FUTEX_USED flag with someone else, so we ++ can simply enable blocking (see full wrlock code). */ + atomic_store_relaxed (&rwlock->__data.__writers_futex, 1); +- atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); ++ /* If we started a write phase, we need to enable readers to ++ wait. If we did not, we must not change it because other threads ++ may have set the PTHREAD_RWLOCK_FUTEX_USED in the meantime. */ ++ if ((r & PTHREAD_RWLOCK_WRPHASE) == 0) ++ atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); + atomic_store_relaxed (&rwlock->__data.__cur_writer, + THREAD_GETMEM (THREAD_SELF, tid)); + return 0; +diff --git a/nptl/tst-rwlock-tryrdlock-stall.c b/nptl/tst-rwlock-tryrdlock-stall.c +new file mode 100644 +index 0000000000..5e476da2b8 +--- /dev/null ++++ b/nptl/tst-rwlock-tryrdlock-stall.c +@@ -0,0 +1,355 @@ ++/* Bug 23844: Test for pthread_rwlock_tryrdlock stalls. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* For a full analysis see comment: ++ https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14 ++ ++ Provided here for reference: ++ ++ --- Analysis of pthread_rwlock_tryrdlock() stall --- ++ A read lock begins to execute. ++ ++ In __pthread_rwlock_rdlock_full: ++ ++ We can attempt a read lock, but find that the lock is ++ in a write phase (PTHREAD_RWLOCK_WRPHASE, or WP-bit ++ is set), and the lock is held by a primary writer ++ (PTHREAD_RWLOCK_WRLOCKED is set). In this case we must ++ wait for explicit hand over from the writer to us or ++ one of the other waiters. The read lock threads are ++ about to execute: ++ ++ 341 r = (atomic_fetch_add_acquire (&rwlock->__data.__readers, ++ 342 (1 << PTHREAD_RWLOCK_READER_SHIFT)) ++ 343 + (1 << PTHREAD_RWLOCK_READER_SHIFT)); ++ ++ An unlock beings to execute. ++ ++ Then in __pthread_rwlock_wrunlock: ++ ++ 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); ++ ... ++ 549 while (!atomic_compare_exchange_weak_release ++ 550 (&rwlock->__data.__readers, &r, ++ 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED) ++ 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 ++ 553 : PTHREAD_RWLOCK_WRPHASE)))) ++ 554 { ++ ... ++ 556 } ++ ++ We clear PTHREAD_RWLOCK_WRLOCKED, and if there are ++ no readers so we leave the lock in PTHRAD_RWLOCK_WRPHASE. ++ ++ Back in the read lock. ++ ++ The read lock adjusts __readres as above. ++ ++ 383 while ((r & PTHREAD_RWLOCK_WRPHASE) != 0 ++ 384 && (r & PTHREAD_RWLOCK_WRLOCKED) == 0) ++ 385 { ++ ... ++ 390 if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r, ++ 391 r ^ PTHREAD_RWLOCK_WRPHASE)) ++ 392 { ++ ++ And then attemps to start the read phase. ++ ++ Assume there happens to be a tryrdlock at this point, noting ++ that PTHREAD_RWLOCK_WRLOCKED is clear, and PTHREAD_RWLOCK_WRPHASE ++ is 1. So the try lock attemps to start the read phase. ++ ++ In __pthread_rwlock_tryrdlock: ++ ++ 44 if ((r & PTHREAD_RWLOCK_WRPHASE) == 0) ++ 45 { ++ ... ++ 49 if (((r & PTHREAD_RWLOCK_WRLOCKED) != 0) ++ 50 && (rwlock->__data.__flags ++ 51 == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) ++ 52 return EBUSY; ++ 53 rnew = r + (1 << PTHREAD_RWLOCK_READER_SHIFT); ++ 54 } ++ ... ++ 89 while (!atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, ++ 90 &r, rnew)); ++ ++ And succeeds. ++ ++ Back in the write unlock: ++ ++ 557 if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0) ++ 558 { ++ ... ++ 563 if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) ++ 564 & PTHREAD_RWLOCK_FUTEX_USED) != 0) ++ 565 futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); ++ 566 } ++ ++ We note that PTHREAD_RWLOCK_FUTEX_USED is non-zero ++ and don't wake anyone. This is OK because we handed ++ over to the trylock. It will be the trylock's responsibility ++ to wake any waiters. ++ ++ Back in the read lock: ++ ++ The read lock fails to install PTHRAD_REWLOCK_WRPHASE as 0 because ++ the __readers value was adjusted by the trylock, and so it falls through ++ to waiting on the lock for explicit handover from either a new writer ++ or a new reader. ++ ++ 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, ++ 449 1 | PTHREAD_RWLOCK_FUTEX_USED, ++ 450 abstime, private); ++ ++ We use PTHREAD_RWLOCK_FUTEX_USED to indicate the futex ++ is in use. ++ ++ At this point we have readers waiting on the read lock ++ to unlock. The wrlock is done. The trylock is finishing ++ the installation of the read phase. ++ ++ 92 if ((r & PTHREAD_RWLOCK_WRPHASE) != 0) ++ 93 { ++ ... ++ 105 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0); ++ 106 } ++ ++ The trylock does note that we were the one that ++ installed the read phase, but the comments are not ++ correct, the execution ordering above shows that ++ readers might indeed be waiting, and they are. ++ ++ The atomic_store_relaxed throws away PTHREAD_RWLOCK_FUTEX_USED, ++ and the waiting reader is never worken becuase as noted ++ above it is conditional on the futex being used. ++ ++ The solution is for the trylock thread to inspect ++ PTHREAD_RWLOCK_FUTEX_USED and wake the waiting readers. ++ ++ --- Analysis of pthread_rwlock_trywrlock() stall --- ++ ++ A write lock begins to execute, takes the write lock, ++ and then releases the lock... ++ ++ In pthread_rwlock_wrunlock(): ++ ++ 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); ++ ... ++ 549 while (!atomic_compare_exchange_weak_release ++ 550 (&rwlock->__data.__readers, &r, ++ 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED) ++ 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0 ++ 553 : PTHREAD_RWLOCK_WRPHASE)))) ++ 554 { ++ ... ++ 556 } ++ ++ ... leaving it in the write phase with zero readers ++ (the case where we leave the write phase in place ++ during a write unlock). ++ ++ A write trylock begins to execute. ++ ++ In __pthread_rwlock_trywrlock: ++ ++ 40 while (((r & PTHREAD_RWLOCK_WRLOCKED) == 0) ++ 41 && (((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0) ++ 42 || (prefer_writer && ((r & PTHREAD_RWLOCK_WRPHASE) != 0)))) ++ 43 { ++ ++ The lock is not locked. ++ ++ There are no readers. ++ ++ 45 if (atomic_compare_exchange_weak_acquire ( ++ 46 &rwlock->__data.__readers, &r, ++ 47 r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED)) ++ ++ We atomically install the write phase and we take the ++ exclusive write lock. ++ ++ 48 { ++ 49 atomic_store_relaxed (&rwlock->__data.__writers_futex, 1); ++ ++ We get this far. ++ ++ A reader lock begins to execute. ++ ++ In pthread_rwlock_rdlock: ++ ++ 437 for (;;) ++ 438 { ++ 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) ++ 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) ++ 441 { ++ 442 int private = __pthread_rwlock_get_private (rwlock); ++ 443 if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0) ++ 444 && (!atomic_compare_exchange_weak_relaxed ++ 445 (&rwlock->__data.__wrphase_futex, ++ 446 &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED))) ++ 447 continue; ++ 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, ++ 449 1 | PTHREAD_RWLOCK_FUTEX_USED, ++ 450 abstime, private); ++ ++ We are in a write phase, so the while() on line 439 is true. ++ ++ The value of wpf does not have PTHREAD_RWLOCK_FUTEX_USED set ++ since this is the first reader to lock. ++ ++ The atomic operation sets wpf with PTHREAD_RELOCK_FUTEX_USED ++ on the expectation that this reader will be woken during ++ the handoff. ++ ++ Back in pthread_rwlock_trywrlock: ++ ++ 50 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1); ++ 51 atomic_store_relaxed (&rwlock->__data.__cur_writer, ++ 52 THREAD_GETMEM (THREAD_SELF, tid)); ++ 53 return 0; ++ 54 } ++ ... ++ 57 } ++ ++ We write 1 to __wrphase_futex discarding PTHREAD_RWLOCK_FUTEX_USED, ++ and so in the unlock we will not awaken the waiting reader. ++ ++ The solution to this is to realize that if we did not start the write ++ phase we need not write 1 or any other value to __wrphase_futex. ++ This ensures that any readers (which saw __wrphase_futex != 0) can ++ set PTHREAD_RWLOCK_FUTEX_USED and this can be used at unlock to ++ wake them. ++ ++ If we installed the write phase then all other readers are looping ++ here: ++ ++ In __pthread_rwlock_rdlock_full: ++ ++ 437 for (;;) ++ 438 { ++ 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) ++ 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED)) ++ 441 { ++ ... ++ 508 } ++ ++ waiting for the write phase to be installed or removed before they ++ can begin waiting on __wrphase_futex (part of the algorithm), or ++ taking a concurrent read lock, and thus we can safely write 1 to ++ __wrphase_futex. ++ ++ If we did not install the write phase then the readers may already ++ be waiting on the futex, the original writer wrote 1 to __wrphase_futex ++ as part of starting the write phase, and we cannot also write 1 ++ without loosing the PTHREAD_RWLOCK_FUTEX_USED bit. ++ ++ --- ++ ++ Summary for the pthread_rwlock_tryrdlock() stall: ++ ++ The stall is caused by pthread_rwlock_tryrdlock failing to check ++ that PTHREAD_RWLOCK_FUTEX_USED is set in the __wrphase_futex futex ++ and then waking the futex. ++ ++ The fix for bug 23844 ensures that waiters on __wrphase_futex are ++ correctly woken. Before the fix the test stalls as readers can ++ wait forever on __wrphase_futex. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* We need only one lock to reproduce the issue. We will need multiple ++ threads to get the exact case where we have a read, try, and unlock ++ all interleaving to produce the case where the readers are waiting ++ and the try fails to wake them. */ ++pthread_rwlock_t onelock; ++ ++/* The number of threads is arbitrary but empirically chosen to have ++ enough threads that we see the condition where waiting readers are ++ not woken by a successful tryrdlock. */ ++#define NTHREADS 32 ++ ++_Atomic int do_exit; ++ ++void * ++run_loop (void *arg) ++{ ++ int i = 0, ret; ++ while (!do_exit) ++ { ++ /* Arbitrarily choose if we are the writer or reader. Choose a ++ high enough ratio of readers to writers to make it likely ++ that readers block (and eventually are susceptable to ++ stalling). ++ ++ If we are a writer, take the write lock, and then unlock. ++ If we are a reader, try the lock, then lock, then unlock. */ ++ if ((i % 8) != 0) ++ xpthread_rwlock_wrlock (&onelock); ++ else ++ { ++ if ((ret = pthread_rwlock_tryrdlock (&onelock)) != 0) ++ { ++ if (ret == EBUSY) ++ xpthread_rwlock_rdlock (&onelock); ++ else ++ exit (EXIT_FAILURE); ++ } ++ } ++ /* Thread does some work and then unlocks. */ ++ xpthread_rwlock_unlock (&onelock); ++ i++; ++ } ++ return NULL; ++} ++ ++int ++do_test (void) ++{ ++ int i; ++ pthread_t tids[NTHREADS]; ++ xpthread_rwlock_init (&onelock, NULL); ++ for (i = 0; i < NTHREADS; i++) ++ tids[i] = xpthread_create (NULL, run_loop, NULL); ++ /* Run for some amount of time. Empirically speaking exercising ++ the stall via pthread_rwlock_tryrdlock is much harder, and on ++ a 3.5GHz 4 core x86_64 VM system it takes somewhere around ++ 20-200s to stall, approaching 100% stall past 200s. We can't ++ wait that long for a regression test so we just test for 20s, ++ and expect the stall to happen with a 5-10% chance (enough for ++ developers to see). */ ++ sleep (20); ++ /* Then exit. */ ++ printf ("INFO: Exiting...\n"); ++ do_exit = 1; ++ /* If any readers stalled then we will timeout waiting for them. */ ++ for (i = 0; i < NTHREADS; i++) ++ xpthread_join (tids[i]); ++ printf ("INFO: Done.\n"); ++ xpthread_rwlock_destroy (&onelock); ++ printf ("PASS: No pthread_rwlock_tryrdlock stalls detected.\n"); ++ return 0; ++} ++ ++#define TIMEOUT 30 ++#include +diff --git a/nptl/tst-rwlock-trywrlock-stall.c b/nptl/tst-rwlock-trywrlock-stall.c +new file mode 100644 +index 0000000000..14d27cbcbc +--- /dev/null ++++ b/nptl/tst-rwlock-trywrlock-stall.c +@@ -0,0 +1,108 @@ ++/* Bug 23844: Test for pthread_rwlock_trywrlock stalls. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* For a full analysis see comments in tst-rwlock-tryrdlock-stall.c. ++ ++ Summary for the pthread_rwlock_trywrlock() stall: ++ ++ The stall is caused by pthread_rwlock_trywrlock setting ++ __wrphase_futex futex to 1 and loosing the ++ PTHREAD_RWLOCK_FUTEX_USED bit. ++ ++ The fix for bug 23844 ensures that waiters on __wrphase_futex are ++ correctly woken. Before the fix the test stalls as readers can ++ wait forever on __wrphase_futex. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* We need only one lock to reproduce the issue. We will need multiple ++ threads to get the exact case where we have a read, try, and unlock ++ all interleaving to produce the case where the readers are waiting ++ and the try clears the PTHREAD_RWLOCK_FUTEX_USED bit and a ++ subsequent unlock fails to wake them. */ ++pthread_rwlock_t onelock; ++ ++/* The number of threads is arbitrary but empirically chosen to have ++ enough threads that we see the condition where waiting readers are ++ not woken by a successful unlock. */ ++#define NTHREADS 32 ++ ++_Atomic int do_exit; ++ ++void * ++run_loop (void *arg) ++{ ++ int i = 0, ret; ++ while (!do_exit) ++ { ++ /* Arbitrarily choose if we are the writer or reader. Choose a ++ high enough ratio of readers to writers to make it likely ++ that readers block (and eventually are susceptable to ++ stalling). ++ ++ If we are a writer, take the write lock, and then unlock. ++ If we are a reader, try the lock, then lock, then unlock. */ ++ if ((i % 8) != 0) ++ { ++ if ((ret = pthread_rwlock_trywrlock (&onelock)) != 0) ++ { ++ if (ret == EBUSY) ++ xpthread_rwlock_wrlock (&onelock); ++ else ++ exit (EXIT_FAILURE); ++ } ++ } ++ else ++ xpthread_rwlock_rdlock (&onelock); ++ /* Thread does some work and then unlocks. */ ++ xpthread_rwlock_unlock (&onelock); ++ i++; ++ } ++ return NULL; ++} ++ ++int ++do_test (void) ++{ ++ int i; ++ pthread_t tids[NTHREADS]; ++ xpthread_rwlock_init (&onelock, NULL); ++ for (i = 0; i < NTHREADS; i++) ++ tids[i] = xpthread_create (NULL, run_loop, NULL); ++ /* Run for some amount of time. The pthread_rwlock_tryrwlock stall ++ is very easy to trigger and happens in seconds under the test ++ conditions. */ ++ sleep (10); ++ /* Then exit. */ ++ printf ("INFO: Exiting...\n"); ++ do_exit = 1; ++ /* If any readers stalled then we will timeout waiting for them. */ ++ for (i = 0; i < NTHREADS; i++) ++ xpthread_join (tids[i]); ++ printf ("INFO: Done.\n"); ++ xpthread_rwlock_destroy (&onelock); ++ printf ("PASS: No pthread_rwlock_tryrwlock stalls detected.\n"); ++ return 0; ++} ++ ++#include +diff --git a/support/Makefile b/support/Makefile +index 432cf2fe6c..c15b93647c 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -129,6 +129,7 @@ libsupport-routines = \ + xpthread_mutexattr_settype \ + xpthread_once \ + xpthread_rwlock_init \ ++ xpthread_rwlock_destroy \ + xpthread_rwlock_rdlock \ + xpthread_rwlock_unlock \ + xpthread_rwlock_wrlock \ +diff --git a/support/xpthread_rwlock_destroy.c b/support/xpthread_rwlock_destroy.c +new file mode 100644 +index 0000000000..6d6e953569 +--- /dev/null ++++ b/support/xpthread_rwlock_destroy.c +@@ -0,0 +1,26 @@ ++/* pthread_rwlock_destroy with error checking. ++ Copyright (C) 2019 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 ++ . */ ++ ++#include ++ ++void ++xpthread_rwlock_destroy (pthread_rwlock_t *rwlock) ++{ ++ xpthread_check_return ("pthread_rwlock_destroy", ++ pthread_rwlock_destroy (rwlock)); ++} +diff --git a/support/xthread.h b/support/xthread.h +index 47c23235f3..9fe1f68b3b 100644 +--- a/support/xthread.h ++++ b/support/xthread.h +@@ -84,6 +84,7 @@ void xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref); + void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock); + void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock); + void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock); ++void xpthread_rwlock_destroy (pthread_rwlock_t *rwlock); + + __END_DECLS + +-- +2.21.0 + diff --git a/0002-x86-64-memcmp-Use-unsigned-Jcc-instructions-on-size-.patch b/0002-x86-64-memcmp-Use-unsigned-Jcc-instructions-on-size-.patch new file mode 100644 index 0000000..0960bde --- /dev/null +++ b/0002-x86-64-memcmp-Use-unsigned-Jcc-instructions-on-size-.patch @@ -0,0 +1,250 @@ +From 726a78867b3144e9b9da10197bcf59bde3d8b2a4 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Mon, 4 Feb 2019 08:55:52 -0800 +Subject: [PATCH 02/11] x86-64 memcmp: Use unsigned Jcc instructions on size + [BZ #24155] + +Since the size argument is unsigned. we should use unsigned Jcc +instructions, instead of signed, to check size. + +Tested on x86-64 and x32, with and without --disable-multi-arch. + + [BZ #24155] + CVE-2019-7309 + * NEWS: Updated for CVE-2019-7309. + * sysdeps/x86_64/memcmp.S: Use RDX_LP for size. Clear the + upper 32 bits of RDX register for x32. Use unsigned Jcc + instructions, instead of signed. + * sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcmp-2. + * sysdeps/x86_64/x32/tst-size_t-memcmp-2.c: New test. + +(cherry picked from commit 3f635fb43389b54f682fc9ed2acc0b2aaf4a923d) +--- + ChangeLog | 11 ++++ + NEWS | 17 +++++ + sysdeps/x86_64/memcmp.S | 20 +++--- + sysdeps/x86_64/x32/Makefile | 3 +- + sysdeps/x86_64/x32/tst-size_t-memcmp-2.c | 79 ++++++++++++++++++++++++ + 5 files changed, 121 insertions(+), 9 deletions(-) + create mode 100644 sysdeps/x86_64/x32/tst-size_t-memcmp-2.c + +diff --git a/ChangeLog b/ChangeLog +index adb4e719a6..e0969afd80 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,14 @@ ++2019-02-04 H.J. Lu ++ ++ [BZ #24155] ++ CVE-2019-7309 ++ * NEWS: Updated for CVE-2019-7309. ++ * sysdeps/x86_64/memcmp.S: Use RDX_LP for size. Clear the ++ upper 32 bits of RDX register for x32. Use unsigned Jcc ++ instructions, instead of signed. ++ * sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcmp-2. ++ * sysdeps/x86_64/x32/tst-size_t-memcmp-2.c: New test. ++ + 2019-01-31 Carlos O'Donell + Torvald Riegel + Rik Prohaska +diff --git a/NEWS b/NEWS +index 912a9bdc0f..1751ed118a 100644 +--- a/NEWS ++++ b/NEWS +@@ -5,6 +5,23 @@ See the end for copying conditions. + Please send GNU C library bug reports via + using `glibc' in the "product" field. + ++Version 2.29.1 ++ ++The following bugs are resolved with this release: ++ ++ [24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309) ++ ++Security related changes: ++ ++ CVE-2019-7309: x86-64 memcmp used signed Jcc instructions to check ++ size. For x86-64, memcmp on an object size larger than SSIZE_MAX ++ has undefined behavior. On x32, the size_t argument may be passed ++ in the lower 32 bits of the 64-bit RDX register with non-zero upper ++ 32 bits. When it happened with the sign bit of RDX register set, ++ memcmp gave the wrong result since it treated the size argument as ++ zero. Reported by H.J. Lu. ++ ++ + Version 2.29 + + Major new features: +diff --git a/sysdeps/x86_64/memcmp.S b/sysdeps/x86_64/memcmp.S +index 1fc487caa5..1322bb3b92 100644 +--- a/sysdeps/x86_64/memcmp.S ++++ b/sysdeps/x86_64/memcmp.S +@@ -21,14 +21,18 @@ + + .text + ENTRY (memcmp) +- test %rdx, %rdx ++#ifdef __ILP32__ ++ /* Clear the upper 32 bits. */ ++ movl %edx, %edx ++#endif ++ test %RDX_LP, %RDX_LP + jz L(finz) + cmpq $1, %rdx +- jle L(finr1b) ++ jbe L(finr1b) + subq %rdi, %rsi + movq %rdx, %r10 + cmpq $32, %r10 +- jge L(gt32) ++ jae L(gt32) + /* Handle small chunks and last block of less than 32 bytes. */ + L(small): + testq $1, %r10 +@@ -156,7 +160,7 @@ L(A32): + movq %r11, %r10 + andq $-32, %r10 + cmpq %r10, %rdi +- jge L(mt16) ++ jae L(mt16) + /* Pre-unroll to be ready for unrolled 64B loop. */ + testq $32, %rdi + jz L(A64) +@@ -178,7 +182,7 @@ L(A64): + movq %r11, %r10 + andq $-64, %r10 + cmpq %r10, %rdi +- jge L(mt32) ++ jae L(mt32) + + L(A64main): + movdqu (%rdi,%rsi), %xmm0 +@@ -216,7 +220,7 @@ L(mt32): + movq %r11, %r10 + andq $-32, %r10 + cmpq %r10, %rdi +- jge L(mt16) ++ jae L(mt16) + + L(A32main): + movdqu (%rdi,%rsi), %xmm0 +@@ -254,7 +258,7 @@ L(ATR): + movq %r11, %r10 + andq $-32, %r10 + cmpq %r10, %rdi +- jge L(mt16) ++ jae L(mt16) + testq $16, %rdi + jz L(ATR32) + +@@ -325,7 +329,7 @@ L(ATR64main): + movq %r11, %r10 + andq $-32, %r10 + cmpq %r10, %rdi +- jge L(mt16) ++ jae L(mt16) + + L(ATR32res): + movdqa (%rdi,%rsi), %xmm0 +diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile +index 1557724b0c..8748956563 100644 +--- a/sysdeps/x86_64/x32/Makefile ++++ b/sysdeps/x86_64/x32/Makefile +@@ -8,7 +8,8 @@ endif + ifeq ($(subdir),string) + tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy \ + tst-size_t-memrchr tst-size_t-memset tst-size_t-strncasecmp \ +- tst-size_t-strncmp tst-size_t-strncpy tst-size_t-strnlen ++ tst-size_t-strncmp tst-size_t-strncpy tst-size_t-strnlen \ ++ tst-size_t-memcmp-2 + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/x86_64/x32/tst-size_t-memcmp-2.c b/sysdeps/x86_64/x32/tst-size_t-memcmp-2.c +new file mode 100644 +index 0000000000..d8ae1a0813 +--- /dev/null ++++ b/sysdeps/x86_64/x32/tst-size_t-memcmp-2.c +@@ -0,0 +1,79 @@ ++/* Test memcmp with size_t in the lower 32 bits of 64-bit register. ++ Copyright (C) 2019 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 ++ . */ ++ ++#define TEST_MAIN ++#ifdef WIDE ++# define TEST_NAME "wmemcmp" ++#else ++# define TEST_NAME "memcmp" ++#endif ++ ++#include "test-size_t.h" ++ ++#ifdef WIDE ++# include ++# include ++ ++# define MEMCMP wmemcmp ++# define CHAR wchar_t ++#else ++# define MEMCMP memcmp ++# define CHAR char ++#endif ++ ++IMPL (MEMCMP, 1) ++ ++typedef int (*proto_t) (const CHAR *, const CHAR *, size_t); ++ ++static int ++__attribute__ ((noinline, noclone)) ++do_memcmp (parameter_t a, parameter_t b) ++{ ++ return CALL (&b, a.p, b.p, a.len); ++} ++ ++static int ++test_main (void) ++{ ++ test_init (); ++ ++ parameter_t dest = { { page_size / sizeof (CHAR) }, buf1 }; ++ parameter_t src = { { 0 }, buf2 }; ++ ++ memcpy (buf1, buf2, page_size); ++ ++ CHAR *p = (CHAR *) buf1; ++ p[page_size / sizeof (CHAR) - 1] = (CHAR) 1; ++ ++ int ret = 0; ++ FOR_EACH_IMPL (impl, 0) ++ { ++ src.fn = impl->fn; ++ int res = do_memcmp (dest, src); ++ if (res >= 0) ++ { ++ error (0, 0, "Wrong result in function %s: %i >= 0", ++ impl->name, res); ++ ret = 1; ++ } ++ } ++ ++ return ret ? EXIT_FAILURE : EXIT_SUCCESS; ++} ++ ++#include +-- +2.21.0 + diff --git a/0003-arm-Use-nr-constraint-for-Systemtap-probes-BZ-24164.patch b/0003-arm-Use-nr-constraint-for-Systemtap-probes-BZ-24164.patch new file mode 100644 index 0000000..e156eff --- /dev/null +++ b/0003-arm-Use-nr-constraint-for-Systemtap-probes-BZ-24164.patch @@ -0,0 +1,121 @@ +From 2de15ac95713a238dc258eb8977ecdfca811fc19 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Tue, 5 Feb 2019 13:49:02 +0100 +Subject: [PATCH 03/11] arm: Use "nr" constraint for Systemtap probes [BZ + #24164] + +With the default "nor" constraint, current GCC will use the "o" +constraint for constants, after emitting the constant to memory. That +results in unparseable Systemtap probe notes such as "-4@.L1052". +Removing the "o" alternative and using "nr" instead avoids this. + +(cherry picked from commit f1ac7455831546e5dca0ed98fe8af2686fae7ce6) +--- + ChangeLog | 11 +++++++++++ + NEWS | 1 + + include/stap-probe.h | 1 + + sysdeps/arm/stap-probe-machine.h | 22 ++++++++++++++++++++++ + sysdeps/generic/stap-probe-machine.h | 19 +++++++++++++++++++ + 5 files changed, 54 insertions(+) + create mode 100644 sysdeps/arm/stap-probe-machine.h + create mode 100644 sysdeps/generic/stap-probe-machine.h + +diff --git a/ChangeLog b/ChangeLog +index e0969afd80..9517ff9e82 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,14 @@ ++2019-02-05 Florian Weimer ++ ++ [BZ #24164] ++ arm: Use "nr" constraint for Systemtap probes, to avoid the ++ compiler using memory operands for constants, due to the "o" ++ alternative in the default "nor" constraint. ++ * include/stap-probe.h [USE_STAP_PROBE]: Include ++ ++ * sysdeps/generic/stap-probe-machine.h: New file. ++ * sysdeps/arm/stap-probe-machine.h: Likewise. ++ + 2019-02-04 H.J. Lu + + [BZ #24155] +diff --git a/NEWS b/NEWS +index 1751ed118a..1f0fc4b3cb 100644 +--- a/NEWS ++++ b/NEWS +@@ -10,6 +10,7 @@ Version 2.29.1 + The following bugs are resolved with this release: + + [24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309) ++ [24164] Systemtap probes need to use "nr" constraint on 32-bit Arm + + Security related changes: + +diff --git a/include/stap-probe.h b/include/stap-probe.h +index c53dd86592..8c26292edd 100644 +--- a/include/stap-probe.h ++++ b/include/stap-probe.h +@@ -21,6 +21,7 @@ + + #ifdef USE_STAP_PROBE + ++# include + # include + + /* Our code uses one macro LIBC_PROBE (name, n, arg1, ..., argn). +diff --git a/sysdeps/arm/stap-probe-machine.h b/sysdeps/arm/stap-probe-machine.h +new file mode 100644 +index 0000000000..d27ca22040 +--- /dev/null ++++ b/sysdeps/arm/stap-probe-machine.h +@@ -0,0 +1,22 @@ ++/* Macros for customizing Systemtap . Arm version. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* The default "nor" constraint produces unparseable memory references ++ for constants. Omit the problematic "o" constraint. See bug 24164 ++ and GCC PR 89146. */ ++#define STAP_SDT_ARG_CONSTRAINT nr +diff --git a/sysdeps/generic/stap-probe-machine.h b/sysdeps/generic/stap-probe-machine.h +new file mode 100644 +index 0000000000..2e5790c3b2 +--- /dev/null ++++ b/sysdeps/generic/stap-probe-machine.h +@@ -0,0 +1,19 @@ ++/* Macros for customizing Systemtap . Generic version. ++ Copyright (C) 2019 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 ++ . */ ++ ++/* By default, there are no customizations. */ +-- +2.21.0 + diff --git a/0004-Add-compiler-barriers-around-modifications-of-the-ro.patch b/0004-Add-compiler-barriers-around-modifications-of-the-ro.patch new file mode 100644 index 0000000..f7a2766 --- /dev/null +++ b/0004-Add-compiler-barriers-around-modifications-of-the-ro.patch @@ -0,0 +1,223 @@ +From 44113a8ba24af23d7bbb174f9087a6b83a76289a Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 7 Feb 2019 15:18:36 +0100 +Subject: [PATCH 04/11] Add compiler barriers around modifications of the + robust mutex list for pthread_mutex_trylock. [BZ #24180] + +While debugging a kernel warning, Thomas Gleixner, Sebastian Sewior and +Heiko Carstens found a bug in pthread_mutex_trylock due to misordered +instructions: +140: a5 1b 00 01 oill %r1,1 +144: e5 48 a0 f0 00 00 mvghi 240(%r10),0 <--- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); +14a: e3 10 a0 e0 00 24 stg %r1,224(%r10) <--- last THREAD_SETMEM of ENQUEUE_MUTEX_PI + +vs (with compiler barriers): +140: a5 1b 00 01 oill %r1,1 +144: e3 10 a0 e0 00 24 stg %r1,224(%r10) +14a: e5 48 a0 f0 00 00 mvghi 240(%r10),0 + +Please have a look at the discussion: +"Re: WARN_ON_ONCE(!new_owner) within wake_futex_pi() triggerede" +(https://lore.kernel.org/lkml/20190202112006.GB3381@osiris/) + +This patch is introducing the same compiler barriers and comments +for pthread_mutex_trylock as introduced for pthread_mutex_lock and +pthread_mutex_timedlock by commit 8f9450a0b7a9e78267e8ae1ab1000ebca08e473e +"Add compiler barriers around modifications of the robust mutex list." + +ChangeLog: + + [BZ #24180] + * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): + Add compiler barriers and comments. + +(cherry picked from commit 823624bdc47f1f80109c9c52dee7939b9386d708) +--- + ChangeLog | 6 ++++ + nptl/pthread_mutex_trylock.c | 57 +++++++++++++++++++++++++++++++++--- + 2 files changed, 59 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 9517ff9e82..7a8895bcc6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2019-02-07 Stefan Liebler ++ ++ [BZ #24180] ++ * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): ++ Add compiler barriers and comments. ++ + 2019-02-05 Florian Weimer + + [BZ #24164] +diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c +index 8fe43b8f0f..bf2869eca2 100644 +--- a/nptl/pthread_mutex_trylock.c ++++ b/nptl/pthread_mutex_trylock.c +@@ -94,6 +94,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP: + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + &mutex->__data.__list.__next); ++ /* We need to set op_pending before starting the operation. Also ++ see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + + oldval = mutex->__data.__lock; + do +@@ -119,7 +122,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + /* But it is inconsistent unless marked otherwise. */ + mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Note that we deliberately exist here. If we fall +@@ -135,6 +143,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + int kind = PTHREAD_MUTEX_TYPE (mutex); + if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. Also see comments at ENQUEUE_MUTEX. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + return EDEADLK; +@@ -142,6 +152,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + + if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + +@@ -160,6 +172,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + id, 0); + if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0) + { ++ /* We haven't acquired the lock as it is already acquired by ++ another owner. We do not need to ensure ordering wrt another ++ memory access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -173,13 +188,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + if (oldval == id) + lll_unlock (mutex->__data.__lock, + PTHREAD_ROBUST_MUTEX_PSHARED (mutex)); ++ /* FIXME This violates the mutex destruction requirements. See ++ __pthread_mutex_unlock_full. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return ENOTRECOVERABLE; + } + } + while ((oldval & FUTEX_OWNER_DIED) != 0); + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + mutex->__data.__owner = id; +@@ -211,10 +233,15 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + } + + if (robust) +- /* Note: robust PI futexes are signaled by setting bit 0. */ +- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, +- (void *) (((uintptr_t) &mutex->__data.__list.__next) +- | 1)); ++ { ++ /* Note: robust PI futexes are signaled by setting bit 0. */ ++ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, ++ (void *) (((uintptr_t) &mutex->__data.__list.__next) ++ | 1)); ++ /* We need to set op_pending before starting the operation. Also ++ see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); ++ } + + oldval = mutex->__data.__lock; + +@@ -223,12 +250,16 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + { + if (kind == PTHREAD_MUTEX_ERRORCHECK_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return EDEADLK; + } + + if (kind == PTHREAD_MUTEX_RECURSIVE_NP) + { ++ /* We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Just bump the counter. */ +@@ -250,6 +281,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + { + if ((oldval & FUTEX_OWNER_DIED) == 0) + { ++ /* We haven't acquired the lock as it is already acquired by ++ another owner. We do not need to ensure ordering wrt another ++ memory access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -270,6 +304,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + if (INTERNAL_SYSCALL_ERROR_P (e, __err) + && INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK) + { ++ /* The kernel has not yet finished the mutex owner death. ++ We do not need to ensure ordering wrt another memory ++ access. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; +@@ -287,7 +324,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + /* But it is inconsistent unless marked otherwise. */ + mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; + ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + /* Note that we deliberately exit here. If we fall +@@ -310,13 +352,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + PTHREAD_ROBUST_MUTEX_PSHARED (mutex)), + 0, 0); + ++ /* To the kernel, this will be visible after the kernel has ++ acquired the mutex in the syscall. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + return ENOTRECOVERABLE; + } + + if (robust) + { ++ /* We must not enqueue the mutex before we have acquired it. ++ Also see comments at ENQUEUE_MUTEX. */ ++ __asm ("" ::: "memory"); + ENQUEUE_MUTEX_PI (mutex); ++ /* We need to clear op_pending after we enqueue the mutex. */ ++ __asm ("" ::: "memory"); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + } + +-- +2.21.0 + diff --git a/0005-nptl-Avoid-fork-handler-lock-for-async-signal-safe-f.patch b/0005-nptl-Avoid-fork-handler-lock-for-async-signal-safe-f.patch new file mode 100644 index 0000000..a1918a1 --- /dev/null +++ b/0005-nptl-Avoid-fork-handler-lock-for-async-signal-safe-f.patch @@ -0,0 +1,159 @@ +From c096b008d2671028c21ac8cf01f18a2083e73c44 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Fri, 8 Feb 2019 12:54:41 +0100 +Subject: [PATCH 05/11] nptl: Avoid fork handler lock for async-signal-safe + fork [BZ #24161] + +Commit 27761a1042daf01987e7d79636d0c41511c6df3c ("Refactor atfork +handlers") introduced a lock, atfork_lock, around fork handler list +accesses. It turns out that this lock occasionally results in +self-deadlocks in malloc/tst-mallocfork2: + +(gdb) bt +#0 __lll_lock_wait_private () + at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:63 +#1 0x00007f160c6f927a in __run_fork_handlers (who=(unknown: 209394016), + who@entry=atfork_run_prepare) at register-atfork.c:116 +#2 0x00007f160c6b7897 in __libc_fork () at ../sysdeps/nptl/fork.c:58 +#3 0x00000000004027d6 in sigusr1_handler (signo=) + at tst-mallocfork2.c:80 +#4 sigusr1_handler (signo=) at tst-mallocfork2.c:64 +#5 +#6 0x00007f160c6f92e4 in __run_fork_handlers (who=who@entry=atfork_run_parent) + at register-atfork.c:136 +#7 0x00007f160c6b79a2 in __libc_fork () at ../sysdeps/nptl/fork.c:152 +#8 0x0000000000402567 in do_test () at tst-mallocfork2.c:156 +#9 0x0000000000402dd2 in support_test_main (argc=1, argv=0x7ffc81ef1ab0, + config=config@entry=0x7ffc81ef1970) at support_test_main.c:350 +#10 0x0000000000402362 in main (argc=, argv=) + at ../support/test-driver.c:168 + +If no locking happens in the single-threaded case (where fork is +expected to be async-signal-safe), this deadlock is avoided. +(pthread_atfork is not required to be async-signal-safe, so a fork +call from a signal handler interrupting pthread_atfork is not +a problem.) + +(cherry picked from commit 669ff911e2571f74a2668493e326ac9a505776bd) +--- + ChangeLog | 10 ++++++++++ + NEWS | 1 + + nptl/register-atfork.c | 8 +++++--- + sysdeps/nptl/fork.c | 6 +++--- + sysdeps/nptl/fork.h | 8 +++++--- + 5 files changed, 24 insertions(+), 9 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7a8895bcc6..d363be4620 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,13 @@ ++2019-02-08 Florian Weimer ++ ++ [BZ #24161] ++ * sysdeps/nptl/fork.h (__run_fork_handlers): Add multiple_threads ++ argument. ++ * nptl/register-atfork.c (__run_fork_handlers): Only perform ++ locking if the new do_locking argument is true. ++ * sysdeps/nptl/fork.c (__libc_fork): Pass multiple_threads to ++ __run_fork_handlers. ++ + 2019-02-07 Stefan Liebler + + [BZ #24180] +diff --git a/NEWS b/NEWS +index 1f0fc4b3cb..dbcdd48502 100644 +--- a/NEWS ++++ b/NEWS +@@ -11,6 +11,7 @@ The following bugs are resolved with this release: + + [24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309) + [24164] Systemtap probes need to use "nr" constraint on 32-bit Arm ++ [24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2 + + Security related changes: + +diff --git a/nptl/register-atfork.c b/nptl/register-atfork.c +index bc797b761a..80a1becb5f 100644 +--- a/nptl/register-atfork.c ++++ b/nptl/register-atfork.c +@@ -107,13 +107,14 @@ __unregister_atfork (void *dso_handle) + } + + void +-__run_fork_handlers (enum __run_fork_handler_type who) ++__run_fork_handlers (enum __run_fork_handler_type who, _Bool do_locking) + { + struct fork_handler *runp; + + if (who == atfork_run_prepare) + { +- lll_lock (atfork_lock, LLL_PRIVATE); ++ if (do_locking) ++ lll_lock (atfork_lock, LLL_PRIVATE); + size_t sl = fork_handler_list_size (&fork_handlers); + for (size_t i = sl; i > 0; i--) + { +@@ -133,7 +134,8 @@ __run_fork_handlers (enum __run_fork_handler_type who) + else if (who == atfork_run_parent && runp->parent_handler) + runp->parent_handler (); + } +- lll_unlock (atfork_lock, LLL_PRIVATE); ++ if (do_locking) ++ lll_unlock (atfork_lock, LLL_PRIVATE); + } + } + +diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c +index bd68f18b45..14b69a6f89 100644 +--- a/sysdeps/nptl/fork.c ++++ b/sysdeps/nptl/fork.c +@@ -55,7 +55,7 @@ __libc_fork (void) + but our current fork implementation is not. */ + bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads); + +- __run_fork_handlers (atfork_run_prepare); ++ __run_fork_handlers (atfork_run_prepare, multiple_threads); + + /* If we are not running multiple threads, we do not have to + preserve lock state. If fork runs from a signal handler, only +@@ -134,7 +134,7 @@ __libc_fork (void) + __rtld_lock_initialize (GL(dl_load_lock)); + + /* Run the handlers registered for the child. */ +- __run_fork_handlers (atfork_run_child); ++ __run_fork_handlers (atfork_run_child, multiple_threads); + } + else + { +@@ -149,7 +149,7 @@ __libc_fork (void) + } + + /* Run the handlers registered for the parent. */ +- __run_fork_handlers (atfork_run_parent); ++ __run_fork_handlers (atfork_run_parent, multiple_threads); + } + + return pid; +diff --git a/sysdeps/nptl/fork.h b/sysdeps/nptl/fork.h +index a1c3b26b68..99ed76034b 100644 +--- a/sysdeps/nptl/fork.h ++++ b/sysdeps/nptl/fork.h +@@ -52,9 +52,11 @@ enum __run_fork_handler_type + - atfork_run_child: run all the CHILD_HANDLER and unlocks the internal + lock. + - atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal +- lock. */ +-extern void __run_fork_handlers (enum __run_fork_handler_type who) +- attribute_hidden; ++ lock. ++ ++ Perform locking only if DO_LOCKING. */ ++extern void __run_fork_handlers (enum __run_fork_handler_type who, ++ _Bool do_locking) attribute_hidden; + + /* C library side function to register new fork handlers. */ + extern int __register_atfork (void (*__prepare) (void), +-- +2.21.0 + diff --git a/0006-nptl-Fix-invalid-Systemtap-probe-in-pthread_join-BZ-.patch b/0006-nptl-Fix-invalid-Systemtap-probe-in-pthread_join-BZ-.patch new file mode 100644 index 0000000..9e8a89e --- /dev/null +++ b/0006-nptl-Fix-invalid-Systemtap-probe-in-pthread_join-BZ-.patch @@ -0,0 +1,88 @@ +From 067fc32968b601493f4b247a3ac00caeea3f3d61 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Fri, 15 Feb 2019 21:27:01 +0100 +Subject: [PATCH 06/11] nptl: Fix invalid Systemtap probe in pthread_join [BZ + #24211] + +After commit f1ac7455831546e5dca0ed98fe8af2686fae7ce6 ("arm: Use "nr" +constraint for Systemtap probes [BZ #24164]"), we load pd->result into +a register in the probe below: + + /* Free the TCB. */ + __free_tcb (pd); + } + else + pd->joinid = NULL; + + LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd->result); + +However, at this point, the thread descriptor has been freed. If the +thread stack does not fit into the thread stack cache, the memory will +have been unmapped, and the program will crash in the probe. + +(cherry picked from commit bc10e22c90e42613bd5dafb77b80a9ea1759dd1b) +--- + ChangeLog | 6 ++++++ + NEWS | 1 + + nptl/pthread_join_common.c | 5 +++-- + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index d363be4620..a6a0ce19ed 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2019-02-15 Florian Weimer ++ ++ [BZ #24211] ++ * nptl/pthread_join_common.c (__pthread_timedjoin_ex): Do not read ++ pd->result after the thread descriptor has been freed. ++ + 2019-02-08 Florian Weimer + + [BZ #24161] +diff --git a/NEWS b/NEWS +index dbcdd48502..340e06d0f4 100644 +--- a/NEWS ++++ b/NEWS +@@ -12,6 +12,7 @@ The following bugs are resolved with this release: + [24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309) + [24164] Systemtap probes need to use "nr" constraint on 32-bit Arm + [24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2 ++ [24211] Use-after-free in Systemtap probe in pthread_join + + Security related changes: + +diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c +index ecb78ffba5..366feb376b 100644 +--- a/nptl/pthread_join_common.c ++++ b/nptl/pthread_join_common.c +@@ -86,6 +86,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return, + pthread_cleanup_pop (0); + } + ++ void *pd_result = pd->result; + if (__glibc_likely (result == 0)) + { + /* We mark the thread as terminated and as joined. */ +@@ -93,7 +94,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return, + + /* Store the return value if the caller is interested. */ + if (thread_return != NULL) +- *thread_return = pd->result; ++ *thread_return = pd_result; + + /* Free the TCB. */ + __free_tcb (pd); +@@ -101,7 +102,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return, + else + pd->joinid = NULL; + +- LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd->result); ++ LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd_result); + + return result; + } +-- +2.21.0 + diff --git a/0007-Fix-output-of-LD_SHOW_AUXV-1.patch b/0007-Fix-output-of-LD_SHOW_AUXV-1.patch new file mode 100644 index 0000000..3280d86 --- /dev/null +++ b/0007-Fix-output-of-LD_SHOW_AUXV-1.patch @@ -0,0 +1,163 @@ +From bc6f839fb4066be83272c735e662850af2595777 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 13 Mar 2019 10:45:35 +0100 +Subject: [PATCH 07/11] Fix output of LD_SHOW_AUXV=1. + +Starting with commit 1616d034b61622836d3a36af53dcfca7624c844e +the output was corrupted on some platforms as _dl_procinfo +was called for every auxv entry and on some architectures like s390 +all entries were represented as "AT_HWCAP". + +This patch is removing the condition and let _dl_procinfo decide if +an entry is printed in a platform specific or generic way. +This patch also adjusts all _dl_procinfo implementations which assumed +that they are only called for AT_HWCAP or AT_HWCAP2. They are now just +returning a non-zero-value for entries which are not handled platform +specifc. + +ChangeLog: + + * elf/dl-sysdep.c (_dl_show_auxv): Remove condition and always + call _dl_procinfo. + * sysdeps/unix/sysv/linux/s390/dl-procinfo.h (_dl_procinfo): + Ignore types other than AT_HWCAP. + * sysdeps/sparc/dl-procinfo.h (_dl_procinfo): Likewise. + * sysdeps/unix/sysv/linux/i386/dl-procinfo.h (_dl_procinfo): + Likewise. + * sysdeps/powerpc/dl-procinfo.h (_dl_procinfo): Adjust comment + in the case of falling back to generic output mechanism. + * sysdeps/unix/sysv/linux/arm/dl-procinfo.h (_dl_procinfo): + Likewise. + +(cherry picked from commit 7c6513082b787a7d36ab7d75720b48f8a216089c) + +Conflicts: + ChangeLog +--- + ChangeLog | 14 ++++++++++++++ + elf/dl-sysdep.c | 11 +++-------- + sysdeps/powerpc/dl-procinfo.h | 2 +- + sysdeps/sparc/dl-procinfo.h | 4 ++-- + sysdeps/unix/sysv/linux/arm/dl-procinfo.h | 2 +- + sysdeps/unix/sysv/linux/i386/dl-procinfo.h | 4 ++-- + sysdeps/unix/sysv/linux/s390/dl-procinfo.h | 4 ++-- + 7 files changed, 25 insertions(+), 16 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index a6a0ce19ed..90558e434c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,17 @@ ++2019-03-13 Stefan Liebler ++ ++ * elf/dl-sysdep.c (_dl_show_auxv): Remove condition and always ++ call _dl_procinfo. ++ * sysdeps/unix/sysv/linux/s390/dl-procinfo.h (_dl_procinfo): ++ Ignore types other than AT_HWCAP. ++ * sysdeps/sparc/dl-procinfo.h (_dl_procinfo): Likewise. ++ * sysdeps/unix/sysv/linux/i386/dl-procinfo.h (_dl_procinfo): ++ Likewise. ++ * sysdeps/powerpc/dl-procinfo.h (_dl_procinfo): Adjust comment ++ in the case of falling back to generic output mechanism. ++ * sysdeps/unix/sysv/linux/arm/dl-procinfo.h (_dl_procinfo): ++ Likewise. ++ + 2019-02-15 Florian Weimer + + [BZ #24211] +diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c +index 5f6c679a3f..5d19b100b2 100644 +--- a/elf/dl-sysdep.c ++++ b/elf/dl-sysdep.c +@@ -328,14 +328,9 @@ _dl_show_auxv (void) + assert (AT_NULL == 0); + assert (AT_IGNORE == 1); + +- if (av->a_type == AT_HWCAP || av->a_type == AT_HWCAP2 +- || AT_L1I_CACHEGEOMETRY || AT_L1D_CACHEGEOMETRY +- || AT_L2_CACHEGEOMETRY || AT_L3_CACHEGEOMETRY) +- { +- /* These are handled in a special way per platform. */ +- if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0) +- continue; +- } ++ /* Some entries are handled in a special way per platform. */ ++ if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0) ++ continue; + + if (idx < sizeof (auxvars) / sizeof (auxvars[0]) + && auxvars[idx].form != unknown) +diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h +index f542f7318f..dfc3b33a72 100644 +--- a/sysdeps/powerpc/dl-procinfo.h ++++ b/sysdeps/powerpc/dl-procinfo.h +@@ -225,7 +225,7 @@ _dl_procinfo (unsigned int type, unsigned long int word) + break; + } + default: +- /* This should not happen. */ ++ /* Fallback to generic output mechanism. */ + return -1; + } + _dl_printf ("\n"); +diff --git a/sysdeps/sparc/dl-procinfo.h b/sysdeps/sparc/dl-procinfo.h +index 282b8c5117..64ee267fc7 100644 +--- a/sysdeps/sparc/dl-procinfo.h ++++ b/sysdeps/sparc/dl-procinfo.h +@@ -31,8 +31,8 @@ _dl_procinfo (unsigned int type, unsigned long int word) + { + int i; + +- /* Fallback to unknown output mechanism. */ +- if (type == AT_HWCAP2) ++ /* Fallback to generic output mechanism. */ ++ if (type != AT_HWCAP) + return -1; + + _dl_printf ("AT_HWCAP: "); +diff --git a/sysdeps/unix/sysv/linux/arm/dl-procinfo.h b/sysdeps/unix/sysv/linux/arm/dl-procinfo.h +index 66c00297b7..05c62c8687 100644 +--- a/sysdeps/unix/sysv/linux/arm/dl-procinfo.h ++++ b/sysdeps/unix/sysv/linux/arm/dl-procinfo.h +@@ -67,7 +67,7 @@ _dl_procinfo (unsigned int type, unsigned long int word) + break; + } + default: +- /* This should not happen. */ ++ /* Fallback to generic output mechanism. */ + return -1; + } + _dl_printf ("\n"); +diff --git a/sysdeps/unix/sysv/linux/i386/dl-procinfo.h b/sysdeps/unix/sysv/linux/i386/dl-procinfo.h +index 22b43431bc..0585cdaa9c 100644 +--- a/sysdeps/unix/sysv/linux/i386/dl-procinfo.h ++++ b/sysdeps/unix/sysv/linux/i386/dl-procinfo.h +@@ -30,8 +30,8 @@ _dl_procinfo (unsigned int type, unsigned long int word) + in the kernel sources. */ + int i; + +- /* Fallback to unknown output mechanism. */ +- if (type == AT_HWCAP2) ++ /* Fallback to generic output mechanism. */ ++ if (type != AT_HWCAP) + return -1; + + _dl_printf ("AT_HWCAP: "); +diff --git a/sysdeps/unix/sysv/linux/s390/dl-procinfo.h b/sysdeps/unix/sysv/linux/s390/dl-procinfo.h +index 19329a335b..d67fde368f 100644 +--- a/sysdeps/unix/sysv/linux/s390/dl-procinfo.h ++++ b/sysdeps/unix/sysv/linux/s390/dl-procinfo.h +@@ -32,8 +32,8 @@ _dl_procinfo (unsigned int type, unsigned long int word) + in the kernel sources. */ + int i; + +- /* Fallback to unknown output mechanism. */ +- if (type == AT_HWCAP2) ++ /* Fallback to generic output mechanism. */ ++ if (type != AT_HWCAP) + return -1; + + _dl_printf ("AT_HWCAP: "); +-- +2.21.0 + diff --git a/0008-regex-fix-read-overrun-BZ-24114.patch b/0008-regex-fix-read-overrun-BZ-24114.patch new file mode 100644 index 0000000..d39bfa1 --- /dev/null +++ b/0008-regex-fix-read-overrun-BZ-24114.patch @@ -0,0 +1,52 @@ +From 4d0b1b0f61bfba034e9e76a1d76acc59c975238f Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Mon, 21 Jan 2019 11:08:13 -0800 +Subject: [PATCH 08/11] regex: fix read overrun [BZ #24114] + +Problem found by AddressSanitizer, reported by Hongxu Chen in: +https://debbugs.gnu.org/34140 +* posix/regexec.c (proceed_next_node): +Do not read past end of input buffer. + +(cherry picked from commit 583dd860d5b833037175247230a328f0050dbfe9) +--- + ChangeLog | 8 ++++++++ + posix/regexec.c | 6 ++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 90558e434c..fb88626efe 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,11 @@ ++2019-01-31 Paul Eggert ++ ++ regex: fix read overrun [BZ #24114] ++ Problem found by AddressSanitizer, reported by Hongxu Chen in: ++ https://debbugs.gnu.org/34140 ++ * posix/regexec.c (proceed_next_node): ++ Do not read past end of input buffer. ++ + 2019-03-13 Stefan Liebler + + * elf/dl-sysdep.c (_dl_show_auxv): Remove condition and always +diff --git a/posix/regexec.c b/posix/regexec.c +index 91d5a797b8..084b1222d9 100644 +--- a/posix/regexec.c ++++ b/posix/regexec.c +@@ -1293,8 +1293,10 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + else if (naccepted) + { + char *buf = (char *) re_string_get_buffer (&mctx->input); +- if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, +- naccepted) != 0) ++ if (mctx->input.valid_len - *pidx < naccepted ++ || (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, ++ naccepted) ++ != 0)) + return -1; + } + } +-- +2.21.0 + diff --git a/0009-Record-CVE-2019-9169-in-NEWS-and-ChangeLog-BZ-24114.patch b/0009-Record-CVE-2019-9169-in-NEWS-and-ChangeLog-BZ-24114.patch new file mode 100644 index 0000000..7019cb2 --- /dev/null +++ b/0009-Record-CVE-2019-9169-in-NEWS-and-ChangeLog-BZ-24114.patch @@ -0,0 +1,40 @@ +From 10dd17da710fd32aaf1f2187544d80064b8c4ee0 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sat, 16 Mar 2019 22:59:56 +0100 +Subject: [PATCH 09/11] Record CVE-2019-9169 in NEWS and ChangeLog [BZ #24114] + +(cherry picked from commit b626c5aa5d0673a9caa48fb79fba8bda237e6fa8) +--- + ChangeLog | 1 + + NEWS | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index fb88626efe..80413dd560 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,6 @@ + 2019-01-31 Paul Eggert + ++ CVE-2019-9169 + regex: fix read overrun [BZ #24114] + Problem found by AddressSanitizer, reported by Hongxu Chen in: + https://debbugs.gnu.org/34140 +diff --git a/NEWS b/NEWS +index 340e06d0f4..271bf7a2cd 100644 +--- a/NEWS ++++ b/NEWS +@@ -24,6 +24,10 @@ Security related changes: + memcmp gave the wrong result since it treated the size argument as + zero. Reported by H.J. Lu. + ++ CVE-2019-9169: Attempted case-insensitive regular-expression match ++ via proceed_next_node in posix/regexec.c leads to heap-based buffer ++ over-read. Reported by Hongxu Chen. ++ + + Version 2.29 + +-- +2.21.0 + diff --git a/0010-S390-Mark-vx-and-vxe-as-important-hwcap.patch b/0010-S390-Mark-vx-and-vxe-as-important-hwcap.patch new file mode 100644 index 0000000..1051756 --- /dev/null +++ b/0010-S390-Mark-vx-and-vxe-as-important-hwcap.patch @@ -0,0 +1,53 @@ +From 6eb48fe80cb6dd3ef536e86d005976d1c22b170e Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 21 Mar 2019 09:14:26 +0100 +Subject: [PATCH 10/11] S390: Mark vx and vxe as important hwcap. + +This patch adds vx and vxe as important hwcaps +which allows one to provide shared libraries +tuned for platforms with non-vx/-vxe, vx or vxe. + +ChangeLog: + + * sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT): + Add HWCAP_S390_VX and HWCAP_S390_VXE. + +(cherry picked from commit 61f5e9470fb397a4c334938ac5a667427d9047df) + +Conflicts: + ChangeLog +--- + ChangeLog | 5 +++++ + sysdeps/s390/dl-procinfo.h | 3 ++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 80413dd560..7111aeb149 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2019-03-21 Stefan Liebler ++ ++ * sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT): ++ Add HWCAP_S390_VX and HWCAP_S390_VXE. ++ + 2019-01-31 Paul Eggert + + CVE-2019-9169 +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index b4b81fc70a..99697ae649 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -57,7 +57,8 @@ enum + }; + + #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ +- | HWCAP_S390_EIMM | HWCAP_S390_DFP) ++ | HWCAP_S390_EIMM | HWCAP_S390_DFP \ ++ | HWCAP_S390_VX | HWCAP_S390_VXE) + + /* We cannot provide a general printing function. */ + #define _dl_procinfo(type, word) -1 +-- +2.21.0 + diff --git a/0011-ja_JP-Change-the-offset-for-Taisho-gan-nen-from-2-to.patch b/0011-ja_JP-Change-the-offset-for-Taisho-gan-nen-from-2-to.patch new file mode 100644 index 0000000..ccd7ac2 --- /dev/null +++ b/0011-ja_JP-Change-the-offset-for-Taisho-gan-nen-from-2-to.patch @@ -0,0 +1,55 @@ +From e28ad442e73b00ae2047d89c8cc7f9b2a0de5436 Mon Sep 17 00:00:00 2001 +From: TAMUKI Shoichi +Date: Sat, 2 Mar 2019 21:00:28 +0900 +Subject: [PATCH 11/11] ja_JP: Change the offset for Taisho gan-nen from 2 to 1 + [BZ #24162] + +The offset in era-string format for Taisho gan-nen (1912) is currently +defined as 2, but it should be 1. So fix it. "Gan-nen" means the 1st +(origin) year, Taisho started on July 30, 1912. + +Reported-by: Morimitsu, Junji +Reviewed-by: Rafal Luzynski + +ChangeLog: + + [BZ #24162] + * localedata/locales/ja_JP (LC_TIME): Change the offset for Taisho + gan-nen from 2 to 1. Problem reported by Morimitsu, Junji. + +(cherry picked from commit 31effacee2fc1b327bedc9a5fcb4b83f227c6539) +--- + ChangeLog | 6 ++++++ + localedata/locales/ja_JP | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 7111aeb149..048ca9644c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2019-03-02 TAMUKI Shoichi ++ ++ [BZ #24162] ++ * localedata/locales/ja_JP (LC_TIME): Change the offset for Taisho ++ gan-nen from 2 to 1. Problem reported by Morimitsu, Junji. ++ + 2019-03-21 Stefan Liebler + + * sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT): +diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP +index 1fd2fee44b..9bfbb2bb9b 100644 +--- a/localedata/locales/ja_JP ++++ b/localedata/locales/ja_JP +@@ -14951,7 +14951,7 @@ era "+:2:1990//01//01:+*::%EC%Ey";/ + "+:2:1927//01//01:1989//01//07::%EC%Ey";/ + "+:1:1926//12//25:1926//12//31::%EC";/ + "+:2:1913//01//01:1926//12//24::%EC%Ey";/ +- "+:2:1912//07//30:1912//12//31::%EC";/ ++ "+:1:1912//07//30:1912//12//31::%EC";/ + "+:6:1873//01//01:1912//07//29::%EC%Ey";/ + "+:1:0001//01//01:1872//12//31::%EC%Ey";/ + "+:1:-0001//12//31:-*::%EC%Ey" +-- +2.21.0 + diff --git a/Makefile.locales b/Makefile.locales deleted file mode 100644 index f5d3da1..0000000 --- a/Makefile.locales +++ /dev/null @@ -1,21 +0,0 @@ -SUPPORTED ?= /usr/share/i18n/SUPPORTED - -include $(SUPPORTED) - -INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES)) - -install-locales: $(INSTALL-SUPPORTED-LOCALES) - -install-locales-dir: - mkdir -p $(DESTDIR)/usr/lib/locale - -$(INSTALL-SUPPORTED-LOCALES): install-locales-dir - @locale=`echo $@ | sed -e 's/^install-//'`; \ - charset=`echo $$locale | sed -e 's,.*/,,'`; \ - locale=`echo $$locale | sed -e 's,/[^/]*,,'`; \ - input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \ - echo "localedef -i $$input -c -f $$charset" \ - "$(DESTDIR)/usr/lib/locale/$$locale"; \ - localedef -i $$input -c -f $$charset \ - $(DESTDIR)/usr/lib/locale/$$locale; \ - diff --git a/glibc-fedora-include-bits-ldbl.patch b/glibc-fedora-include-bits-ldbl.patch deleted file mode 100644 index 1e5d763..0000000 --- a/glibc-fedora-include-bits-ldbl.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 5eb4509a6651d19c7a28c4506d6aa582c9ee095a Mon Sep 17 00:00:00 2001 -From: Jakub Jelinek -Date: Wed, 1 Feb 2006 09:30:43 +0000 -Subject: [PATCH] 128-bit long double fixes - -* include/bits/stdlib-ldbl.h: New file. -* include/bits/wchar-ldbl.h: New file. - ---- - ChangeLog | 5 +++++ - include/bits/stdlib-ldbl.h | 1 + - include/bits/wchar-ldbl.h | 1 + - 3 files changed, 7 insertions(+), 0 deletions(-) - create mode 100644 include/bits/stdlib-ldbl.h - create mode 100644 include/bits/wchar-ldbl.h - -diff --git a/include/bits/stdlib-ldbl.h b/include/bits/stdlib-ldbl.h -new file mode 100644 -index 0000000..6250949 ---- /dev/null -+++ b/include/bits/stdlib-ldbl.h -@@ -0,0 +1 @@ -+#include -diff --git a/include/bits/wchar-ldbl.h b/include/bits/wchar-ldbl.h -new file mode 100644 -index 0000000..29baa2f ---- /dev/null -+++ b/include/bits/wchar-ldbl.h -@@ -0,0 +1 @@ -+#include diff --git a/glibc-fedora-localedef.patch b/glibc-fedora-localedef.patch index 515611a..314ed41 100644 --- a/glibc-fedora-localedef.patch +++ b/glibc-fedora-localedef.patch @@ -1,17 +1,7 @@ -Short description: Fedora-specific glibc install locale changes. -Author(s): Fedora glibc team -Origin: PATCH -Upstream status: not-needed - -The Fedora glibc build and install does not need the normal install -behaviour which updates the locale archive. The Fedora install phase -in the spec file of the rpm will handle this manually. - -diff --git a/localedata/Makefile b/localedata/Makefile -index 0eea396ad86da956..54caabda33728207 100644 ---- a/localedata/Makefile -+++ b/localedata/Makefile -@@ -413,6 +413,7 @@ define build-one-locale +diff -Naur glibc-2.29/localedata/Makefile glibc-2.29.tpg/localedata/Makefile +--- glibc-2.29/localedata/Makefile 2019-02-01 11:37:49.564873847 +0000 ++++ glibc-2.29.tpg/localedata/Makefile 2019-02-01 11:38:20.352871703 +0000 +@@ -413,6 +413,7 @@ echo -n '...'; \ input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \ $(LOCALEDEF) $$flags --alias-file=../intl/locale.alias \ diff --git a/glibc.rpmlintrc b/glibc.rpmlintrc index b29ea06..72922d0 100644 --- a/glibc.rpmlintrc +++ b/glibc.rpmlintrc @@ -6,3 +6,6 @@ addFilter("E: executable-in-library-package") addFilter("E: invalid-soname") # libc6 is unstripped by default addFilter("E: unstripped-binary-or-object") +addFilter("E: postin-without-ldconfig") +addFilter("missing-PT_GNU_STACK-section.*mips.*\.so.*") +addFilter("use-of-RPM_SOURCE_DIR") diff --git a/glibc.spec b/glibc.spec index d9c9ce1..a961350 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1,93 +1,156 @@ -%define checklist %{_builddir}/%{name}-%{version}/Check.list +%bcond_with crosscompilers +%define debug_package %nil +%ifarch %{ix86} %{arm} +# FIXME add riscv32-linux when glibc starts supporting it +# FIXME Determine why (and fix) 32-bit platform to x86_64-linux crosscompilers +# are broken (build failure with static assertion on offset of __private_ss) +%global targets aarch64-linux armv7hnl-linux i686-linux x32-linux riscv64-linux +%else +# FIXME add riscv32-linux when glibc starts supporting it +%global targets aarch64-linux armv7hnl-linux i686-linux x86_64-linux x32-linux riscv64-linux +%endif +%global long_targets %( + for i in %{targets}; do + CPU=$(echo $i |cut -d- -f1) + OS=$(echo $i |cut -d- -f2) + echo -n "$(rpm --target=${CPU}-${OS} -E %%{_target_platform}) " + done +) -%define _slibdir /%{_lib} -%define _slibdir32 /lib -%define _libdir32 %{_prefix}/lib +%define _libdir32 %{_prefix}/lib +%define _libdirn32 %{_prefix}/lib32 -%define major 6 -%define libc %mklibname c %{major} -%define devname %mklibname -d c -%define statname %mklibname -d -s c -%define multilibc libc%{major} +%define ver 2.29 +%define linaro %{nil} -%define _disable_ld_no_undefined 1 -%undefine _fortify_cflags +%define oname glibc +%define major 6 +%if "%{linaro}" != "" +%define fullver %{ver}-%{linaro} +%define source_dir glibc-linaro-%{fullver} +%else +%define fullver %{ver} +%define source_dir %{oname}-%{ver} +%endif +%define checklist %{_builddir}/%{source_dir}/Check.list +%define libc %mklibname c %{major} +%define devname %mklibname -d c +%define statname %mklibname -d -s c +%define multilibc libc%{major} -%ifarch %{arm} -%define _gnu -gnueabi +%define _disable_rebuild_configure 1 +%bcond_with lto +%if !%{with lto} +%define _disable_lto 1 %endif +%define _disable_ld_no_undefined 1 + +# (tpg) optimize it a bit +%global optflags %{optflags} -O3 + +%global platform %{_target_vendor}-%{_target_os}%{?_gnu} +%global target_cpu %{_target_cpu} + +%global target_platform %{_target_platform} +%global target_arch %{_arch} +%define cross_prefix %{nil} +%define cross_program_prefix %{nil} +%define _slibdir /%{_lib} +%define _slibdir32 /lib + +# Define target (base) architecture +%define arch %(echo %{target_cpu}|sed -e "s/\\(i.86\\|athlon\\)/i386/" -e "s/amd64/x86_64/") +%define isarch() %(case " %* " in (*" %{arch} "*) echo 1;; (*) echo 0;; esac) + # Define Xen arches to build with -mno-tls-direct-seg-refs -%define xenarches %{ix86} +%define xenarches %{ix86} -# Distro-specific default value is defined in branding-configs package -%{?build_selinux}%{?!build_selinux:%bcond_with selinux} -%{?build_systap}%{?!build_systap:%bcond_without systap} +# Determine minimum kernel versions (rhbz#619538) +%ifarch %{arm} +# currently using 3.0.35 kernel with wandboard +%define enablekernel 3.0.35 +%else +%ifarch %{aarch64} +# Before increasing, please make sure all +# boxes we support can be updated: +# As of 2018/06/08: +# Opteron server boxes have 4.4.x +# Rockchip 3399 has 4.4.x +# Gemini PDA has 3.18.x +%define enablekernel 3.18.0 +%else +%define enablekernel 4.14.0 +%endif +%endif -# FIXME disable libselinux, new version is not yet available +# Define to build nscd with selinux support %bcond_with selinux -# Allow make check to fail only when running kernels where we know -# tests must pass (no missing features or bugs in the kernel) -%define check_min_kver 2.6.21 - # Define to build a biarch package -%define build_multiarch 0 -%ifarch x86_64 -%define build_multiarch 1 +%define build_biarch 0 +%if %isarch %{x86_64} mips64 mips64el mips mipsel +%define build_biarch 1 %endif %bcond_without nscd %bcond_without i18ndata %bcond_with timezone -%bcond_without nsscrypt %bcond_without locales +%if %isarch %{ix86} %{x86_64} +%bcond_with systap +%else +%bcond_with systap +%endif + # build documentation by default -%bcond_without doc -%bcond_with pdf +%bcond_with doc +%bcond_with pdf # enable utils by default -%bcond_without utils +%bcond_without utils #----------------------------------------------------------------------- Summary: The GNU libc libraries -Name: glibc +Name: %{cross_prefix}%{oname} Epoch: 6 -Version: 2.29 -Release: 3 +%if "%{linaro}" != "" +Version: %{ver}_%{linaro} +Source0: http://cbuild.validation.linaro.org/snapshots/glibc-linaro-%{fullver}.tar.xz +%else +Version: %{ver} +Source0: http://ftp.gnu.org/gnu/glibc/%{oname}-%{ver}.tar.xz +#if %(test $(echo %{version}.0 |cut -d. -f3) -lt 90 && echo 1 || echo 0) +#Source1: http://ftp.gnu.org/gnu/glibc/%{oname}-%{ver}.tar.xz.sig +#endif +%endif +Release: 4 License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ Group: System/Libraries -Url: http://www.eglibc.org/ -Source0: http://ftp.gnu.org/gnu/glibc/%{name}-%{version}.tar.xz -Source1: http://ftp.gnu.org/gnu/glibc/%{name}-%{version}.tar.xz.sig +Url: http://www.gnu.org/software/libc/ # From Fedora Source2: glibc_post_upgrade.c Source3: glibc-manpages.tar.bz2 -Source4: nscd.conf Source5: glibc-check.sh -Source6: nscd.service -Source7: nscd.socket Source10: libc-lock.h +# (tpg) our NSS config +Source11: nsswitch.conf -# Locales -Source20: Makefile.locales - -Source100: %{name}.rpmlintrc - -Source1000: locale-pkg +Source100: %{oname}.rpmlintrc +Source1000: localepkg.sh Source1001: locale_install.sh Source1002: locale_uninstall.sh +Source1003: locales.sysconfig #----------------------------------------------------------------------- # fedora patches Patch21: http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/plain/glibc-fedora-i386-tls-direct-seg-refs.patch -#Patch23: http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/plain/glibc-fedora-include-bits-ldbl.patch Patch25: http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/plain/glibc-fedora-linux-tcsetattr.patch Patch26: eglibc-fedora-locale-euro.patch Patch27: http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/plain/glibc-fedora-localedata-rh61908.patch # We disagree with -# http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/plain/glibc-fedora-streams-rh436349.patch +# http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/plain/glibc-fedora-streams-rh436349.patch # Therefore we don't package/apply it. Patch30: http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/plain/glibc-fedora-localedef.patch Patch31: http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/plain/glibc-fedora-locarchive.patch @@ -127,7 +190,10 @@ Patch88: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/malloc_t Patch89: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/ldconfig-format-new.patch # (tpg) CLR disabled this patch #Patch90: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/ldconfig-Os.patch -# https://sourceware.org/ml/libc-alpha/2018-03/msg00504.html +%if %{with lto} +Patch91: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/mathlto.patch +%endif +Patch92: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/pause.patch Patch99: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/gcc-8-fix.patch Patch100: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/spin-smarter.patch Patch101: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/nostackshrink.patch @@ -135,6 +201,19 @@ Patch101: https://raw.githubusercontent.com/clearlinux-pkgs/glibc/master/nostack # # Patches from upstream # +# Taken from git://sourceware.org/git/glibc.git +# release branch +Patch500: 0001-nptl-Fix-pthread_rwlock_try-lock-stalls-Bug-23844.patch +Patch501: 0002-x86-64-memcmp-Use-unsigned-Jcc-instructions-on-size-.patch +Patch502: 0003-arm-Use-nr-constraint-for-Systemtap-probes-BZ-24164.patch +Patch503: 0004-Add-compiler-barriers-around-modifications-of-the-ro.patch +Patch504: 0005-nptl-Avoid-fork-handler-lock-for-async-signal-safe-f.patch +Patch505: 0006-nptl-Fix-invalid-Systemtap-probe-in-pthread_join-BZ-.patch +Patch506: 0007-Fix-output-of-LD_SHOW_AUXV-1.patch +Patch507: 0008-regex-fix-read-overrun-BZ-24114.patch +Patch508: 0009-Record-CVE-2019-9169-in-NEWS-and-ChangeLog-BZ-24114.patch +Patch509: 0010-S390-Mark-vx-and-vxe-as-important-hwcap.patch +Patch510: 0011-ja_JP-Change-the-offset-for-Taisho-gan-nen-from-2-to.patch #----------------------------------------------------------------------- # OpenMandriva patches @@ -164,58 +243,62 @@ Patch1034: glibc-2.27-clang-_Float.patch Patch1035: glibc-2.29-aarch64-buildfix.patch Patch1036: glibc-2.29-strict-aliasing.patch Patch1037: glibc-2.29-SIG_BLOCK.patch -Patch1039: unsigned-magic.patch +Patch1038: unsigned-magic.patch -# yes need python3 -BuildRequires: pkgconfig(python3) BuildRequires: autoconf2.5 -BuildRequires: bison +BuildRequires: python3 +BuildRequires: %{cross_prefix}binutils >= 2.30-7 +BuildRequires: %{cross_prefix}gcc BuildRequires: gettext -BuildRequires: kernel-headers +BuildRequires: %{?cross:cross-}kernel-headers >= %{enablekernel} BuildRequires: patch -BuildRequires: perl +BuildRequires: hardlink BuildRequires: cap-devel +BuildRequires: bison +BuildRequires: pkgconfig(libidn2) +BuildRequires: systemd %if %{with selinux} -BuildRequires: pkgconfig(libselinux) >= 1.17.10 +BuildRequires: libselinux-devel >= 1.17.10 %endif BuildRequires: texinfo %if %{with pdf} BuildRequires: texlive %endif %if %{with utils} -BuildRequires: gd-devel +BuildRequires: gd-devel pkgconfig(zlib) pkgconfig(libpng) %endif %if %{with systap} BuildRequires: systemtap-devel %endif -%if %{with nsscrypt} -BuildRequires: pkgconfig(nss) -%endif -# we'll be the only package requiring this, avoiding any other package -# dependencies on '/bin/sh' or 'bash' -Requires: bash -# Requires: filesystem -%ifarch %{xenarches} +Requires: filesystem +Requires(post): filesystem +%if %isarch %{xenarches} %rename %{name}-xen %endif # The dynamic linker supports DT_GNU_HASH Provides: rtld(GNU_HASH) Provides: should-restart = system -# Determine minimum kernel versions (rhbz#619538) -%define enablekernel 2.6.32 +Obsoletes: glibc-profile +# Old prelink versions breaks the system with glibc 2.11 +Conflicts: prelink < 1:0.4.2-1.20091104.1mdv2010.1 Conflicts: kernel < %{enablekernel} -%if %{with locales} -Conflicts: locales < %{EVRD} -Conflicts: locales > %{EVRD} -%endif # Don't try to explicitly provide GLIBC_PRIVATE versioned libraries -%define _filter_GLIBC_PRIVATE 1 - -Provides: ld.so +%global _filter_GLIBC_PRIVATE 1 +%rename ld.so +%ifarch %{mips} %{mipsel} +Provides: ld.so.1 +%endif %rename ldconfig +%define libnssfiles %mklibname nss_files 2 +%rename %{libnssfiles} Provides: /sbin/ldconfig +Obsoletes: nss_db + +%if %{build_biarch} +Requires: %{multilibc} = %{EVRD} +%endif %description The glibc package contains standard libraries which are used by @@ -227,13 +310,227 @@ library and the standard math library. Without these two libraries, a Linux system will not function. %post -/usr/sbin/glibc_post_upgrade +# rpm5 bug? +# %post(glibc-2.29-2.i586) scriptlet failed, exit status 255 +# it always return 255 +#/usr/sbin/glibc_post_upgrade +#/sbin/ldconfig -X + +%if %{with locales} +%package -n locales +Summary: Base files for localization +Group: System/Internationalization +Obsoletes: locales <= 2.18.90-2 +Obsoletes: locales < 2.19-13 +Requires(post,preun): /bin/sh +Requires(post,preun): grep +Requires(post,preun): sed +Requires(post,preun): coreutils +Requires(post,preun): util-linux +Requires(post,preun): glibc +Requires(post,preun): rpm + +%description -n locales +These are the base files for language localization. +You also need to install the specific locales-?? for the +language(s) you want. Then the user need to set the +LANG variable to their preferred language in their +~/.profile configuration file. + +# Locale specifc packages +# To look up a language name from a newly appearing code, +# Try http://scriptsource.org/cms/scripts/page.php?item_id=language_detail&key=XXX (where XXX is the new code without country suffix) +%{expand:%(sh %{S:1000} "Afar" "aa" "aa_DJ" "aa_ER" "aa_ET")} +%{expand:%(sh %{S:1000} "Afrikaans" "af" "af_ZA")} +%{expand:%(sh %{S:1000} "Aguaruna" "agr" "agr_PE")} +%{expand:%(sh %{S:1000} "Amharic" "am" "am_ET" "byn_ER" "gez_ER" "gez_ET" "om_ET" "om_KE" "sid_ET" "ti_ER" "ti_ET" "tig_ER" "wal_ET")} +%{expand:%(sh %{S:1000} "Akan" "ak" "ak_GH")} +%{expand:%(sh %{S:1000} "Angika" "anp" "anp_IN")} +%{expand:%(sh %{S:1000} "Arabic" "ar" "ar_AE" "ar_BH" "ar_DZ" "ar_EG" "ar_IN" "ar_IQ" "ar_JO" "ar_KW" "ar_LB" "ar_LY" "ar_MA" "ar_OM" "ar_QA" "ar_SA" "ar_SD" "ar_SS" "ar_SY" "ar_TN" "ar_YE")} +%{expand:%(sh %{S:1000} "Assamese" "as" "as_IN")} +%{expand:%(sh %{S:1000} "Asturian" "ast" "ast_ES")} +%{expand:%(sh %{S:1000} "Aymara" "ayc" "ayc_PE")} +%{expand:%(sh %{S:1000} "Azeri" "az" "az_AZ" "az_IR")} +%{expand:%(sh %{S:1000} "Belarusian" "be" "be_BY")} +%{expand:%(sh %{S:1000} "Bemba" "bem" "bem_ZM")} +%{expand:%(sh %{S:1000} "Berber" "ber" "ber_DZ" "ber_MA")} +%{expand:%(sh %{S:1000} "Bulgarian" "bg" "bg_BG")} +%{expand:%(sh %{S:1000} "Bhili" "bhb" "bhb_IN")} +%{expand:%(sh %{S:1000} "Bhojpuri" "bho" "bho_NP")} +%{expand:%(sh %{S:1000} "Bislama" "bi" "bi_VU")} +%{expand:%(sh %{S:1000} "Bengali" "bn" "bn_BD" "bn_IN")} +%{expand:%(sh %{S:1000} "Tibetan" "bo" "bo_CN" "bo_IN")} +%{expand:%(sh %{S:1000} "Breton" "br" "br_FR")} +%{expand:%(sh %{S:1000} "Bosnian" "bs" "bs_BA")} +%{expand:%(sh %{S:1000} "Catalan" "ca" "ca_AD" "ca_ES" "ca_FR" "ca_IT")} +%{expand:%(sh %{S:1000} "Chechen" "ce" "ce_RU")} +%{expand:%(sh %{S:1000} "Cherokee" "chr" "chr_US")} +%{expand:%(sh %{S:1000} "Crimean Tatar" "crh" "crh_UA")} +%{expand:%(sh %{S:1000} "Czech" "cs" "cs_CZ")} +%{expand:%(sh %{S:1000} "Chuvash" "cv" "cv_RU")} +%{expand:%(sh %{S:1000} "Welsh" "cy" "cy_GB")} +%{expand:%(sh %{S:1000} "Danish" "da" "da_DK")} +%{expand:%(sh %{S:1000} "German" "de" "de_AT" "de_BE" "de_CH" "de_DE" "de_LU" "de_IT" "de_LI")} +%{expand:%(sh %{S:1000} "Dogri" "doi" "doi_IN")} +%{expand:%(sh %{S:1000} "Dhivehi" "dv" "dv_MV")} +%{expand:%(sh %{S:1000} "Dzongkha" "dz" "dz_BT")} +%{expand:%(sh %{S:1000} "Greek" "el" "r:gr" "el_CY" "el_GR")} +%{expand:%(sh %{S:1000} "English" "en" "C" "en_AG" "en_AU" "en_BW" "en_CA" "en_DK" "en_GB" "en_HK" "en_IE" "en_IL" "en_IN" "en_NG" "en_NZ" "en_PH" "en_SC" "en_SG" "en_US" "en_ZA" "en_ZM" "en_ZW")} +%{expand:%(sh %{S:1000} "Esperanto" "eo" "eo" "eo_XX")} +# Potentially unhandled: es@tradicional? an = Aragonese +%{expand:%(sh %{S:1000} "Spanish" "es" "an_ES" "es_AR" "es_BO" "es_CL" "es_CO" "es_CR" "es_CU" "es_DO" "es_EC" "es_ES" "es_GT" "es_HN" "es_MX" "es_NI" "es_PA" "es_PE" "es_PR" "es_PY" "es_SV" "es_US" "es_UY" "es_VE")} +%{expand:%(sh %{S:1000} "Estonian" "et" "et_EE")} +%{expand:%(sh %{S:1000} "Basque" "eu" "eu_ES")} +%{expand:%(sh %{S:1000} "Farsi" "fa" "fa_IR")} +%{expand:%(sh %{S:1000} "Finnish" "fi" "fi_FI")} +%{expand:%(sh %{S:1000} "Fulah" "ff" "ff_SN")} +%{expand:%(sh %{S:1000} "Faroese" "fo" "fo_FO")} +%{expand:%(sh %{S:1000} "French" "fr" "fr_BE" "fr_CA" "fr_CH" "fr_FR" "fr_LU")} +%{expand:%(sh %{S:1000} "Friulan" "fur" "fur_IT")} +%{expand:%(sh %{S:1000} "Frisian" "fy" "fy_DE" "fy_NL")} +%{expand:%(sh %{S:1000} "Irish" "ga" "ga_IE")} +%{expand:%(sh %{S:1000} "Scottish Gaelic" "gd" "gd_GB")} +%{expand:%(sh %{S:1000} "Galician" "gl" "gl_ES")} +%{expand:%(sh %{S:1000} "Gujarati" "gu" "gu_IN")} +%{expand:%(sh %{S:1000} "Manx Gaelic" "gv" "gv_GB")} +%{expand:%(sh %{S:1000} "Hausa" "ha" "ha_NG")} +%{expand:%(sh %{S:1000} "Hebrew" "he" "he_IL" "iw_IL")} +%{expand:%(sh %{S:1000} "Hindi" "hi" "bho_IN" "brx_IN" "hi_IN" "ur_IN")} +%{expand:%(sh %{S:1000} "Fiji Hindi" "hif" "hif_FJ")} +%{expand:%(sh %{S:1000} "Chhattisgarhi" "hne" "hne_IN")} +%{expand:%(sh %{S:1000} "Croatian" "hr" "hr_HR")} +%{expand:%(sh %{S:1000} "Upper Sorbian" "hsb" "hsb_DE")} +%{expand:%(sh %{S:1000} "Lower Sorbian" "dsb" "dsb_DE")} +%{expand:%(sh %{S:1000} "Breyol" "ht" "ht_HT")} +%{expand:%(sh %{S:1000} "Hungarian" "hu" "hu_HU")} +%{expand:%(sh %{S:1000} "Armenian" "hy" "hy_AM")} +%{expand:%(sh %{S:1000} "Interlingua" "ia" "ia_FR")} +%{expand:%(sh %{S:1000} "Indonesian" "id" "id_ID")} +%{expand:%(sh %{S:1000} "Igbo" "ig" "ig_NG")} +%{expand:%(sh %{S:1000} "Inupiaq" "ik" "ik_CA")} +%{expand:%(sh %{S:1000} "Icelandic" "is" "is_IS")} +%{expand:%(sh %{S:1000} "Italian" "it" "it_CH" "it_IT")} +%{expand:%(sh %{S:1000} "Inuktitut" "iu" "iu_CA")} +%{expand:%(sh %{S:1000} "Japanese" "ja" "ja" "ja_JP")} +%{expand:%(sh %{S:1000} "Georgian" "ka" "ka_GE")} +%{expand:%(sh %{S:1000} "Kabyle" "kab" "kab_DZ")} +%{expand:%(sh %{S:1000} "Kazakh" "kk" "kk_KZ")} +%{expand:%(sh %{S:1000} "Sakha" "sah" "sah_RU")} +%{expand:%(sh %{S:1000} "Greenlandic" "kl" "kl_GL")} +%{expand:%(sh %{S:1000} "Khmer" "km" "km_KH")} +%{expand:%(sh %{S:1000} "Kannada" "kn" "kn_IN")} +%{expand:%(sh %{S:1000} "Korean" "ko" "ko_KR")} +%{expand:%(sh %{S:1000} "Konkani" "kok" "kok_IN")} +%{expand:%(sh %{S:1000} "Kashmiri" "ks" "ks_IN")} +%{expand:%(sh %{S:1000} "Kurdish" "ku" "ku_TR")} +%{expand:%(sh %{S:1000} "Cornish" "kw" "kw_GB")} +%{expand:%(sh %{S:1000} "Kyrgyz" "ky" "ky_KG")} +%{expand:%(sh %{S:1000} "Luxembourgish" "lb" "lb_LU")} +%{expand:%(sh %{S:1000} "Luganda" "lg" "lg_UG")} +%{expand:%(sh %{S:1000} "Limburguish" "li" "li_BE" "li_NL")} +%{expand:%(sh %{S:1000} "Ligurian" "lij" "lij_IT")} +%{expand:%(sh %{S:1000} "Lingala" "ln" "ln_CD")} +%{expand:%(sh %{S:1000} "Laotian" "lo" "lo_LA")} +%{expand:%(sh %{S:1000} "Lithuanian" "lt" "lt_LT")} +%{expand:%(sh %{S:1000} "Latvian" "lv" "lv_LV")} +%{expand:%(sh %{S:1000} "Magahi" "mag" "mag_IN")} +%{expand:%(sh %{S:1000} "Maithili" "mai" "mai_IN" "mai_NP")} +%{expand:%(sh %{S:1000} "Mauritian Creole" "mfe" "mfe_MU")} +%{expand:%(sh %{S:1000} "Malagasy" "mg" "mg_MG")} +%{expand:%(sh %{S:1000} "Mari" "mhr" "mhr_RU")} +%{expand:%(sh %{S:1000} "Maori" "mi" "mi_NZ")} +%{expand:%(sh %{S:1000} "Miskito" "miq" "miq_NI")} +%{expand:%(sh %{S:1000} "Karbi" "mjw" "mjw_IN")} +%{expand:%(sh %{S:1000} "Macedonian" "mk" "mk_MK")} +%{expand:%(sh %{S:1000} "Malayalam" "ml" "ml_IN")} +%{expand:%(sh %{S:1000} "Mongolian" "mn" "mn_MN")} +%{expand:%(sh %{S:1000} "Manipuri" "mni" "mni_IN")} +%{expand:%(sh %{S:1000} "Marathi" "mr" "mr_IN")} +%{expand:%(sh %{S:1000} "Malay" "ms" "ms_MY")} +%{expand:%(sh %{S:1000} "Maltese" "mt" "mt_MT")} +%{expand:%(sh %{S:1000} "Burmese" "my" "my_MM")} +%{expand:%(sh %{S:1000} "Lower Saxon" "nds" "nds_DE" "nds_NL")} +%{expand:%(sh %{S:1000} "Nepali" "ne" "ne_NP")} +%{expand:%(sh %{S:1000} "Nahuatl" "nhn" "nhn_MX")} +%{expand:%(sh %{S:1000} "Niuean" "niu" "niu_NU" "niu_NZ")} +%{expand:%(sh %{S:1000} "Dutch" "nl" "nl_AW" "nl_BE" "nl_NL")} +%{expand:%(sh %{S:1000} "Norwegian" "no" "r:nb" "r:nn" "nb_NO" "nn_NO")} +%{expand:%(sh %{S:1000} "Ndebele" "nr" "nr_ZA")} +%{expand:%(sh %{S:1000} "Northern Sotho" "nso" "nso_ZA")} +%{expand:%(sh %{S:1000} "Occitan" "oc" "oc_FR")} +%{expand:%(sh %{S:1000} "Oriya" "or" "or_IN")} +%{expand:%(sh %{S:1000} "Ossetian" "os" "os_RU")} +%{expand:%(sh %{S:1000} "Punjabi" "pa" "pa_IN" "pa_PK")} +%{expand:%(sh %{S:1000} "Papiamento" "pap" "r:pp" "pap_AN" "pap_AW" "pap_CW")} +%{expand:%(sh %{S:1000} "Polish" "pl" "csb_PL" "pl_PL")} +%{expand:%(sh %{S:1000} "Pashto" "ps" "ps_AF")} +%{expand:%(sh %{S:1000} "Portuguese" "pt" "pt_BR" "pt_PT")} +%{expand:%(sh %{S:1000} "Quechua" "quz" "quz_PE")} +%{expand:%(sh %{S:1000} "Rajasthani" "raj" "raj_IN")} +%{expand:%(sh %{S:1000} "Romanian" "ro" "ro_RO")} +%{expand:%(sh %{S:1000} "Russian" "ru" "ru_RU" "ru_UA")} +%{expand:%(sh %{S:1000} "Kinyarwanda" "rw" "rw_RW")} +%{expand:%(sh %{S:1000} "Sanskrit" "sa" "sa_IN")} +%{expand:%(sh %{S:1000} "Santali" "sat" "sat_IN")} +%{expand:%(sh %{S:1000} "Sardinian" "sc" "sc_IT")} +%{expand:%(sh %{S:1000} "Sindhi" "sd" "sd_IN")} +%{expand:%(sh %{S:1000} "Saami" "se" "se_NO")} +%{expand:%(sh %{S:1000} "Samogitian" "sgs" "sgs_LT")} +%{expand:%(sh %{S:1000} "Shan" "shn" "shn_MM")} +%{expand:%(sh %{S:1000} "Secwepemctsin" "shs" "shs_CA")} +%{expand:%(sh %{S:1000} "Sinhala" "si" "si_LK")} +%{expand:%(sh %{S:1000} "Slovak" "sk" "sk_SK")} +%{expand:%(sh %{S:1000} "Slovenian" "sl" "sl_SI")} +%{expand:%(sh %{S:1000} "Samoan" "sm" "sm_WS")} +%{expand:%(sh %{S:1000} "Serbian" "sr" "sr_ME" "sr_RS")} +%{expand:%(sh %{S:1000} "Somali" "so" "so_DJ" "so_ET" "so_KE" "so_SO")} +%{expand:%(sh %{S:1000} "Albanian" "sq" "sq_AL" "sq_MK")} +%{expand:%(sh %{S:1000} "Swati" "ss" "ss_ZA")} +%{expand:%(sh %{S:1000} "Sotho" "st" "st_ZA")} +%{expand:%(sh %{S:1000} "Swedish" "sv" "sv_FI" "sv_SE")} +# sw_XX? +%{expand:%(sh %{S:1000} "Swahili" "sw" "sw_KE" "sw_TZ")} +%{expand:%(sh %{S:1000} "Silesian" "szl" "szl_PL")} +%{expand:%(sh %{S:1000} "Tamil" "ta" "ta_IN" "ta_LK")} +%{expand:%(sh %{S:1000} "Telugu" "te" "te_IN")} +%{expand:%(sh %{S:1000} "Tajik" "tg" "tg_TJ")} +%{expand:%(sh %{S:1000} "Thai" "th" "th_TH")} +%{expand:%(sh %{S:1000} "Tharu/Tharuhati" "the" "the_NP")} +%{expand:%(sh %{S:1000} "Tok Pisin" "tpi" "tpi_PG")} +%{expand:%(sh %{S:1000} "Turkmen" "tk" "tk_TM")} +%{expand:%(sh %{S:1000} "Pilipino" "tl" "r:ph" "fil_PH" "tl_PH")} +%{expand:%(sh %{S:1000} "Tswana" "tn" "tn_ZA")} +%{expand:%(sh %{S:1000} "Tonga" "to" "to_TO")} +%{expand:%(sh %{S:1000} "Turkish" "tr" "tr_CY" "tr_TR")} +%{expand:%(sh %{S:1000} "Tsonga" "ts" "ts_ZA")} +%{expand:%(sh %{S:1000} "Tatar" "tt" "tt_RU")} +%{expand:%(sh %{S:1000} "Tulu" "tcy" "tcy_IN")} +%{expand:%(sh %{S:1000} "Uyghur" "ug" "ug_CN")} +%{expand:%(sh %{S:1000} "Unami" "unm" "unm_US")} +%{expand:%(sh %{S:1000} "Ukrainian" "uk" "uk_UA")} +%{expand:%(sh %{S:1000} "Urdu" "ur" "ur_PK")} +%{expand:%(sh %{S:1000} "Uzbek" "uz" "uz_UZ")} +%{expand:%(sh %{S:1000} "Venda" "ve" "ve_ZA")} +%{expand:%(sh %{S:1000} "Vietnamese" "vi" "vi_VN")} +%{expand:%(sh %{S:1000} "Walloon" "wa" "wa_BE")} +%{expand:%(sh %{S:1000} "Walser" "wae" "wae_CH")} +%{expand:%(sh %{S:1000} "Wolof" "wo" "wo_SN")} +%{expand:%(sh %{S:1000} "Xhosa" "xh" "xh_ZA")} +%{expand:%(sh %{S:1000} "Yiddish" "yi" "yi_US")} +%{expand:%(sh %{S:1000} "Yoruba" "yo" "yo_NG")} +%{expand:%(sh %{S:1000} "Yue Chinese (Cantonese)" "yue" "yue_HK")} +%{expand:%(sh %{S:1000} "Yau" "yuw" "yuw_PG")} +%{expand:%(sh %{S:1000} "Chinese" "zh" "zh_CN" "zh_HK" "zh_SG" "zh_TW" "cmn_TW" "hak_TW" "lzh_TW" "nan_TW")} +%{expand:%(sh %{S:1000} "Zulu" "zu" "zu_ZA")} + +%endif %files -f libc.lang %if %{with timezone} %verify(not md5 size mtime) %config(noreplace) %{_sysconfdir}/localtime %endif -%verify(not md5 size mtime) %config(noreplace) %{_sysconfdir}/nsswitch.conf +# (tpg) please do not set (noreplace) here as after update system may end up in broken state +%config %{_sysconfdir}/nsswitch.conf %verify(not md5 size mtime) %config(noreplace) %{_sysconfdir}/ld.so.conf %dir %{_sysconfdir}/ld.so.conf.d %config(noreplace) %{_sysconfdir}/rpc @@ -248,7 +545,7 @@ Linux system will not function. %{_localedir}/locale.alias /sbin/sln %{_prefix}/libexec/getconf -%ifarch x86_64 +%if %isarch %{x86_64} %exclude %{_prefix}/libexec/getconf/POSIX_V6_ILP32_OFF32 %exclude %{_prefix}/libexec/getconf/POSIX_V6_ILP32_OFFBIG %exclude %{_prefix}/libexec/getconf/POSIX_V7_ILP32_OFF32 @@ -256,23 +553,30 @@ Linux system will not function. %exclude %{_prefix}/libexec/getconf/XBS5_ILP32_OFF32 %exclude %{_prefix}/libexec/getconf/XBS5_ILP32_OFFBIG %endif -%{_slibdir}/ld-%{version}.so -%ifarch %{ix86} +%{_slibdir}/ld-%{fullver}.so +%if %isarch %{ix86} %{_slibdir}/ld-linux.so.2 -%{_slibdir}/i686 %endif -%ifarch x86_64 +%if %isarch %{x86_64} %{_slibdir}/ld-linux-x86-64.so.2 %endif -%ifarch armv7l +%if %isarch armv7l armv8l %{_slibdir}/ld-linux.so.3 %endif -%ifarch armv7hl armv6j +%if %isarch armv7hl armv7hnl armv8hl armv8hnl armv8hcnl armv6j %{_slibdir}/ld-linux-armhf.so.3 %endif -%ifarch aarch64 +%if %isarch aarch64 %{_slibdir}/ld-linux-aarch64.so.1 -%{_slibdir32}/ld-linux-aarch64.so.1 +/lib/ld-linux-aarch64.so.1 +%endif +%if %isarch %{mips} +%{_slibdir}/ld.so.1 +%endif +%if %isarch riscv64 +%{_slibdir}/ld-linux-riscv64-lp64d.so.1 +%dir %{_slibdir}/lp64d +%dir %{_libdir}/lp64d %endif %{_slibdir}/lib*-[.0-9]*.so %{_slibdir}/lib*.so.[0-9]* @@ -283,14 +587,13 @@ Linux system will not function. %{_libdir}/gconv/*.so %{_libdir}/gconv/gconv-modules %ghost %{_libdir}/gconv/gconv-modules.cache -# %attr(4755,root,root) %{_prefix}/libexec/pt_chown %{_bindir}/catchsegv %{_bindir}/gencat %{_bindir}/getconf %{_bindir}/getent %{_bindir}/iconv %{_bindir}/ldd -%ifarch %{ix86} +%if %isarch %{ix86} %{_bindir}/lddlibc4 %endif %{_bindir}/locale @@ -307,22 +610,36 @@ Linux system will not function. %ghost %{_sysconfdir}/ld.so.cache %dir %{_var}/cache/ldconfig %ghost %{_var}/cache/ldconfig/aux-cache -%{_var}/lib/rpm/filetriggers/ldconfig.* %{_var}/db/Makefile +%if %isarch mips mipsel +%if %{build_biarch} +%{_slibdir32}/ld-%{fullver}.so +%{_slibdir32}/ld.so.1 +%{_slibdir32}/lib*-[.0-9]*.so +%{_slibdir32}/lib*.so.[0-9]* +%{_slibdir32}/libSegFault.so +%dir %{_slibdirn32} +%{_slibdirn32}/ld*-[.0-9]*.so +%{_slibdirn32}/ld.so.1 +%{_slibdirn32}/lib*-[.0-9]*.so +%{_slibdirn32}/lib*.so.[0-9]* +%{_slibdirn32}/libSegFault.so +%endif +%endif ######################################################################## -%if %{build_multiarch} +%if %{build_biarch} #----------------------------------------------------------------------- -%package -n %{multilibc} +%package -n %{multilibc} Summary: The GNU libc libraries Group: System/Libraries -Requires(post): %{name} = %{EVRD} -Conflicts: glibc < 6:2.14.90-13 +Conflicts: glibc < 2.14.90-13 +Requires: %{name} = %{EVRD} %post -n %{multilibc} %{_sbindir}/iconvconfig %{_libdir32}/gconv -o %{_libdir32}/gconv/gconv-modules.cache -%description -n %{multilibc} +%description -n %{multilibc} The glibc package contains standard libraries which are used by multiple programs on the system. In order to save disk space and memory, as well as to make upgrading easier, common system code is @@ -331,17 +648,19 @@ contains the most important sets of shared libraries: the standard C library and the standard math library. Without these two libraries, a Linux system will not function. -%files -n %{multilibc} -%{_slibdir32}/ld-%{version}.so +%files -n %{multilibc} +%{_slibdir32}/ld-%{fullver}.so %{_slibdir32}/ld-linux*.so.2 %{_slibdir32}/lib*-[.0-9]*.so %{_slibdir32}/lib*.so.[0-9]* %{_slibdir32}/libSegFault.so %dir %{_libdir32}/audit %{_libdir32}/audit/sotruss-lib.so +%dir %{_libdir32}/gconv %{_libdir32}/gconv/*.so %{_libdir32}/gconv/gconv-modules %ghost %{_libdir32}/gconv/gconv-modules.cache + %{_prefix}/libexec/getconf/POSIX_V6_ILP32_OFF32 %{_prefix}/libexec/getconf/POSIX_V6_ILP32_OFFBIG %{_prefix}/libexec/getconf/POSIX_V7_ILP32_OFF32 @@ -349,7 +668,7 @@ Linux system will not function. %{_prefix}/libexec/getconf/XBS5_ILP32_OFF32 %{_prefix}/libexec/getconf/XBS5_ILP32_OFFBIG #----------------------------------------------------------------------- -# build_multiarch +# build_biarch %endif #----------------------------------------------------------------------- @@ -357,11 +676,12 @@ Linux system will not function. Summary: Header and object files for development using standard C libraries Group: Development/C Requires: %{name} = %{EVRD} -%if %{build_multiarch} +#Requires: pkgconfig(libxcrypt) +%if %{build_biarch} Requires: %{multilibc} = %{EVRD} %endif -Requires: kernel-headers -%rename glibc-doc +Autoreq: true +Requires: %{?cross:cross-}kernel-headers >= %{enablekernel} %if %{with pdf} %rename glibc-doc-pdf %endif @@ -374,29 +694,57 @@ will use the standard C libraries, your system needs to have these standard header and object files available in order to create the executables. -%files devel -%{_infodir}/libc.info* +%package doc +Summary: Docs for %{name} +Group: Development/C +BuildArch: noarch + +%description doc +The glibc-docs package contains docs for %{name}. + +%files doc %doc %{_docdir}/glibc/* %exclude %{_docdir}/glibc/nss %exclude %{_docdir}/glibc/gai.conf %exclude %{_docdir}/glibc/COPYING %exclude %{_docdir}/glibc/COPYING.LIB + +%files devel +%{_infodir}/libc.info* %{_includedir}/* %{_libdir}/*.o %{_libdir}/*.so +%exclude %{_slibdir}/ld*-[.0-9]*.so +%exclude %{_slibdir}/lib*-[.0-9]*.so +%exclude %{_slibdir}/libSegFault.so %{_libdir}/libc_nonshared.a +# Exists for some, but not all arches +%optional %{_libdir}/libmvec_nonshared.a %{_libdir}/libg.a %{_libdir}/libmcheck.a -%ifarch x86_64 -%{_libdir}/libmvec.a -%{_libdir}/libmvec_nonshared.a -%endif -%if %{build_multiarch} +%optional %{_libdir}/libmvec.a +%if %{build_biarch} %{_libdir32}/*.o %{_libdir32}/*.so %{_libdir32}/libc_nonshared.a %{_libdir32}/libg.a %{_libdir32}/libmcheck.a +%if %isarch mips mipsel +%exclude %{_slibdir32}/ld*-[.0-9]*.so +%exclude %{_slibdir32}/lib*-[.0-9]*.so +%exclude %{_slibdir32}/libSegFault.so +%exclude %{_slibdirn32}/ld*-[.0-9]*.so +%exclude %{_slibdirn32}/lib*-[.0-9]*.so +%exclude %{_slibdirn32}/libSegFault.so +%{_libdirn32}/*.o +%{_libdirn32}/*.so +%{_libdirn32}/libc_nonshared.a +%{_libdirn32}/libg.a +%{_libdirn32}/libmcheck.a +%exclude %{_slibdir}/ld*-[.0-9]*.so +%exclude %{_slibdir}/lib*-[.0-9]*.so +%exclude %{_slibdir}/libSegFault.so +%endif %endif #----------------------------------------------------------------------- @@ -404,6 +752,7 @@ executables. Summary: Static libraries for GNU C library Group: Development/C Requires: %{name}-devel = %{EVRD} +#Requires: %{_lib}crypt-static-devel >= 4.4.3 %description static-devel The glibc-static-devel package contains the static libraries necessary @@ -414,44 +763,52 @@ library. %files static-devel %{_libdir}/libBrokenLocale.a %{_libdir}/libanl.a -%{_libdir}/libc.a %{_libdir}/libcrypt.a +%{_libdir}/libc.a %{_libdir}/libdl.a %{_libdir}/libm.a -%ifarch x86_64 -%{_libdir}/libm-%{version}.a -%endif +# Versioned libm.a seems to be generated only on x86_64 +%optional %{_libdir}/libm-%{version}.a %{_libdir}/libpthread.a %{_libdir}/libresolv.a %{_libdir}/librt.a %{_libdir}/libutil.a -%if %{build_multiarch} +%if %{build_biarch} %{_libdir32}/libBrokenLocale.a -%{_libdir32}/libanl.a -%{_libdir32}/libc.a +%{_libdir32}/libanl.ao %{_libdir32}/libcrypt.a +%{_libdir32}/libc.a %{_libdir32}/libdl.a %{_libdir32}/libm.a %{_libdir32}/libpthread.a %{_libdir32}/libresolv.a %{_libdir32}/librt.a %{_libdir32}/libutil.a +%if %isarch mips mipsel +%{_libdirn32}/libBrokenLocale.a +%{_libdirn32}/libanl.a +%{_libdirn32}/libc.a +%{_libdirn32}/libdl.a +%{_libdirn32}/libm.a +%{_libdirn32}/libpthread.a +%{_libdirn32}/libresolv.a +%{_libdirn32}/librt.a +%{_libdirn32}/libutil.a +%endif %endif ######################################################################## %if %{with nscd} #----------------------------------------------------------------------- -%package -n nscd +%package -n nscd Summary: A Name Service Caching Daemon (nscd) Group: System/Servers Conflicts: kernel < 2.2.0 +BuildRequires: rpm-helper Requires(post): systemd -Requires(pre): rpm-helper -Requires(preun):rpm-helper -Requires(post): rpm-helper -Requires(postun):rpm-helper +Requires(pre): shadow -%description -n nscd +%description -n nscd Nscd caches name service lookups and can dramatically improve performance with NIS+, and may help with DNS as well. @@ -459,7 +816,7 @@ performance with NIS+, and may help with DNS as well. %_pre_useradd nscd / /sbin/nologin %post -n nscd - %_post_service nscd + %_post_service nscd.service %preun -n nscd %_preun_service nscd @@ -470,13 +827,27 @@ performance with NIS+, and may help with DNS as well. systemctl condrestart nscd > /dev/null 2>&1 || : fi -%files -n nscd +%files -n nscd %config(noreplace) %{_sysconfdir}/nscd.conf -%{_tmpfilesdir}/nscd.conf +%dir %attr(0755,root,root) /run/nscd +%dir %attr(0755,root,root) %{_var}/db/nscd +%dir %attr(0755,root,root) %{_sysconfdir}/netgroup +%{_presetdir}/86-nscd.preset %{_unitdir}/nscd.service %{_unitdir}/nscd.socket %{_sbindir}/nscd -/var/db/nscd +%{_tmpfilesdir}/nscd.conf +%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /run/nscd/nscd.pid +%attr(0666,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /run/nscd/socket +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /run/nscd/passwd +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /run/nscd/group +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /run/nscd/hosts +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /run/nscd/services +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) %{_var}/db/nscd/passwd +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) %{_var}/db/nscd/group +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) %{_var}/db/nscd/hosts +%attr(0600,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) %{_var}/db/nscd/services +%ghost %config(missingok,noreplace) %{_sysconfdir}/sysconfig/nscd #----------------------------------------------------------------------- # with nscd %endif @@ -484,19 +855,19 @@ performance with NIS+, and may help with DNS as well. ######################################################################## %if %{with utils} #----------------------------------------------------------------------- -%package utils +%package utils Summary: Development utilities from GNU C library Group: Development/Other Requires: %{name} = %{EVRD} -%description utils +%description utils The glibc-utils package contains memusage, a memory usage profiler, mtrace, a memory leak tracer and xtrace, a function call tracer which can be helpful during program debugging. If unsure if you need this, don't install this package. -%files utils +%files utils %{_bindir}/memusage %{_bindir}/memusagestat %{_bindir}/mtrace @@ -504,7 +875,7 @@ If unsure if you need this, don't install this package. %{_bindir}/xtrace %{_slibdir}/libmemusage.so %{_slibdir}/libpcprofile.so -%if %{build_multiarch} +%if %{build_biarch} %{_slibdir32}/libmemusage.so %{_slibdir32}/libpcprofile.so %endif @@ -541,6 +912,7 @@ to use the internationalization features of the GNU libc. %package -n timezone Summary: Time zone descriptions Group: System/Base +Obsoletes: zoneinfo %description -n timezone These are configuration files that describe possible time zones. @@ -554,203 +926,33 @@ These are configuration files that describe possible time zones. # with timezone %endif -######################################################################## +%if %{with crosscompilers} +%global kernelver %(rpm -q --qf '%%{version}-%%{release}%%{disttag}' kernel-release-source) +%( +for i in %{long_targets}; do + [ "$i" = "%{_target_platform}" ] && continue + package=cross-${i}-libc + cat <@@g' -e 's@@@g' configure* +sed -e 's@@@g' -e 's@@@g' -i configure* aclocal autoconf @@ -777,7 +977,7 @@ autoconf #----------------------------------------------------------------------- %build # ... -mkdir bin +mkdir -p bin ln -sf %{_bindir}/ld.bfd bin/ld export PATH=$PWD/bin:$PATH @@ -794,57 +994,115 @@ function BuildGlibc() { # Select optimization flags and compiler to use BuildAltArch="no" BuildCompFlags="" - BuildFlags="" + # -Wall is just added to get conditionally %%optflags printed... + # cut -flto flag +%if %{with lto} + BuildFlags="$(rpm --target ${arch}-%{_target_os} -D '%{__common_cflags} -Wall' -E %%{optflags} | sed -e 's# -fPIC##g' -e 's#-m64##' -e 's#-gdwarf-4##;s#-g##' -e 's#-m[36][24]##' -e 's#-O[s2]#-O3#' -e 's#-Wp,-D_FORTIFY_SOURCE=2##')" +%else + BuildFlags="$(rpm --target ${arch}-%{_target_os} -D '%{__common_cflags} -Wall' -E %%{optflags} | sed -e 's# -fPIC##g' -e 's#-m64##' -e 's#-gdwarf-4##;s#-g##' -e 's#-flto##' -e 's#-m[36][24]##' -e 's#-O[s2]#-O3#' -e 's#-Wp,-D_FORTIFY_SOURCE=2##')" +%endif case $arch in i[3-6]86) -%ifarch x86_64 - BuildFlags="-march=pentium4 -mtune=generic" +%ifarch %{x86_64} +%ifarch znver1 + BuildFlags="$BuildFlags -march=znver1 -mtune=znver1" +%else + BuildFlags="$BuildFlags -march=x86-64 -mtune=generic" +%endif BuildAltArch="yes" BuildCompFlags="-m32" -%else - BuildFlags="-march=$arch -mtune=generic -mstackrealign" +%endif +%ifarch %{ix86} + BuildFlags="$BuildFlags -march=i686 -msse -mfpmath=sse -fasynchronous-unwind-tables -mtune=generic" %endif ;; + znver1) + BuildFlags="$BuildFlags -march=znver1 -mtune=znver1" + ;; x86_64) - BuildFlags="-mtune=generic" + BuildFlags="$BuildFlags -march=x86-64 -mtune=generic" + ;; + mips|mipsel) + BuildCompFlags="$BuildFlags" + ;; + mips32|mips32el) + BuildFlags="$BuildFlags -march=mips3 -mabi=n32" + BuildCompFlags="$BuildFlags -march=mips3 -mabi=n32" + ;; + mips64|mips64el) + BuildFlags="$BuildFlags -march=mips3 -mabi=64" + BuildCompFlags="$BuildFlags -march=mips3 -mabi=64" ;; armv5t*) - BuildFlags="-march=armv5t" - BuildCompFlags="-march=armv5t" + BuildFlags="$BuildFlags -march=armv5t" + BuildCompFlags="$BuildFlags -march=armv5t" ;; # to check armv7*) - BuildFlags="-march=armv7-a" - BuildCompFlags="-march=armv7-a" + # As of gcc 8.3.0, glibc 2.29, using -funwind-tables or -fasynchronous-unwind-tables + # on armv7hnl results in a build failure because configure can't find a + # compiler it believes to be working -- with -nostdlib, we get an + # undefined reference to __aeabi_unwind_cpp_pr0 + BuildFlags="`echo $BuildFlags |sed -e 's,-funwind-tables ,,g;s,-fasynchronous-unwind-tables,,g'`" + BuildCompFlags="$BuildFlags" ;; armv6*) - BuildFlags="-march=armv6" - BuildCompFlags="-march=armv6" + BuildCompFlags="$BuildFlags" ;; esac - BuildCompFlags="$BuildCompFlags -fuse-ld=bfd" + BuildCompFlags="$BuildCompFlags" - # Choose multiarch support + # Choose biarch support MultiArchFlags= case $arch in - i686 | x86_64) + i686|x86_64|znver1) MultiArchFlags="--enable-multi-arch" ;; esac # Determine C & C++ compilers - BuildCC="%{__cc} $BuildCompFlags" - BuildCXX="%{__cxx} $BuildCompFlags" + BuildCC="gcc -fuse-ld=bfd $BuildCompFlags" + BuildCXX="g++ -fuse-ld=bfd $BuildCompFlags" - #add_flags="%(rpm --eval '%%{__common_cflags}' |sed -e 's,-Werror[^ ]*,,g;s,-ffat-lto-objects,,g')" - BuildFlags="$BuildFlags -DNDEBUG=1 %{__common_cflags} -O3" + # Are we supposed to cross-compile? + if [ "%{target_cpu}" != "%{_target_cpu}" ]; then + # Can't use BuildCC anymore with previous changes. + BuildCC="%{cross_program_prefix}gcc $BuildCompFlags" + BuildCXX="%{cross_program_prefix}g++ $BuildCompFlags" + BuildCross="--build=%{_target_platform}" + export libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes + fi + +# set some extra flags here +# (tpg) build with -O3 + + BuildFlags="$BuildFlags -Wp,-D_GLIBCXX_ASSERTIONS -DNDEBUG=1 %(echo %{__common_cflags} | sed -e 's#-m[36][24]##g;s#-O[s2]#-O3#g' -e 's#-Wp,-D_FORTIFY_SOURCE=2##')" + %ifnarch %{arm} + # As of gcc 8.3.0, glibc 2.29, using -funwind-tables or -fasynchronous-unwind-tables + # on armv7hnl results in a build failure because configure can't find a + # compiler it believes to be working -- with -nostdlib, we get an + # undefined reference to __aeabi_unwind_cpp_pr0 + BuildFlags="-funwind-tables -fasynchronous-unwind-tables $BuildFlags" + %endif +%if !%{with lto} + %if "%{distepoch}" >= "2015.0" + BuildFlags="$BuildFlags -fno-lto" + %endif +%endif + + if [ "$arch" = 'i586' ] || [ "$arch" = 'i686' ]; then + # Work around https://sourceware.org/ml/libc-alpha/2015-10/msg00745.html + BuildCC="$BuildCC -fomit-frame-pointer" + BuildCXX="$BuildCXX -fomit-frame-pointer" + fi # XXX: -frecord-gcc-switches makes gold abort with assertion error and gcc segfault :| - #BuildFlags="$(echo $BuildFlags |sed -e 's#-frecord-gcc-switches##g')" +# BuildFlags="$(echo $BuildFlags |sed -e 's#-frecord-gcc-switches##g')" + BuildFlags="$(echo $BuildFlags |sed -e 's#-frecordcc-switches##g')" # Do not use direct references against %gs when accessing tls data # XXX make it the default in GCC? (for other non glibc specific usage) -%ifarch %{xenarches} +%if %isarch %{xenarches} BuildFlags="$BuildFlags -mno-tls-direct-seg-refs" %endif @@ -856,11 +1114,8 @@ function BuildGlibc() { # But as the alternate arch is less likely to make any use of the # functionality and that we might just ditch biarch packaging completely, # we just enable it on the main arch for now. -%if %{with nsscrypt} || %{with systap} - if [[ "$BuildAltArch" = "no" ]]; then -%if %{with nsscrypt} - ExtraFlags="$ExtraFlags --enable-nss-crypt" -%endif +%if %{with systap} + if [ "$BuildAltArch" = 'no' ]; then %if %{with systap} ExtraFlags="$ExtraFlags --enable-systemtap" %endif @@ -870,33 +1125,83 @@ function BuildGlibc() { # Add-ons AddOns="libidn" - # Force a separate and clean object dir - rm -rf build-$arch-linux - mkdir build-$arch-linux - pushd build-$arch-linux - - [[ "$BuildAltArch" = "yes" ]] && touch ".alt" || touch ".main" - CC="$BuildCC" CXX="$BuildCXX" CFLAGS="$BuildFlags -Wno-error -fno-strict-aliasing" LDFLAGS="%{ldflags} -fuse-ld=bfd" ../configure \ - $arch-%{_target_vendor}-%{_target_os}%{?_gnu} \ + # Kernel headers directory + %if "%{name}" == "glibc" + KernelHeaders=%{_includedir} + %else + KernelHeaders=/usr/%{target_arch}-%{_target_os}/include + %endif + + LIB=$(rpm --macros %{_usrlibrpm}/macros:%{_usrlibrpm}/platform/${arch}-%{_target_os}/macros --target=${arch} -E %%{_lib}) + LIBDIR=$(rpm --macros %{_usrlibrpm}/macros:%{_usrlibrpm}/platform/${arch}-%{_target_os}/macros --target=${arch} -E %%{_libdir}) + SLIBDIR=/${LIB} + + # Determine library name + glibc_cv_cc_64bit_output=no + if echo ".text" | $BuildCC -c -o test.o -xassembler -; then + case `/usr/bin/file test.o` in + *"ELF 64"*) + glibc_cv_cc_64bit_output=yes + ;; + esac + fi + rm -f test.o + # Force a separate object dir + mkdir -p build-$arch-linux + cd build-$arch-linux + [ "$BuildAltArch" = 'yes' ] && touch ".alt" || touch ".main" + export libc_cv_slibdir=${SLIBDIR} + case $arch in + znver1) + configarch=x86_64 + ;; + *) + configarch=$arch + ;; + esac + CC="$BuildCC" CXX="$BuildCXX" CFLAGS="$BuildFlags -Wno-error -fno-strict-aliasing" ARFLAGS="$ARFLAGS --generate-missing-build-notes=yes" LDFLAGS="%{ldflags} -fuse-ld=bfd" ../configure \ + --target=$configarch-%{platform} \ + --host=$configarch-%{platform} \ + $BuildCross \ --prefix=%{_prefix} \ --libexecdir=%{_prefix}/libexec \ + --libdir=${LIBDIR} \ --infodir=%{_infodir} \ --localedir=%{_localedir} \ --enable-add-ons=$AddOns \ --disable-profile \ --enable-static \ + --disable-nss-crypt \ +%if %{with selinux} + --with-selinux \ +%else + --without-selinux \ +%endif +%if !%{with nscd} + --disable-build-nscd \ +%endif --enable-bind-now \ + --enable-lock-elision \ + --enable-tunables \ + --enable-stack-protector=strong \ $ExtraFlags \ $MultiArchFlags \ --enable-kernel=%{enablekernel} \ - --with-headers=%{_includedir} ${1+"$@"} - %make -r - popd + --with-headers=$KernelHeaders ${1+"$@"} \ + --with-bugurl=%{bugurl} + + # FIXME drop -j1 if the Makefiles ever get fixed for parallel build + if [ "$BuildAltArch" = "yes" ]; then + %make -j1 -r all subdir_stubs LIBGD=no + else + %make -j1 -r all subdir_stubs + fi + cd - check_flags="-k" # Generate test matrix - [[ -d "build-$arch-linux" ]] || { + [ -d "build-$arch-linux" ] || { echo "ERROR: PrepareGlibcTest: build-$arch-linux does not exist!" return 1 } @@ -904,27 +1209,93 @@ function BuildGlibc() { echo "$BuildJobs -d build-$arch-linux $check_flags" >> %{checklist} case $arch in - i686) base_arch=i586;; + i[56]86) base_arch=i686;; *) base_arch=none;; esac - [[ -d "build-$base_arch-linux" ]] && { + [ -d "build-$base_arch-linux" ] && { check_flags="$check_flags -l build-$base_arch-linux/elf/ld.so" echo "$BuildJobs -d build-$arch-linux $check_flags" >> %{checklist} } return 0 } -# Build main glibc -BuildGlibc %{_target_cpu} +%if %{with crosscompilers} +for i in %{targets}; do + CPU=$(echo $i |cut -d- -f1) + OS=$(echo $i |cut -d- -f2) + TRIPLET="$(rpm --target=${CPU}-${OS} -E %%{_target_platform})" + if [ "${TRIPLET}" = "%{_target_platform}" ]; then + echo "===== Skipping $i cross libc (native arch) =====" + continue + fi + echo "===== Building %{_target_platform} -> $i ($TRIPLET) cross libc =====" + KARCH=$(echo $TRIPLET |cut -d- -f1) + case $KARCH in + aarch64) + KARCH=arm64 + ;; + arm*) + KARCH=arm + ;; + i.86) + KARCH=x86 + ;; + esac + mkdir -p obj-${TRIPLET} + cd obj-${TRIPLET} +%if %{with lto} + CFLAGS="$(rpm --target ${i} --eval '%%{optflags} -fuse-ld=bfd -fno-strict-aliasing -Wno-error' |sed -e 's,-m[36][24],,;s,-Werror[^ ]*,,g')" \ + CXXFLAGS="$(rpm --target ${i} --eval '%%{optflags} -fuse-ld=bfd -fno-strict-aliasing -Wno-error' |sed -e 's,-m[36][24],,;s,-Werror[^ ]*,,g')" \ + ASFLAGS="$(rpm --target ${i} --eval '%%{optflags} -fuse-ld=bfd -fno-strict-aliasing -Wno-error' |sed -e 's,-m[36][24],,;s,-Werror[^ ]*,,g')" \ + LDFLAGS="$(rpm --target ${i} --eval '%%{ldflags} -fuse-ld=bfd -fno-strict-aliasing -Wno-error' |sed -e 's,-m[36][24],,')" \ +%else + CFLAGS="$(rpm --target ${i} --eval '%%{optflags} -fuse-ld=bfd -fno-strict-aliasing -Wno-error' |sed -e 's,-m[36][24],,;s,-flto,,g;s,-Werror[^ ]*,,g')" \ + CXXFLAGS="$(rpm --target ${i} --eval '%%{optflags} -fuse-ld=bfd -fno-strict-aliasing -Wno-error' |sed -e 's,-m[36][24],,;s,-flto,,g;s,-Werror[^ ]*,,g')" \ + ASFLAGS="$(rpm --target ${i} --eval '%%{optflags} -fuse-ld=bfd -fno-strict-aliasing -Wno-error' |sed -e 's,-m[36][24],,;s,-flto,,g;s,-Werror[^ ]*,,g')" \ + LDFLAGS="$(rpm --target ${i} --eval '%%{ldflags} -fuse-ld=bfd -fno-strict-aliasing -Wno-error' |sed -e 's,-m[36][24],,;s,-flto,,g')" \ +%endif + CC="${TRIPLET}-gcc ${CFLAGS}" \ + ../configure \ + --prefix=%{_prefix}/${TRIPLET} \ + --host=${TRIPLET} \ + --target=${TRIPLET} \ + --with-gnu-ld=${TRIPLET}-ld.bfd \ + --with-headers=%{_prefix}/${TRIPLET}/include + # We set CXX to empty to prevent links-dso-program from being built + # (it may not work -- if we're using a bootstrap version of gcc, + # there's no libstdc++ or libgcc_s) + %make CXX="" LIBGD=no + cd .. +done +%endif -%if %{build_multiarch} - %ifarch x86_64 +# Build main glibc +BuildGlibc %{target_cpu} + +%if %{build_biarch} + %if %isarch %{x86_64} BuildGlibc i686 %endif + %if %isarch mips + BuildGlibc mips64 + BuildGlibc mips32 + %endif + %if %isarch mipsel + BuildGlibc mips64el + BuildGlibc mips32el + %endif + %if %isarch mips64 + BuildGlibc mips + BuildGlibc mips32 + %endif + %if %isarch mips64el + BuildGlibc mipsel + BuildGlibc mips32el + %endif %else # Build i686 libraries if not already building for i686 - case %{_target_cpu} in + case %{target_cpu} in i686) ;; i[3-5]86) @@ -934,13 +1305,15 @@ BuildGlibc %{_target_cpu} %endif # post install wrapper -gcc -static -Lbuild-%{_target_cpu}-linux %{optflags} -Os %{SOURCE2} -o build-%{_target_cpu}-linux/glibc_post_upgrade \ +gcc -static -Lbuild-%{target_cpu}-linux %{optflags} -Os %{SOURCE2} -o build-%{target_cpu}-linux/glibc_post_upgrade \ '-DLIBTLS="/%{_lib}/tls/"' \ '-DGCONV_MODULES_DIR="%{_libdir}/gconv"' \ '-DLD_SO_CONF="/etc/ld.so.conf"' \ '-DICONVCONFIG="%{_sbindir}/iconvconfig"' #----------------------------------------------------------------------- + +%if "%{target_cpu}" != "i686" %check # ... export PATH=$PWD/bin:$PATH @@ -950,26 +1323,81 @@ export TIMEOUTFACTOR=16 while read arglist; do sh %{SOURCE5} $arglist || exit 1 done < %{checklist} +%endif #----------------------------------------------------------------------- %install # ... +%if !%isarch %{mipsx} export PATH=$PWD/bin:$PATH - -%if %{build_multiarch} - %ifarch x86_64 - ALT_ARCH=i686 - %endif - %make install install_root=%{buildroot} -C build-${ALT_ARCH}-linux -%endif -%make install install_root=%{buildroot} -C build-%{_target_cpu}-linux -%if %{build_multiarch} - %ifarch x86_64 - rm -f %{buildroot}%{_bindir}/lddlibc4 - %endif %endif -install -m700 build-%{_target_cpu}-linux/glibc_post_upgrade -D %{buildroot}%{_sbindir}/glibc_post_upgrade +%if %{with crosscompilers} +for i in %{long_targets}; do + if [ "${i}" = "%{_target_platform}" ]; then + echo "===== Skipping $i cross libc (native arch)" + continue + fi + echo "===== Installing %{_target_platform} -> $i cross libc =====" + cd obj-${i} + %make_install + cd .. + # We don't need all the bits and pieces with a crosscompiler + rm -rf %{buildroot}%{_prefix}/$i/bin %{buildroot}%{_prefix}/$i/sbin %{buildroot}%{_prefix}/$i/var %{buildroot}%{_prefix}/$i/share %{buildroot}%{_prefix}/$i/etc +done +%endif + +make install_root=%{buildroot} install -C build-%{target_cpu}-linux + +%if %{build_biarch} || %isarch %{mips} %{mipsel} + %if %isarch %{x86_64} + ALT_ARCHES=i686-linux + %endif + %if %isarch %{mips} + ALT_ARCHES="mips64-linux mips32-linux" + %endif + %if %isarch %{mipsel} + ALT_ARCHES="mips64el-linux mips32el-linux" + %endif + %if %isarch mips64 + ALT_ARCHES="mips-linux mips32-linux" + %endif + %if %isarch mips64el + ALT_ARCHES="mipsel-linux mips32el-linux" + %endif + for ALT_ARCH in $ALT_ARCHES; do + mkdir -p %{buildroot}/$ALT_ARCH + %make install_root=%{buildroot}/$ALT_ARCH LIBGD=no -C build-$ALT_ARCH \ + install + + # Dispatch */lib only + case "$ALT_ARCH" in + mips32*) + LIB="%{_slibdirn32}" + ;; + mips64*) + LIB="%{_slibdir}" + ;; + mips*) + LIB="%{_slibdir32}" + ;; + *) + LIB=/lib + ;; + esac + mv %{buildroot}/$ALT_ARCH/$LIB %{buildroot}/$LIB + mv %{buildroot}/$ALT_ARCH%{_libexecdir}/getconf/* %{buildroot}%{_prefix}/libexec/getconf/ + [ ! -d %{buildroot}%{_prefix}/$LIB/ ] && mkdir -p %{buildroot}%{_prefix}/$LIB/ + mv %{buildroot}/$ALT_ARCH%{_prefix}/$LIB/* %{buildroot}%{_prefix}/$LIB/ + + rm -rf %{buildroot}/$ALT_ARCH + # XXX Dispatch 32-bit stubs + (sed '/^@/d' include/stubs-prologue.h; LC_ALL=C sort $(find build-$ALT_ARCH -name stubs)) \ + > %{buildroot}%{_includedir}/gnu/stubs-32.h + done +%endif + +install -m700 build-%{target_cpu}-linux/glibc_post_upgrade -D %{buildroot}%{_sbindir}/glibc_post_upgrade sh manpages/Script.sh # Install extra glibc libraries @@ -978,9 +1406,9 @@ function InstallGlibc() { local SubDir="$2" local LibDir="$3" - [[ -z "$LibDir" ]] && LibDir="%{_slibdir}" + [ -z "$LibDir" ] && LibDir="%{_slibdir}" - pushd $BuildDir + cd $BuildDir mkdir -p %{buildroot}$LibDir/$SubDir/ install -m755 libc.so %{buildroot}$LibDir/$SubDir/`basename %{buildroot}$LibDir/libc-*.so` ln -sf `basename %{buildroot}$LibDir/libc-*.so` %{buildroot}$LibDir/$SubDir/`basename %{buildroot}$LibDir/libc.so.*` @@ -992,15 +1420,18 @@ function InstallGlibc() { ln -sf `basename %{buildroot}$LibDir/libthread_db-*.so` %{buildroot}$LibDir/$SubDir/`basename %{buildroot}$LibDir/libthread_db.so.*` install -m755 rt/librt.so %{buildroot}$LibDir/$SubDir/`basename %{buildroot}$LibDir/librt-*.so` ln -sf `basename %{buildroot}$LibDir/librt-*.so` %{buildroot}$LibDir/$SubDir/`basename %{buildroot}$LibDir/librt.so.*` - popd + cd - + } # Install arch-specific optimized libraries -case %{_target_cpu} in +%if %isarch %{i586} +case %{target_cpu} in i[3-5]86) InstallGlibc build-i686-linux i686 ;; esac +%endif # NPTL is not usable outside of glibc, so include # the generic one (RH#162634) @@ -1013,98 +1444,88 @@ install -m644 %{SOURCE10} -D %{buildroot}%{_includedir}/bits/libc-lock.h # section but with glibc that is simply not an option mkdir -p %{buildroot}%{_localedir}/ru_RU/LC_MESSAGES -# Remove the files we don't want to distribute -rm -f %{buildroot}%{_libdir}/libNoVersion* -rm -f %{buildroot}%{_slibdir}/libNoVersion* +install -m 644 %{SOURCE11} %{buildroot}%{_sysconfdir}/nsswitch.conf - -# (tpg) workaround for aarch64 ? -%ifarch aarch64 -ls -sf %{_slibdir}/ld-linux-aarch64.so.1 %{buildroot}%{_slibdir32}/ld-linux-aarch64.so.1 -%endif - -install -m 644 mandriva/nsswitch.conf %{buildroot}%{_sysconfdir}/nsswitch.conf - -# This is for ncsd - in glibc 2.2 +# This is for nscd - in glibc 2.2 %if %{with nscd} install -m644 nscd/nscd.conf -D %{buildroot}%{_sysconfdir}/nscd.conf - install -m755 %{SOURCE6} -D %{buildroot}%{_unitdir}/nscd.service - mkdir -p %{buildroot}%{_tmpfilesdir} - install -m 644 %{SOURCE4} %{buildroot}%{_tmpfilesdir} - install -m755 %{SOURCE7} -D %{buildroot}%{_unitdir}/nscd.socket - install -m755 -d %{buildroot}/var/db/nscd + install -m755 -d %{buildroot}%{_sysconfdir}/sysconfig + touch %{buildroot}%{_sysconfdir}/sysconfig/nscd + install -m755 -d %{buildroot}%{_sysconfdir}/netgroup + mkdir -p %{buildroot}%{_unitdir} + install -m 644 nscd/nscd.service nscd/nscd.socket %{buildroot}%{_unitdir} + install -m644 nscd/nscd.tmpfiles -D %{buildroot}%{_tmpfilesdir}/nscd.conf + install -m755 -d %{buildroot}%{_var}/db/nscd + touch %{buildroot}%{_var}/db/nscd/{passwd,group,hosts,services} + install -m755 -d %{buildroot}/run/nscd + touch %{buildroot}/run/nscd/{nscd.pid,socket,passwd,group,hosts,services} + install -d %{buildroot}%{_presetdir} +cat > %{buildroot}%{_presetdir}/86-nscd.preset << EOF +enable nscd.socket +enable nscd.service +EOF %endif -# Useless and takes place -rm -rf %{buildroot}/%{_datadir}/zoneinfo/{posix,right} - # Include ld.so.conf +%if %isarch mips mipsel +# needed to get a ldd which understands o32, n32, 64 +install -m755 build-%{_target_cpu}-linux/elf/ldd %{buildroot}%{_bindir}/ldd +%endif + +# ldconfig cache +mkdir -p %{buildroot}%{_var}/cache/ldconfig +truncate -s 0 %{buildroot}%{_var}/cache/ldconfig/aux-cache +# Note: This has to happen before creating /etc/ld.so.conf. +# ldconfig is statically linked, so we can use the new version. +%{buildroot}/sbin/ldconfig -N -r %{buildroot} + echo "include /etc/ld.so.conf.d/*.conf" > %{buildroot}%{_sysconfdir}/ld.so.conf chmod 644 %{buildroot}%{_sysconfdir}/ld.so.conf mkdir -p %{buildroot}%{_sysconfdir}/ld.so.conf.d -# ldconfig cache -mkdir -p %{buildroot}%{_var}/cache/ldconfig -touch %{buildroot}%{_var}/cache/ldconfig/aux-cache - -# automatic ldconfig cache update on rpm installs/removals -# (see http://wiki.mandriva.com/en/Rpm_filetriggers) -install -d %{buildroot}%{_var}/lib/rpm/filetriggers -cat > %{buildroot}%{_var}/lib/rpm/filetriggers/ldconfig.filter << EOF -^.((/lib|/usr/lib)(64)?/[^/]*\.so\.|/etc/ld.so.conf.d/[^/]*\.conf) -EOF -cat > %{buildroot}%{_var}/lib/rpm/filetriggers/ldconfig.script << EOF -#!/bin/sh -ldconfig -X -EOF -chmod 755 %{buildroot}%{_var}/lib/rpm/filetriggers/ldconfig.script - # gconv-modules.cache touch %{buildroot}%{_libdir}/gconv/gconv-modules.cache chmod 644 %{buildroot}%{_libdir}/gconv/gconv-modules.cache -%if %{build_multiarch} +%if %{build_biarch} touch %{buildroot}%{_libdir32}/gconv/gconv-modules.cache chmod 644 %{buildroot}%{_libdir32}/gconv/gconv-modules.cache %endif touch %{buildroot}%{_sysconfdir}/ld.so.cache -# Strip debugging info from all static libraries -pushd %{buildroot}%{_libdir} - for i in *.a; do - if [ -f "$i" ]; then - case "$i" in -%ifarch x86_64 -# libm.a is a gnu ld script for glibc 2.28 -%if "%{version}" == "2.29" - libm.a) ;; -%endif -%endif - *_p.a) ;; - *) strip -g -R .comment -R .GCC.command.line $i;; - esac - fi - done -popd +# Are we cross-compiling? +Strip="strip" +if [ "%{_target_cpu}" != "%{target_cpu}" ]; then + Strip="%{cross_program_prefix}$Strip" +fi -# rquota.x and rquota.h are now provided by quota -rm -f %{buildroot}%{_includedir}/rpcsvc/rquota.[hx] +# Strip debugging info from all static libraries +cd %{buildroot}%{_slibdir} +for i in *.a; do + if [ -f "$i" ]; then + case "$i" in + *_p.a) ;; + *) $Strip -g -R .comment -R .GCC.command.line $i ;; + esac + fi +done +cd - %if %{with i18ndata} install -m644 localedata/SUPPORTED %{buildroot}%{_datadir}/i18n/ %endif -rm -rf %{buildroot}%{_includedir}/netatalk/ +rm -r %{buildroot}%{_includedir}/netatalk/ # /etc/localtime - we're proud of our timezone #Well we(mdk) may put Paris %if %{with timezone} - rm -f %{buildroot}%{_sysconfdir}/localtime + rm %{buildroot}%{_sysconfdir}/localtime cp -f %{buildroot}%{_datadir}/zoneinfo/CET %{buildroot}%{_sysconfdir}/localtime %endif # Documentation install -m 755 -d %{buildroot}%{_docdir}/glibc - pushd build-%{_target_cpu}-linux + cd build-%{target_cpu}-linux %if %{with doc} make html cp -fpar manual/libc %{buildroot}%{_docdir}/glibc/html @@ -1113,53 +1534,45 @@ install -m 755 -d %{buildroot}%{_docdir}/glibc make pdf install -m644 -D manual/libc.pdf %{buildroot}%{_docdir}/glibc/libc.pdf %endif - popd -install -m 644 COPYING COPYING.LIB README NEWS INSTALL hesiod/README.hesiod \ - ChangeLog* crypt/README.ufc-crypt nis/nss posix/gai.conf \ + cd - +install -m 644 COPYING COPYING.LIB README NEWS INSTALL \ + hesiod/README.hesiod \ + ChangeLog nis/nss posix/gai.conf \ %{buildroot}%{_docdir}/glibc -xz -0 --text %{buildroot}%{_docdir}/glibc/ChangeLog* +xz -0 --text -T0 %{buildroot}%{_docdir}/glibc/ChangeLog install -m 644 timezone/README %{buildroot}%{_docdir}/glibc/README.timezone # Localization %find_lang libc # Remove unpackaged files -rm -f %{buildroot}%{_infodir}/dir.old* -rm -rf %{buildroot}%{_includedir}/asm-*/mach-*/ -rm -f %{buildroot}%{_localedir}/locale-archive* +rm -f %{buildroot}%{_bindir}/rpcgen %{buildroot}%{_mandir}/man1/rpcgen.1* # XXX: verify #find %{buildroot}%{_localedir} -type f -name LC_\* -o -name SYS_LC_\* |xargs rm -f -%if !%{with nscd} - rm -f %{buildroot}%{_sbindir}/nscd -%endif - -rm -f %{buildroot}%{_infodir}/dir - -# Avoid conflicts with tirpc -rm -f %{buildroot}%{_mandir}/man1/rpcgen.1* - %if %{without utils} - rm -f %{buildroot}%{_bindir}/memusage - rm -f %{buildroot}%{_bindir}/memusagestat - rm -f %{buildroot}%{_bindir}/mtrace - rm -f %{buildroot}%{_bindir}/pcprofiledump - rm -f %{buildroot}%{_bindir}/xtrace - rm -f %{buildroot}%{_slibdir}/libmemusage.so - rm -f %{buildroot}%{_slibdir}/libpcprofile.so - %if %{build_multiarch} - rm -f %{buildroot}%{_slibdir32}/libmemusage.so - rm -f %{buildroot}%{_slibdir32}/libpcprofile.so + rm -f %{buildroot}%{_bindir}/memusage + rm -f %{buildroot}%{_bindir}/memusagestat + rm -f %{buildroot}%{_bindir}/mtrace + rm -f %{buildroot}%{_bindir}/pcprofiledump + rm -f %{buildroot}%{_bindir}/xtrace + rm -f %{buildroot}%{_slibdir}/libmemusage.so + rm -f %{buildroot}%{_slibdir}/libpcprofile.so + %if %{build_biarch} + rm -f %{buildroot}%{_slibdir32}/libmemusage.so + rm -f %{buildroot}%{_slibdir32}/libpcprofile.so + %endif + %if %isarch %{mips} %{mipsel} + rm -f %{buildroot}%{_slibdirn32}/libmemusage.so + rm -f %{buildroot}%{_slibdirn32}/libpcprofile.so %endif %endif %if !%{with timezone} - rm -f %{buildroot}%{_sysconfdir}/localtime - rm -f %{buildroot}%{_sbindir}/zdump - rm -f %{buildroot}%{_sbindir}/zic - rm -f %{buildroot}%{_mandir}/man1/zdump.1* - rm -rf %{buildroot}%{_datadir}/zoneinfo + rm -f %{buildroot}%{_sbindir}/zdump + rm -f %{buildroot}%{_sbindir}/zic + rm -f %{buildroot}%{_mandir}/man1/zdump.1* %endif %if !%{with i18ndata} @@ -1167,32 +1580,94 @@ rm -f %{buildroot}%{_mandir}/man1/rpcgen.1* %endif %if %{with locales} -export PATH=%{buildroot}%{_bindir}:%{buildroot}%{_sbindir}:$PATH -#export LD_LIBRARY_PATH=%{buildroot}/%{_lib}:%{buildroot}%{_libdir}:$LD_LIBRARY_PATH +# Build locales... +%global glibcver %(rpm -q --qf "%%{VERSION}" glibc) export I18NPATH=%{buildroot}%{_datadir}/i18n -# Needed for/used by locale-archive -mkdir -p %{buildroot}%{_prefix}/lib/locale -touch %{buildroot}%{_prefix}/lib/locale/locale-archive - -# Locale related tools -install -c -m 755 %{SOURCE1001} %{SOURCE1002} %{buildroot}%{_bindir}/ - # make default charset pseudo-locales # those will be symlinked (for LC_CTYPE, LC_COLLATE mainly) from # a lot of other locales, thus saving space for DEF_CHARSET in UTF-8 ISO-8859-1 ISO-8859-2 ISO-8859-3 ISO-8859-4 \ - ISO-8859-5 ISO-8859-7 ISO-8859-9 \ - ISO-8859-13 ISO-8859-14 ISO-8859-15 KOI8-R KOI8-U CP1251 + ISO-8859-5 ISO-8859-7 ISO-8859-9 \ + ISO-8859-13 ISO-8859-14 ISO-8859-15 KOI8-R KOI8-U CP1251 do # don't use en_DK because of LC_MONETARY - localedef -c -f $DEF_CHARSET -i en_US %{buildroot}%{_prefix}/lib/locale/$DEF_CHARSET || : + %{buildroot}%{_bindir}/localedef -c -f $DEF_CHARSET -i en_US %{buildroot}%{_datadir}/locale/$DEF_CHARSET done -# TODO: REMOVE?^^^ +# Build regular locales +LANGS="$(sed '1,/^SUPPORTED-LOCALES=/d;s,\\$,,;s,\n,,' %{buildroot}%{_datadir}/i18n/SUPPORTED)" +for l in $LANGS; do + LNG=$(echo $l |cut -d/ -f1) + CS=$(echo $l |cut -d/ -f2) + %{buildroot}%{_bindir}/localedef -i "$(echo $LNG |sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/')" -c -f $CS %{buildroot}%{_datadir}/locale/$LNG +done + +# Locale related tools +install -c -m 755 %{SOURCE1001} %{SOURCE1002} %{buildroot}%{_bindir}/ +# And configs +install -c -m 644 %{SOURCE1003} -D %{buildroot}%{_sysconfdir}/sysconfig/locales + +# Hardlink identical locales +%{_sbindir}/hardlink -vvc %{buildroot}%{_datadir}/locale + +# Symlink identical files +# TODO + +# Needed for/used by locale-archive +mkdir -p %{buildroot}%{_prefix}/lib/locale +touch %{buildroot}%{_prefix}/lib/locale/locale-archive +%endif + +# Remove stuff we get from libxcrypt +#rm -f %{buildroot}%{_prefix}/*/libcrypt.a %{buildroot}%{_includedir}/crypt.h %{buildroot}/*/libcrypt* %{buildroot}%{_prefix}/*/libcrypt.a +# remove broken symlink +#rm -f %{buildroot}%{_prefix}/lib/libcrypt.so + +%ifarch %{aarch64} +# Compat symlink -- some versions of ld hardcoded /lib/ld-linux-aarch64.so.1 +# as dynamic loader +ln -s %{_slibdir}/ld-linux-aarch64.so.1 %{buildroot}/lib/ld-linux-aarch64.so.1 +%endif + +%ifarch riscv64 +# RISC-V ABI wants to install everything in /lib64/lp64d or /usr/lib64/lp64d. +# Make these be symlinks to /lib64 or /usr/lib64 respectively. See: +# https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/DRHT5YTPK4WWVGL3GIN5BF2IKX2ODHZ3/ +for d in %{buildroot}%{_libdir} %{buildroot}/%{_lib}; do + mkdir -p $d + (cd $d && rm -f lp64d; ln -sf . lp64d) +done +%endif + +%ifarch %{x86_64} +# Needed for bootstrapping x32 compilers +[ -e %{buildroot}%{_includedir}/gnu/stubs-x32.h ] || cp %{buildroot}%{_includedir}/gnu/stubs-64.h %{buildroot}%{_includedir}/gnu/stubs-x32.h %endif # This will make the '-g' argument to be passed to eu-strip for these libraries, so that # some info is kept that's required to make valgrind work without depending on glibc-debug # package to be installed. -export EXCLUDE_FROM_FULL_STRIP="ld-%{version}.so libpthread libc-%{version}.so libm-%{version}.so" +export EXCLUDE_FROM_FULL_STRIP="ld-%{fullver}.so libpthread libc-%{fullver}.so libm-%{fullver}.so" + +unset LD_LIBRARY_PATH + +%if %{with locales} +%files -n locales +%{_bindir}/locale_install.sh +%{_bindir}/locale_uninstall.sh +%config(noreplace) %{_sysconfdir}/sysconfig/locales +%dir %{_datadir}/locale +%dir %{_prefix}/lib/locale +%ghost %{_prefix}/lib/locale/locale-archive +%{_datadir}/locale/ISO* +%{_datadir}/locale/CP* +%{_datadir}/locale/UTF* +%{_datadir}/locale/KOI* + +%post -n locales +%{_bindir}/locale_install.sh "ENCODINGS" + +%preun -n locales +%{_bindir}/locale_uninstall.sh "ENCODINGS" +%endif diff --git a/locale-pkg b/locale-pkg deleted file mode 100644 index d425a16..0000000 --- a/locale-pkg +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -LANGNAME="$1" -shift -LOCALE="$1" -if [ "$#" -gt 1 ]; then - shift -fi - -cat < %{EVRD} -EOF - -while echo "$1" |grep -q '^r:'; do - L="`echo $1 |cut -d: -f2-`" - echo "Obsoletes: locales-$L < %{EVRD}" - echo "Provides: locales-$L = %{EVRD}" - shift -done - -cat < /dev/null + fi done # make the installed locale known to rpm (so translations in that # language are installed), and the menu system if [ "$RPM_INSTALL_LANG" != "all" ]; then - RPM_INSTALL_LANG=`echo $i:$RPM_INSTALL_LANG |tr ':' '\n' |sort |tr '\n' ':' |sed -e 's,:$,,'` + RPM_INSTALL_LANG="$(echo "$i":$RPM_INSTALL_LANG |tr ':' '\n' |sort |tr '\n' ':' |sed -e 's,:$,,')" fi done if [ "$OLD_RPM_INSTALL_LANG" != "$RPM_INSTALL_LANG" ]; then # update /etc/rpm/macros file if [ -w /etc/rpm/macros ]; then - sed -i -e "s/^%_install_langs .*/%_install_langs $RPM_INSTALL_LANGS/" /etc/rpm/macros + sed -i -e "s/^%_install_langs .*/%_install_langs $RPM_INSTALL_LANG/" /etc/rpm/macros fi fi diff --git a/locale_uninstall.sh b/locale_uninstall.sh index b520cb7..2309df5 100644 --- a/locale_uninstall.sh +++ b/locale_uninstall.sh @@ -3,40 +3,74 @@ # this script is to be called when a locale is removed from the sistem; # so translations in the language(s) of the locale are no longer installed +if [ "$1" = 'ENCODINGS' ]; then + # remove encoding files used by locales + ENCODINGS="CP1251 ISO-8859-1 ISO-8859-13 ISO-8859-14 ISO-8859-15 \ + ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-7 \ + ISO-8859-9 KOI8-R KOI8-U UTF-8" + for enc in $ENCODINGS; do + if [ -d "/etc/locale/$enc" ]; then + for i in LC_ADDRESS LC_COLLATE LC_CTYPE \ + LC_IDENTIFICATION LC_MEASUREMENT LC_MONETARY \ + LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE \ + LC_TIME LC_MESSAGES/SYS_LC_MESSAGES + do + rm -f "/etc/locale/$enc/$i" + done + rmdir "/etc/locale/$enc/LC_MESSAGES" > /dev/null 2>&1 + rmdir "/etc/locale/$enc" > /dev/null 2>&1 + fi + done + exit 0 +fi + # the list of languages that rpm installs their translations if [ -r /etc/rpm/macros ]; then - RPM_INSTALL_LANG="`grep '^%_install_langs' /etc/rpm/macros | cut -d' ' -f2-`" + RPM_INSTALL_LANG="$(grep '^%_install_langs' /etc/rpm/macros | cut -d' ' -f2-)" fi [ -z "$RPM_INSTALL_LANG" ] && RPM_INSTALL_LANG=C OLD_RPM_INSTALL_LANG="$RPM_INSTALL_LANG" -INSTALLED_LOCALES=`localedef --list` for i in "$@"; do - # Delete corresponding locale definitions from the locale-archive file - for l in $INSTALLED_LOCALES; do - case "$l" in - $i | $i.* | $i@* ) - localedef --delete-from-archive $l - ;; - *) ;; - esac + langs="$i" + for j in /usr/share/locale/$i.*; do + [ -d "$j" ] || continue + lng="$(basename $j)" + # sanity check + echo "$lng" | grep -q "$i" || continue + langs="$langs $lng" + done + for k in $langs; do + # remove the LC_* of the all system locales from /etc/locale, + # copied by locale_install.sh + if [ -d "/etc/locale/$k" ]; then + for j in LC_ADDRESS LC_IDENTIFICATION LC_MONETARY \ + LC_PAPER LC_COLLATE LC_MEASUREMENT LC_NAME \ + LC_TELEPHONE LC_CTYPE LC_NUMERIC LC_TIME \ + LC_MESSAGES/SYS_LC_MESSAGES + do + rm -f "/etc/locale/$k/$j" + done + rmdir "/etc/locale/$k/LC_MESSAGES" > /dev/null 2>&1 + rmdir "/etc/locale/$k" > /dev/null 2>&1 + fi done # remove the locale from the list known to rpm (so translations in that # language are no more installed), and from the menu system if [ "$RPM_INSTALL_LANG" != "all" ]; then - RPM_INSTALL_LANG=`echo $RPM_INSTALL_LANG |sed -e 's,$i,,' |tr ':' '\n' |grep -v '^$' |sort |tr '\n' ':' |sed -e 's,:$,,'` + RPM_INSTALL_LANG="$(echo $RPM_INSTALL_LANG |sed -e 's,$i,,' |tr ':' '\n' |grep -v '^$' |sort |tr '\n' ':' |sed -e 's,:$,,')" fi - langs="`localedef --list-archive | grep \"$i\"`" + langs="$(localedef --list-archive | grep \"$i\")" for lng in $langs; do - localedef --delete-from-archive $lng + localedef --delete-from-archive "$lng" done done if [ "$OLD_RPM_INSTALL_LANG" != "$RPM_INSTALL_LANG" ]; then # update /etc/rpm/macros file if [ -w /etc/rpm/macros ]; then - sed -i -e "s/^%_install_langs .*/%_install_langs ${RPM_INSTALL_LANG}/" /etc/rpm/macros + sed -i -e "s/^%_install_langs .*/%_install_langs $RPM_INSTALL_LANG/" /etc/rpm/macros fi fi diff --git a/localepkg.sh b/localepkg.sh new file mode 100644 index 0000000..db51ed9 --- /dev/null +++ b/localepkg.sh @@ -0,0 +1,58 @@ +#!/bin/sh +langname="$1" +shift +locale="$1" +shift + +cat <