summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/alpha/lockdflt.c25
-rw-r--r--libexec/rtld-elf/amd64/lockdflt.c34
-rw-r--r--libexec/rtld-elf/i386/lockdflt.c34
3 files changed, 88 insertions, 5 deletions
diff --git a/libexec/rtld-elf/alpha/lockdflt.c b/libexec/rtld-elf/alpha/lockdflt.c
index 65900a6..5847abb 100644
--- a/libexec/rtld-elf/alpha/lockdflt.c
+++ b/libexec/rtld-elf/alpha/lockdflt.c
@@ -46,6 +46,7 @@
* them to make some progress.
*/
+#include <signal.h>
#include <stdlib.h>
#include <time.h>
@@ -70,6 +71,7 @@ typedef struct Struct_Lock {
} Lock;
static const struct timespec usec = { 0, 1000 }; /* 1 usec. */
+static sigset_t fullsigmask, oldsigmask;
static void *
lock_create(void *context)
@@ -123,9 +125,16 @@ static void
wlock_acquire(void *lock)
{
Lock *l = (Lock *)lock;
+ sigset_t tmp_oldsigmask;
- while (cmp0_and_store_int(&l->lock, WAFLAG) != 0)
+ for ( ; ; ) {
+ sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
+ if (cmp0_and_store_int(&l->lock, WAFLAG) == 0)
+ break;
+ sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
nanosleep(&usec, NULL);
+ }
+ oldsigmask = tmp_oldsigmask;
}
static void
@@ -142,6 +151,7 @@ wlock_release(void *lock)
Lock *l = (Lock *)lock;
atomic_add_int(&l->lock, -WAFLAG);
+ sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
}
void
@@ -155,4 +165,17 @@ lockdflt_init(LockInfo *li)
li->wlock_release = wlock_release;
li->lock_destroy = lock_destroy;
li->context_destroy = NULL;
+ /*
+ * Construct a mask to block all signals except traps which might
+ * conceivably be generated within the dynamic linker itself.
+ */
+ sigfillset(&fullsigmask);
+ sigdelset(&fullsigmask, SIGILL);
+ sigdelset(&fullsigmask, SIGTRAP);
+ sigdelset(&fullsigmask, SIGABRT);
+ sigdelset(&fullsigmask, SIGEMT);
+ sigdelset(&fullsigmask, SIGFPE);
+ sigdelset(&fullsigmask, SIGBUS);
+ sigdelset(&fullsigmask, SIGSEGV);
+ sigdelset(&fullsigmask, SIGSYS);
}
diff --git a/libexec/rtld-elf/amd64/lockdflt.c b/libexec/rtld-elf/amd64/lockdflt.c
index b2ca9a5..c1c23c1 100644
--- a/libexec/rtld-elf/amd64/lockdflt.c
+++ b/libexec/rtld-elf/amd64/lockdflt.c
@@ -72,6 +72,7 @@ typedef struct Struct_Lock {
} Lock;
static const struct timespec usec = { 0, 1000 }; /* 1 usec. */
+static sigset_t fullsigmask, oldsigmask;
static inline int
cmpxchgl(int old, int new, volatile int *m)
@@ -144,10 +145,17 @@ static void
lock80386_acquire(void *lock)
{
Lock *l = (Lock *)lock;
+ sigset_t tmp_oldsigmask;
- while (xchgl(1, &l->lock) != 0)
+ for ( ; ; ) {
+ sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
+ if (xchgl(1, &l->lock) == 0)
+ break;
+ sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
while (l->lock != 0)
nanosleep(&usec, NULL);
+ }
+ oldsigmask = tmp_oldsigmask;
}
static void
@@ -156,6 +164,7 @@ lock80386_release(void *lock)
Lock *l = (Lock *)lock;
l->lock = 0;
+ sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
}
/*
@@ -175,9 +184,16 @@ static void
wlock_acquire(void *lock)
{
Lock *l = (Lock *)lock;
+ sigset_t tmp_oldsigmask;
- while (cmpxchgl(0, WAFLAG, &l->lock) != 0)
+ for ( ; ; ) {
+ sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
+ if (cmpxchgl(0, WAFLAG, &l->lock) == 0)
+ break;
+ sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
nanosleep(&usec, NULL);
+ }
+ oldsigmask = tmp_oldsigmask;
}
static void
@@ -194,6 +210,7 @@ wlock_release(void *lock)
Lock *l = (Lock *)lock;
atomic_add_int(&l->lock, -WAFLAG);
+ sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
}
/*
@@ -250,4 +267,17 @@ lockdflt_init(LockInfo *li)
li->rlock_acquire = li->wlock_acquire = lock80386_acquire;
li->rlock_release = li->wlock_release = lock80386_release;
}
+ /*
+ * Construct a mask to block all signals except traps which might
+ * conceivably be generated within the dynamic linker itself.
+ */
+ sigfillset(&fullsigmask);
+ sigdelset(&fullsigmask, SIGILL);
+ sigdelset(&fullsigmask, SIGTRAP);
+ sigdelset(&fullsigmask, SIGABRT);
+ sigdelset(&fullsigmask, SIGEMT);
+ sigdelset(&fullsigmask, SIGFPE);
+ sigdelset(&fullsigmask, SIGBUS);
+ sigdelset(&fullsigmask, SIGSEGV);
+ sigdelset(&fullsigmask, SIGSYS);
}
diff --git a/libexec/rtld-elf/i386/lockdflt.c b/libexec/rtld-elf/i386/lockdflt.c
index b2ca9a5..c1c23c1 100644
--- a/libexec/rtld-elf/i386/lockdflt.c
+++ b/libexec/rtld-elf/i386/lockdflt.c
@@ -72,6 +72,7 @@ typedef struct Struct_Lock {
} Lock;
static const struct timespec usec = { 0, 1000 }; /* 1 usec. */
+static sigset_t fullsigmask, oldsigmask;
static inline int
cmpxchgl(int old, int new, volatile int *m)
@@ -144,10 +145,17 @@ static void
lock80386_acquire(void *lock)
{
Lock *l = (Lock *)lock;
+ sigset_t tmp_oldsigmask;
- while (xchgl(1, &l->lock) != 0)
+ for ( ; ; ) {
+ sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
+ if (xchgl(1, &l->lock) == 0)
+ break;
+ sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
while (l->lock != 0)
nanosleep(&usec, NULL);
+ }
+ oldsigmask = tmp_oldsigmask;
}
static void
@@ -156,6 +164,7 @@ lock80386_release(void *lock)
Lock *l = (Lock *)lock;
l->lock = 0;
+ sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
}
/*
@@ -175,9 +184,16 @@ static void
wlock_acquire(void *lock)
{
Lock *l = (Lock *)lock;
+ sigset_t tmp_oldsigmask;
- while (cmpxchgl(0, WAFLAG, &l->lock) != 0)
+ for ( ; ; ) {
+ sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
+ if (cmpxchgl(0, WAFLAG, &l->lock) == 0)
+ break;
+ sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
nanosleep(&usec, NULL);
+ }
+ oldsigmask = tmp_oldsigmask;
}
static void
@@ -194,6 +210,7 @@ wlock_release(void *lock)
Lock *l = (Lock *)lock;
atomic_add_int(&l->lock, -WAFLAG);
+ sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
}
/*
@@ -250,4 +267,17 @@ lockdflt_init(LockInfo *li)
li->rlock_acquire = li->wlock_acquire = lock80386_acquire;
li->rlock_release = li->wlock_release = lock80386_release;
}
+ /*
+ * Construct a mask to block all signals except traps which might
+ * conceivably be generated within the dynamic linker itself.
+ */
+ sigfillset(&fullsigmask);
+ sigdelset(&fullsigmask, SIGILL);
+ sigdelset(&fullsigmask, SIGTRAP);
+ sigdelset(&fullsigmask, SIGABRT);
+ sigdelset(&fullsigmask, SIGEMT);
+ sigdelset(&fullsigmask, SIGFPE);
+ sigdelset(&fullsigmask, SIGBUS);
+ sigdelset(&fullsigmask, SIGSEGV);
+ sigdelset(&fullsigmask, SIGSYS);
}
OpenPOWER on IntegriCloud