summaryrefslogtreecommitdiff
path: root/system/musl
diff options
context:
space:
mode:
Diffstat (limited to 'system/musl')
-rw-r--r--system/musl/APKBUILD18
-rw-r--r--system/musl/CVE-2020-28928.patch112
-rw-r--r--system/musl/amalgamation.patch49
-rw-r--r--system/musl/handle-aux-at_base.patch4
-rw-r--r--system/musl/threads_minus_1.patch267
5 files changed, 39 insertions, 411 deletions
diff --git a/system/musl/APKBUILD b/system/musl/APKBUILD
index 735541e51..56fadc5e2 100644
--- a/system/musl/APKBUILD
+++ b/system/musl/APKBUILD
@@ -1,7 +1,8 @@
# Maintainer: A. Wilcox <awilfox@adelielinux.org>
pkgname=musl
-pkgver=1.2.0
-pkgrel=2
+pkgver=1.2.3_pre1
+pkgrel=0
+pkgdate=20211129
pkgdesc="System library (libc) implementation"
url="https://www.musl-libc.org/"
arch="all"
@@ -21,18 +22,17 @@ nolibc) ;;
triggers="$pkgname-utils.trigger=/etc/ld.so.conf.d"
;;
esac
-source="https://musl.libc.org/releases/$pkgname-$pkgver.tar.gz
+source="https://distfiles.adelielinux.org/source/$pkgname-$pkgver-$pkgdate.tar.xz
amalgamation.patch
3001-make-real-lastlog-h.patch
handle-aux-at_base.patch
fgetspent_r.patch
- threads_minus_1.patch
- CVE-2020-28928.patch
ldconfig
getent.c
iconv.c
"
+builddir="$srcdir/$pkgname-$pkgver-$pkgdate"
# secfixes:
# 1.1.15-r4:
@@ -120,13 +120,11 @@ utils() {
install -D -m755 "$srcdir"/ldconfig "$subpkgdir"/sbin
}
-sha512sums="58bd88189a6002356728cea1c6f6605a893fe54f7687595879add4eab283c8692c3b031eb9457ad00d1edd082cfe62fcc0eb5eb1d3bf4f1d749c0efa2a95fec1 musl-1.2.0.tar.gz
-f01ab92b9d385c15369c0bb7d95e1bc06a009c8851e363517d0ba1bae3fc2647af69fc2f363b5d962d376c5d9a1994b5728fd88ccbfff5f0d3d0970a02df1512 amalgamation.patch
+sha512sums="b8a9790a79571854a0a95cb4fcc2dcc9f705879fafdb9c3ec7088dd72649b60449a8370df9337a734af7198a39337684a7662d2ce411d284ca435ad597b900fc musl-1.2.3_pre1-20211129.tar.xz
+f7b05d8c5f804ba3ad6998b3de5fa4d9dfceac4aca63dd67298c2d5f27cdd28a91eba74f6e428c258323da80635dd333bae2c47ff918894797cba92bd5700909 amalgamation.patch
88ae443dbb8e0a4368235bdc3a1c5c7b718495afa75e06deb8e01becc76cb1f0d6964589e2204fc749c9c1b3190b8b9ac1ae2c0099cab8e2ce3ec877103d4332 3001-make-real-lastlog-h.patch
-6a7ff16d95b5d1be77e0a0fbb245491817db192176496a57b22ab037637d97a185ea0b0d19da687da66c2a2f5578e4343d230f399d49fe377d8f008410974238 handle-aux-at_base.patch
+1f4e9aea5a546015c75f77aa0dec10d56fc14831ccc15cf71ff27fc15ac5230ffeadb382ebe1c87c1ea07a462620e16ed01cd36252d997d1a9c2af11cb5c9ff3 handle-aux-at_base.patch
ded41235148930f8cf781538f7d63ecb0c65ea4e8ce792565f3649ee2523592a76b2a166785f0b145fc79f5852fd1fb1729a7a09110b3b8f85cba3912e790807 fgetspent_r.patch
-68830961e297d9a499f3b609be84848ad5d3326a1af56e9e54a40ecd972c48da11532c51da572d45e0df3574d63191e7ae0d3a1b84a029365f8d00691de96952 threads_minus_1.patch
-343ac5e5365cf98a5d5b7bc192c671733fdba27f06b83484f1ac7647154228745415f62dd676029de538460f8b35e0a70ca453a0f8b73226ed1c420099b1cf90 CVE-2020-28928.patch
cb71d29a87f334c75ecbc911becde7be825ab30d8f39fa6d64cb53812a7c9abaf91d9804c72540e5be3ddd3c84cfe7fd9632274309005cb8bcdf9a9b09b4b923 ldconfig
378d70e65bcc65bb4e1415354cecfa54b0c1146dfb24474b69e418cdbf7ad730472cd09f6f103e1c99ba6c324c9560bccdf287f5889bbc3ef0bdf0e08da47413 getent.c
9d42d66fb1facce2b85dad919be5be819ee290bd26ca2db00982b2f8e055a0196290a008711cbe2b18ec9eee8d2270e3b3a4692c5a1b807013baa5c2b70a2bbf iconv.c"
diff --git a/system/musl/CVE-2020-28928.patch b/system/musl/CVE-2020-28928.patch
deleted file mode 100644
index cc668e149..000000000
--- a/system/musl/CVE-2020-28928.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 3ab2a4e02682df1382955071919d8aa3c3ec40d4 Mon Sep 17 00:00:00 2001
-From: Rich Felker <dalias@aerifal.cx>
-Date: Thu, 19 Nov 2020 17:12:43 -0500
-Subject: [PATCH] rewrite wcsnrtombs to fix buffer overflow and other bugs
-
-the original wcsnrtombs implementation, which has been largely
-untouched since 0.5.0, attempted to build input-length-limiting
-conversion on top of wcsrtombs, which only limits output length. as
-best I recall, this choice was made out of a mix of disdain over
-having yet another variant function to implement (added in POSIX 2008;
-not standard C) and preference not to switch things around and
-implement the wcsrtombs in terms of the more general new function,
-probably over namespace issues. the strategy employed was to impose
-output limits that would ensure the input limit wasn't exceeded, then
-finish up the tail character-at-a-time. unfortunately, none of that
-worked correctly.
-
-first, the logic in the wcsrtombs loop was wrong in that it could
-easily get stuck making no forward progress, by imposing an output
-limit too small to convert even one character.
-
-the character-at-a-time loop that followed was even worse. it made no
-effort to ensure that the converted multibyte character would fit in
-the remaining output space, only that there was a nonzero amount of
-output space remaining. it also employed an incorrect interpretation
-of wcrtomb's interface contract for converting the null character,
-thereby failing to act on end of input, and remaining space accounting
-was subject to unsigned wrap-around. together these errors allow
-unbounded overflow of the destination buffer, controlled by input
-length limit and input wchar_t string contents.
-
-given the extent to which this function was broken, it's plausible
-that most applications that would have been rendered exploitable were
-sufficiently broken not to be usable in the first place. however, it's
-also plausible that common (especially ASCII-only) inputs succeeded in
-the wcsrtombs loop, which mostly worked, while leaving the wildly
-erroneous code in the second loop exposed to particular non-ASCII
-inputs.
-
-CVE-2020-28928 has been assigned for this issue.
----
- src/multibyte/wcsnrtombs.c | 46 ++++++++++++++++----------------------
- 1 file changed, 19 insertions(+), 27 deletions(-)
-
-diff --git a/src/multibyte/wcsnrtombs.c b/src/multibyte/wcsnrtombs.c
-index 676932b5..95e25e70 100644
---- a/src/multibyte/wcsnrtombs.c
-+++ b/src/multibyte/wcsnrtombs.c
-@@ -1,41 +1,33 @@
- #include <wchar.h>
-+#include <limits.h>
-+#include <string.h>
-
- size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
- {
-- size_t l, cnt=0, n2;
-- char *s, buf[256];
- const wchar_t *ws = *wcs;
-- const wchar_t *tmp_ws;
--
-- if (!dst) s = buf, n = sizeof buf;
-- else s = dst;
--
-- while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
-- if (n2>=n) n2=n;
-- tmp_ws = ws;
-- l = wcsrtombs(s, &ws, n2, 0);
-- if (!(l+1)) {
-- cnt = l;
-- n = 0;
-+ size_t cnt = 0;
-+ if (!dst) n=0;
-+ while (ws && wn) {
-+ char tmp[MB_LEN_MAX];
-+ size_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
-+ if (l==-1) {
-+ cnt = -1;
- break;
- }
-- if (s != buf) {
-- s += l;
-+ if (dst) {
-+ if (n<MB_LEN_MAX) {
-+ if (l>n) break;
-+ memcpy(dst, tmp, l);
-+ }
-+ dst += l;
- n -= l;
- }
-- wn = ws ? wn - (ws - tmp_ws) : 0;
-- cnt += l;
-- }
-- if (ws) while (n && wn) {
-- l = wcrtomb(s, *ws, 0);
-- if ((l+1)<=1) {
-- if (!l) ws = 0;
-- else cnt = l;
-+ if (!*ws) {
-+ ws = 0;
- break;
- }
-- ws++; wn--;
-- /* safe - this loop runs fewer than sizeof(buf) times */
-- s+=l; n-=l;
-+ ws++;
-+ wn--;
- cnt += l;
- }
- if (dst) *wcs = ws;
---
-2.25.4
-
diff --git a/system/musl/amalgamation.patch b/system/musl/amalgamation.patch
index 5918c3be6..5e273ce7f 100644
--- a/system/musl/amalgamation.patch
+++ b/system/musl/amalgamation.patch
@@ -8,14 +8,14 @@ index e9ca94cb..b39b12ee 100644
#include <time.h>
#include <errno.h>
diff --git a/include/stdlib.h b/include/stdlib.h
-index 194c2033..5734b1f0 100644
+index b507ca33..5e14b07c 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
-@@ -39,14 +39,18 @@ void *malloc (size_t);
+@@ -41,14 +41,18 @@ void *malloc (size_t);
void *calloc (size_t, size_t);
void *realloc (void *, size_t);
void free (void *);
-+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
++#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
void *aligned_alloc(size_t, size_t);
+#endif
@@ -23,14 +23,14 @@ index 194c2033..5734b1f0 100644
int atexit (void (*) (void));
_Noreturn void exit (int);
_Noreturn void _Exit (int);
-+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
++#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
int at_quick_exit (void (*) (void));
_Noreturn void quick_exit (int);
+#endif
char *getenv (const char *);
-@@ -100,7 +104,6 @@ int posix_memalign (void **, size_t, size_t);
+@@ -102,7 +106,6 @@ int posix_memalign (void **, size_t, size_t);
int setenv (const char *, const char *, int);
int unsetenv (const char *);
int mkstemp (char *);
@@ -38,7 +38,7 @@ index 194c2033..5734b1f0 100644
char *mkdtemp (char *);
int getsubopt (char **, char *const *, char **);
int rand_r (unsigned *);
-@@ -138,6 +141,7 @@ void lcong48 (unsigned short [7]);
+@@ -140,6 +143,7 @@ void lcong48 (unsigned short [7]);
#include <alloca.h>
char *mktemp (char *);
int mkstemps (char *, int);
@@ -59,10 +59,10 @@ index cdc67ef6..fd773896 100644
struct itimerval {
struct timeval it_interval;
diff --git a/include/time.h b/include/time.h
-index 5494df18..2412fe22 100644
+index 3d948372..deb4a450 100644
--- a/include/time.h
+++ b/include/time.h
-@@ -58,11 +58,14 @@ struct tm *gmtime (const time_t *);
+@@ -60,11 +60,14 @@ struct tm *gmtime (const time_t *);
struct tm *localtime (const time_t *);
char *asctime (const struct tm *);
char *ctime (const time_t *);
@@ -79,7 +79,7 @@ index 5494df18..2412fe22 100644
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
-@@ -137,7 +140,10 @@ __REDIR(mktime, __mktime64);
+@@ -139,7 +142,10 @@ __REDIR(mktime, __mktime64);
__REDIR(gmtime, __gmtime64);
__REDIR(localtime, __localtime64);
__REDIR(ctime, __ctime64);
@@ -91,10 +91,10 @@ index 5494df18..2412fe22 100644
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|| defined(_BSD_SOURCE)
diff --git a/include/unistd.h b/include/unistd.h
-index 7bcbff94..6fd67160 100644
+index ee2dbe8a..ed75e578 100644
--- a/include/unistd.h
+++ b/include/unistd.h
-@@ -33,16 +33,23 @@ extern "C" {
+@@ -35,16 +35,23 @@ extern "C" {
#include <bits/alltypes.h>
int pipe(int [2]);
@@ -121,7 +121,7 @@ index 7bcbff94..6fd67160 100644
ssize_t read(int, void *, size_t);
ssize_t write(int, const void *, size_t);
ssize_t pread(int, void *, size_t, off_t);
-@@ -202,8 +209,6 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
+@@ -206,8 +213,6 @@ pid_t gettid(void);
#define off64_t off_t
#endif
@@ -130,7 +130,7 @@ index 7bcbff94..6fd67160 100644
#define _XOPEN_VERSION 700
#define _XOPEN_UNIX 1
#define _XOPEN_ENH_I18N 1
-@@ -276,6 +281,7 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
+@@ -280,6 +285,7 @@ pid_t gettid(void);
#define _PC_ALLOC_SIZE_MIN 18
#define _PC_SYMLINK_MAX 19
#define _PC_2_SYMLINKS 20
@@ -138,7 +138,7 @@ index 7bcbff94..6fd67160 100644
#define _SC_ARG_MAX 0
#define _SC_CHILD_MAX 1
-@@ -419,6 +425,7 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
+@@ -423,6 +429,7 @@ pid_t gettid(void);
#define _SC_XOPEN_STREAMS 246
#define _SC_THREAD_ROBUST_PRIO_INHERIT 247
#define _SC_THREAD_ROBUST_PRIO_PROTECT 248
@@ -146,7 +146,7 @@ index 7bcbff94..6fd67160 100644
#define _CS_PATH 0
#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
-@@ -461,6 +468,8 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
+@@ -465,6 +472,8 @@ pid_t gettid(void);
#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
#define _CS_V6_ENV 1148
#define _CS_V7_ENV 1149
@@ -208,18 +208,27 @@ index 3baaed32..04369596 100644
if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c
-index 2bc7b500..4a601eaf 100644
+index 360c4437..76dbfc37 100644
--- a/src/locale/setlocale.c
+++ b/src/locale/setlocale.c
-@@ -14,6 +14,8 @@ char *setlocale(int cat, const char *name)
+@@ -13,6 +13,8 @@ char *setlocale(int cat, const char *name)
if ((unsigned)cat > LC_ALL) return 0;
+ if (name && (!strncmp(name, "VSX4L", 5))) return 0;
+
- LOCK(lock);
+ LOCK(__locale_lock);
/* For LC_ALL, setlocale is required to return a string which
+diff --git a/src/malloc/posix_memalign.c b/src/malloc/posix_memalign.c
+index ad4d8f47..3318f86a 100644
+--- a/src/malloc/posix_memalign.c
++++ b/src/malloc/posix_memalign.c
+@@ -1,3 +1,4 @@
++#define _BSD_SOURCE
+ #include <stdlib.h>
+ #include <errno.h>
+
diff --git a/src/misc/forkpty.c b/src/misc/forkpty.c
index caf13adb..43494b96 100644
--- a/src/misc/forkpty.c
@@ -331,7 +340,7 @@ index 5af59b80..3f61d278 100644
sigaction(SIGINT, &sa, &oldint);
sigaction(SIGQUIT, &sa, &oldquit);
diff --git a/src/stdio/popen.c b/src/stdio/popen.c
-index 92cb57ee..70c5d6ec 100644
+index 3ec83394..58883b11 100644
--- a/src/stdio/popen.c
+++ b/src/stdio/popen.c
@@ -1,3 +1,4 @@
@@ -387,7 +396,7 @@ index 40ea9c1c..e396da09 100644
/* There is no other implemented value than TIME_UTC; all other values
diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
-index 76bbd4c7..0b4564f9 100644
+index 557503eb..756a7bc4 100644
--- a/src/unistd/faccessat.c
+++ b/src/unistd/faccessat.c
@@ -1,3 +1,4 @@
diff --git a/system/musl/handle-aux-at_base.patch b/system/musl/handle-aux-at_base.patch
index c16463824..697c82bbb 100644
--- a/system/musl/handle-aux-at_base.patch
+++ b/system/musl/handle-aux-at_base.patch
@@ -2,7 +2,7 @@ diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
index b125eb1..616c6a6 100644
--- a/src/env/__init_tls.c
+++ b/src/env/__init_tls.c
-@@ -66,8 +66,10 @@ void *__copy_tls(unsigned char *mem)
+@@ -72,8 +72,10 @@ void *__copy_tls(unsigned char *mem)
}
#if ULONG_MAX == 0xffffffff
@@ -13,7 +13,7 @@ index b125eb1..616c6a6 100644
typedef Elf64_Phdr Phdr;
#endif
-@@ -77,15 +79,23 @@ extern const size_t _DYNAMIC[];
+@@ -82,15 +84,23 @@ extern const size_t _DYNAMIC[];
static void static_init_tls(size_t *aux)
{
unsigned char *p;
diff --git a/system/musl/threads_minus_1.patch b/system/musl/threads_minus_1.patch
deleted file mode 100644
index 05307d97c..000000000
--- a/system/musl/threads_minus_1.patch
+++ /dev/null
@@ -1,267 +0,0 @@
-https://www.openwall.com/lists/musl/2020/05/22/10
-
-From 4d5aa20a94a2d3fae3e69289dc23ecafbd0c16c4 Mon Sep 17 00:00:00 2001
-From: Rich Felker <dalias@aerifal.cx>
-Date: Fri, 22 May 2020 17:35:14 -0400
-Subject: [PATCH 1/4] reorder thread list unlink in pthread_exit after all
- locks
-
-since the backend for LOCK() skips locking if single-threaded, it's
-unsafe to make the process appear single-threaded before the last use
-of lock.
-
-this fixes potential unsynchronized access to a linked list via
-__dl_thread_cleanup.
----
- src/thread/pthread_create.c | 19 +++++++++++--------
- 1 file changed, 11 insertions(+), 8 deletions(-)
-
-diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
-index 5f491092..6a3b0c21 100644
---- a/src/thread/pthread_create.c
-+++ b/src/thread/pthread_create.c
-@@ -90,14 +90,7 @@ _Noreturn void __pthread_exit(void *result)
- exit(0);
- }
-
-- /* At this point we are committed to thread termination. Unlink
-- * the thread from the list. This change will not be visible
-- * until the lock is released, which only happens after SYS_exit
-- * has been called, via the exit futex address pointing at the lock. */
-- libc.threads_minus_1--;
-- self->next->prev = self->prev;
-- self->prev->next = self->next;
-- self->prev = self->next = self;
-+ /* At this point we are committed to thread termination. */
-
- /* Process robust list in userspace to handle non-pshared mutexes
- * and the detached thread case where the robust list head will
-@@ -121,6 +114,16 @@ _Noreturn void __pthread_exit(void *result)
- __do_orphaned_stdio_locks();
- __dl_thread_cleanup();
-
-+ /* Last, unlink thread from the list. This change will not be visible
-+ * until the lock is released, which only happens after SYS_exit
-+ * has been called, via the exit futex address pointing at the lock.
-+ * This needs to happen after any possible calls to LOCK() that might
-+ * skip locking if libc.threads_minus_1 is zero. */
-+ libc.threads_minus_1--;
-+ self->next->prev = self->prev;
-+ self->prev->next = self->next;
-+ self->prev = self->next = self;
-+
- /* This atomic potentially competes with a concurrent pthread_detach
- * call; the loser is responsible for freeing thread resources. */
- int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);
---
-2.21.0
-
-From e01b5939b38aea5ecbe41670643199825874b26c Mon Sep 17 00:00:00 2001
-From: Rich Felker <dalias@aerifal.cx>
-Date: Thu, 21 May 2020 23:32:45 -0400
-Subject: [PATCH 2/4] don't use libc.threads_minus_1 as relaxed atomic for
- skipping locks
-
-after all but the last thread exits, the next thread to observe
-libc.threads_minus_1==0 and conclude that it can skip locking fails to
-synchronize with any changes to memory that were made by the
-last-exiting thread. this can produce data races.
-
-on some archs, at least x86, memory synchronization is unlikely to be
-a problem; however, with the inline locks in malloc, skipping the lock
-also eliminated the compiler barrier, and caused code that needed to
-re-check chunk in-use bits after obtaining the lock to reuse a stale
-value, possibly from before the process became single-threaded. this
-in turn produced corruption of the heap state.
-
-some uses of libc.threads_minus_1 remain, especially for allocation of
-new TLS in the dynamic linker; otherwise, it could be removed
-entirely. it's made non-volatile to reflect that the remaining
-accesses are only made under lock on the thread list.
-
-instead of libc.threads_minus_1, libc.threaded is now used for
-skipping locks. the difference is that libc.threaded is permanently
-true once an additional thread has been created. this will produce
-some performance regression in processes that are mostly
-single-threaded but occasionally creating threads. in the future it
-may be possible to bring back the full lock-skipping, but more care
-needs to be taken to produce a safe design.
----
- src/internal/libc.h | 2 +-
- src/malloc/malloc.c | 2 +-
- src/thread/__lock.c | 2 +-
- 3 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/internal/libc.h b/src/internal/libc.h
-index ac97dc7e..c0614852 100644
---- a/src/internal/libc.h
-+++ b/src/internal/libc.h
-@@ -21,7 +21,7 @@ struct __libc {
- int can_do_threads;
- int threaded;
- int secure;
-- volatile int threads_minus_1;
-+ int threads_minus_1;
- size_t *auxv;
- struct tls_module *tls_head;
- size_t tls_size, tls_align, tls_cnt;
-diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c
-index 96982596..2553a62e 100644
---- a/src/malloc/malloc.c
-+++ b/src/malloc/malloc.c
-@@ -26,7 +26,7 @@ int __malloc_replaced;
-
- static inline void lock(volatile int *lk)
- {
-- if (libc.threads_minus_1)
-+ if (libc.threaded)
- while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
- }
-
-diff --git a/src/thread/__lock.c b/src/thread/__lock.c
-index 45557c88..5b9b144e 100644
---- a/src/thread/__lock.c
-+++ b/src/thread/__lock.c
-@@ -18,7 +18,7 @@
-
- void __lock(volatile int *l)
- {
-- if (!libc.threads_minus_1) return;
-+ if (!libc.threaded) return;
- /* fast path: INT_MIN for the lock, +1 for the congestion */
- int current = a_cas(l, 0, INT_MIN + 1);
- if (!current) return;
---
-2.21.0
-
-From f12888e9eb9eed60cc266b899dcafecb4752964a Mon Sep 17 00:00:00 2001
-From: Rich Felker <dalias@aerifal.cx>
-Date: Fri, 22 May 2020 17:25:38 -0400
-Subject: [PATCH 3/4] cut down size of some libc struct members
-
-these are all flags that can be single-byte values.
----
- src/internal/libc.h | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/internal/libc.h b/src/internal/libc.h
-index c0614852..d47f58e0 100644
---- a/src/internal/libc.h
-+++ b/src/internal/libc.h
-@@ -18,9 +18,9 @@ struct tls_module {
- };
-
- struct __libc {
-- int can_do_threads;
-- int threaded;
-- int secure;
-+ char can_do_threads;
-+ char threaded;
-+ char secure;
- int threads_minus_1;
- size_t *auxv;
- struct tls_module *tls_head;
---
-2.21.0
-
-From 8d81ba8c0bc6fe31136cb15c9c82ef4c24965040 Mon Sep 17 00:00:00 2001
-From: Rich Felker <dalias@aerifal.cx>
-Date: Fri, 22 May 2020 17:45:47 -0400
-Subject: [PATCH 4/4] restore lock-skipping for processes that return to
- single-threaded state
-
-the design used here relies on the barrier provided by the first lock
-operation after the process returns to single-threaded state to
-synchronize with actions by the last thread that exited. by storing
-the intent to change modes in the same object used to detect whether
-locking is needed, it's possible to avoid an extra (possibly costly)
-memory load after the lock is taken.
----
- src/internal/libc.h | 1 +
- src/malloc/malloc.c | 5 ++++-
- src/thread/__lock.c | 4 +++-
- src/thread/pthread_create.c | 8 ++++----
- 4 files changed, 12 insertions(+), 6 deletions(-)
-
-diff --git a/src/internal/libc.h b/src/internal/libc.h
-index d47f58e0..619bba86 100644
---- a/src/internal/libc.h
-+++ b/src/internal/libc.h
-@@ -21,6 +21,7 @@ struct __libc {
- char can_do_threads;
- char threaded;
- char secure;
-+ volatile signed char need_locks;
- int threads_minus_1;
- size_t *auxv;
- struct tls_module *tls_head;
-diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c
-index 2553a62e..a803d4c9 100644
---- a/src/malloc/malloc.c
-+++ b/src/malloc/malloc.c
-@@ -26,8 +26,11 @@ int __malloc_replaced;
-
- static inline void lock(volatile int *lk)
- {
-- if (libc.threaded)
-+ int need_locks = libc.need_locks;
-+ if (need_locks) {
- while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
-+ if (need_locks < 0) libc.need_locks = 0;
-+ }
- }
-
- static inline void unlock(volatile int *lk)
-diff --git a/src/thread/__lock.c b/src/thread/__lock.c
-index 5b9b144e..60eece49 100644
---- a/src/thread/__lock.c
-+++ b/src/thread/__lock.c
-@@ -18,9 +18,11 @@
-
- void __lock(volatile int *l)
- {
-- if (!libc.threaded) return;
-+ int need_locks = libc.need_locks;
-+ if (!need_locks) return;
- /* fast path: INT_MIN for the lock, +1 for the congestion */
- int current = a_cas(l, 0, INT_MIN + 1);
-+ if (need_locks < 0) libc.need_locks = 0;
- if (!current) return;
- /* A first spin loop, for medium congestion. */
- for (unsigned i = 0; i < 10; ++i) {
-diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
-index 6a3b0c21..6bdfb44f 100644
---- a/src/thread/pthread_create.c
-+++ b/src/thread/pthread_create.c
-@@ -118,8 +118,8 @@ _Noreturn void __pthread_exit(void *result)
- * until the lock is released, which only happens after SYS_exit
- * has been called, via the exit futex address pointing at the lock.
- * This needs to happen after any possible calls to LOCK() that might
-- * skip locking if libc.threads_minus_1 is zero. */
-- libc.threads_minus_1--;
-+ * skip locking if process appears single-threaded. */
-+ if (!--libc.threads_minus_1) libc.need_locks = -1;
- self->next->prev = self->prev;
- self->prev->next = self->next;
- self->prev = self->next = self;
-@@ -339,7 +339,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
- ~(1UL<<((SIGCANCEL-1)%(8*sizeof(long))));
-
- __tl_lock();
-- libc.threads_minus_1++;
-+ if (!libc.threads_minus_1++) libc.need_locks = 1;
- ret = __clone((c11 ? start_c11 : start), stack, flags, args, &new->tid, TP_ADJ(new), &__thread_list_lock);
-
- /* All clone failures translate to EAGAIN. If explicit scheduling
-@@ -363,7 +363,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
- new->next->prev = new;
- new->prev->next = new;
- } else {
-- libc.threads_minus_1--;
-+ if (!--libc.threads_minus_1) libc.need_locks = 0;
- }
- __tl_unlock();
- __restore_sigs(&set);
---
-2.21.0
-