about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-04-03 12:20:51 -0400
committerRich Felker <dalias@aerifal.cx>2011-04-03 12:20:51 -0400
commitc9b2d8016fca3b0545433e9d58a04c038b6fc921 (patch)
treeb95287cafebf3496a773131f277f60f506cb1519
parent6e9ed66d0db17ac9ad2342fc107e8c4528fce0ba (diff)
downloadmusl-c9b2d8016fca3b0545433e9d58a04c038b6fc921.tar.gz
musl-c9b2d8016fca3b0545433e9d58a04c038b6fc921.tar.xz
musl-c9b2d8016fca3b0545433e9d58a04c038b6fc921.zip
don't trust siginfo in rsyscall handler
for some inexplicable reason, linux allows the sender of realtime
signals to spoof its identity. permission checks for sending signals
should limit the impact to same-user processes, but just to be safe,
we avoid trusting the siginfo structure and instead simply examine the
program state to see if we're in the middle of a legitimate rsyscall.
-rw-r--r--src/thread/pthread_create.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index d058a1ad..9df4f712 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -80,8 +80,7 @@ static void rsyscall_handler(int sig, siginfo_t *si, void *ctx)
 {
 	struct pthread *self = __pthread_self();
 
-	if (si->si_code > 0 || si->si_pid != self->pid ||
-		rs.cnt == libc.threads_minus_1) return;
+	if (!rs.hold || rs.cnt == libc.threads_minus_1) return;
 
 	/* Threads which have already decremented themselves from the
 	 * thread count must not increment rs.cnt or otherwise act. */
@@ -118,9 +117,9 @@ static int rsyscall(int nr, long a, long b, long c, long d, long e, long f)
 	rs.arg[0] = a; rs.arg[1] = b;
 	rs.arg[2] = c; rs.arg[3] = d;
 	rs.arg[4] = d; rs.arg[5] = f;
-	rs.hold = 1;
 	rs.err = 0;
 	rs.cnt = 0;
+	rs.hold = 1;
 
 	/* Dispatch signals until all threads respond */
 	for (i=libc.threads_minus_1; i; i--)