summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/musl/patch/0001-avoid-set-id-setrlimit-misbehavior-and-hang-in-vfork.patch49
-rw-r--r--pkg/musl/ver2
2 files changed, 50 insertions, 1 deletions
diff --git a/pkg/musl/patch/0001-avoid-set-id-setrlimit-misbehavior-and-hang-in-vfork.patch b/pkg/musl/patch/0001-avoid-set-id-setrlimit-misbehavior-and-hang-in-vfork.patch
new file mode 100644
index 00000000..f8e80031
--- /dev/null
+++ b/pkg/musl/patch/0001-avoid-set-id-setrlimit-misbehavior-and-hang-in-vfork.patch
@@ -0,0 +1,49 @@
+From 1fce9805c251a187b75bd527cad0b1e1021c296b Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Thu, 17 Sep 2020 15:09:46 -0400
+Subject: [PATCH] avoid set*id/setrlimit misbehavior and hang in vforked/cloned
+ child
+
+taking the deprecated/dropped vfork spec strictly, doing pretty much
+anything but execve in the child is wrong and undefined. however,
+these are commonly needed operations to setup the child state before
+exec, and historical implementations tolerated them.
+
+for single-threaded parents, these operations already worked as
+expected in the vforked child. however, due to the need for __synccall
+to synchronize id/resource limit changes among all threads, calling
+these functions in the vforked child of a multithreaded parent caused
+a misdirected broadcast signaling of all threads in the parent. these
+signals could kill the parent entirely if the synccall signal handler
+had never been installed in the parent, or could be ignored if it had,
+or could signal/kill one or more utterly wrong processes if the parent
+already terminated (due to vfork semantics, only possible via fatal
+signal) and the parent tids were recycled. in any case, the expected
+number of semaphore posts would never happen, so the child would
+permanently hang (with all signals blocked) waiting for them.
+
+to mitigate this, and also make the normal usage case work as
+intended, treat the condition where the caller's actual tid does not
+match the tid in its thread structure as single-threaded, and bypass
+the entire synccall broadcast operation.
+---
+ src/thread/synccall.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/thread/synccall.c b/src/thread/synccall.c
+index 648a6ad4..d58c851f 100644
+--- a/src/thread/synccall.c
++++ b/src/thread/synccall.c
+@@ -63,7 +63,8 @@ void __synccall(void (*func)(void *), void *ctx)
+ sem_init(&target_sem, 0, 0);
+ sem_init(&caller_sem, 0, 0);
+
+- if (!libc.threads_minus_1) goto single_threaded;
++ if (!libc.threads_minus_1 || __syscall(SYS_gettid) != self->tid)
++ goto single_threaded;
+
+ callback = func;
+ context = ctx;
+--
+2.28.0
+
diff --git a/pkg/musl/ver b/pkg/musl/ver
index 97fe035b..608f1b9b 100644
--- a/pkg/musl/ver
+++ b/pkg/musl/ver
@@ -1 +1 @@
-1.2.1 r0
+1.2.1 r1