Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • D dynamorio
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 1,467
    • Issues 1,467
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 44
    • Merge requests 44
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • DynamoRIO
  • dynamorio
  • Issues
  • #2812
Closed
Open
Issue created Jan 22, 2018 by Administrator@rootContributor

CRASH: xstate_query_signal_handler does not return properly on 32-bit builds

Created by: alpire

What version of DynamoRIO are you using?

Master ( 5a646683)

What operating system version are you running on?

Ubuntu 16.04.3 LTS on 4.4.0-93-generic amd64 kernel

What application are you running?

#include <stdio.h>

int main() {
  printf("It works\n");
  return 0;
}

Is your application 32-bit or 64-bit?

32-bit

How are you running the application under DynamoRIO?

./drrun -- ./32-bit-application (note that this happens with and without any clients)

What happens when you run with debug build?

It crashes as well and prints <ERROR: master_signal_handler with no siginfo (i#26?): tid=23649, sig=11>

What steps will reproduce the problem?

  1. Compile 5a646683 for 32 bit
  2. Run ./drrun -- ./32-bit-application

What is the expected output? What do you see instead? Is this an application crash, a DynamoRIO crash, a DynamoRIO assert, or a hang?

I expect to see It works! printed on stdout. Instead, I see:

<Starting application /home/.../a.out (8286)>
<ERROR: master_signal_handler with no siginfo (i#26?): tid=8286, sig=11>
<Application /home/.../a.out (8286). Cannot correctly handle a received signal.>

It is a DynamoRIO crash

Additional information below.

The bug was introduced at https://github.com/DynamoRIO/dynamorio/commit/474e93b3b8798bcdc336d523425412b889d335bf. In https://github.com/DynamoRIO/dynamorio/blob/master/core/unix/signal_linux_x86.c#L548, DynamoRIO sets up a SIGILL signal handler and triggers a SIGILL to run the handler. The handler runs, but triggers a segfault after returning. You can see this happening in the syscall trace:

rt_sigaction(SIGILL, {0xf769bb35, ~[SEGV USR2], SA_STACK|SA_RESTART|SA_SIGINFO}, {SIG_DFL, [], 0}, 8) = 0
gettid()                                = 8327
getpid()                                = 8327
tgkill(8327, 8327, SIGILL)              = 0
--- SIGILL {si_signo=SIGILL, si_code=SI_TKILL, si_pid=8327, si_uid=1000} ---
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xbd0} ---

The same segfault can be triggered with this reduced C program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/syscall.h>

struct kernel_sigaction {
  void * k_sa_handler;
  int sa_mask;
  unsigned long sa_flags;
  void (*sa_restorer) (void);
};

static void xstate_query_signal_handler(int sig, siginfo_t *siginfo, void *ucxt) { 
  printf("Helllo\n");
}

void
set_handler_sigact(struct kernel_sigaction *act, int sig, void* handler)
{ 
  act->k_sa_handler = handler;
  act->sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
  
  memset(&act->sa_mask, 0xff, 4);
  sigdelset((sigset_t*)&act->sa_mask, SIGSEGV);
  sigdelset((sigset_t*)&act->sa_mask, SIGUSR2);
}

int
main(void)
{
  int rc;
  struct kernel_sigaction act ;
  memset(&act, 0, sizeof(struct kernel_sigaction));
  set_handler_sigact(&act, SIGILL,  xstate_query_signal_handler);
  rc = syscall(SYS_sigaction, SIGILL, &act, NULL, 4);
  syscall(SYS_tgkill, getpid(), getpid(), SIGILL);             
  printf("It works\n");                                              
  return rc;                                                   
} 

My kernel requires the SA_RESTORER flag to be set. sa_restorer should point to a signal trampoline code (You can see it done in libc at https://github.com/lattera/glibc/blob/master/sysdeps/unix/sysv/linux/i386/sigaction.c#L65). Note that this is done conditionally based on GLRO(dl_sysinfo_dso). I am not sure what an equivalent check in DynamoRIO would be, or if that check is even necessary. Adding the SA_RESTORER flag and the sa_restorer callbacks fixes the segfault in the above C program.

Assignee
Assign to
Time tracking