DynamoRIO / DynamoRIO/dynamorio

Unable to attach to thread that is blocking SIGILL

Open
#7,805 8 comments 0 reactions 0 assignees View on GitHub
OpSys-UNIX
Dominant language
C
Stars
3.2k
Forks
629
Avg merge
2d 15h
Merged PRs (30d)
31

Description

Perhaps this is a more of a known limitation than a bug but I have come across an application in the wild that has a thread which blocks all signals using `pthread_sigmask()` then handles signals by calling `sigwaitinfo()` in a loop.

When statically linking DynamoRIO into the app we are unable to take over the signal handling thread because SIGILL is blocked.

We are able to work around it by modifying the app to unblock SIGILL but perhaps there is a way for DynamoRIO to unblock SIGILL before attempting to attach (perhaps using ptrace if it is not possible using regular APIs).

Here is a test app that reproduces the issue:
```
#include "configure.h"
#include "dr_api.h"
#include "tools.h"
#include "condvar.h"
#include "thread.h"

#include
#include

#ifndef UNIX
# error UNIX-only
#endif

static void *signals_blocked;

static THREAD_FUNC_RETURN_TYPE
sig_thread(void *arg)
{
sigset_t set;
siginfo_t info;
int res;

sigfillset(&set);
res = pthread_sigmask(SIG_BLOCK, &set, NULL);
assert(res == 0);

print("sig_thread blocked signals\n");
signal_cond_var(signals_blocked);

while (true) {
res = sigwaitinfo(&set, &info);
if (res == -1) {
if (errno == EINTR)
continue;
}
assert(res != -1);
if (res == SIGUSR1) {
print("sig_thread received SIGUSR1\n");
break;
}
}
return NULL;
}

DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
print("in dr_client_main\n");
}

int
main(int argc, const char *argv[])
{
signals_blocked = create_cond_var();

print("starting sig_thread\n");
thread_t thread = create_thread(sig_thread, NULL);

wait_cond_var(signals_blocked);

print("pre-DR start\n");
assert(!dr_app_running_under_dynamorio());
dr_app_setup_and_start(); /* This call will hang because we can't attach to sig_thread. */
assert(dr_app_running_under_dynamorio());

print("sending SIGUSR1 to sig_thread\n");
pthread_kill(thread, SIGUSR1);
join_thread(thread);

print("pre-DR stop\n");
dr_app_stop_and_cleanup();
assert(!dr_app_running_under_dynamorio());

destroy_cond_var(signals_blocked);

print("all done\n");
return 0;
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.