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
  • #1814
Closed
Open
Issue created Oct 16, 2015 by Derek Bruening@derekbrueningContributor

Mac does not allow clearing sigaltstack after abnormal signal exit

If we have a crash in a signal handler and we then exit DR we get this on Mac:

<Application /Users/cutler/derek/dr/git/build_x86_dbg_tests/suite/tests/bin/linux.signal0000 (66119).  Internal Error: DynamoRIO debug check failure: /Users/cutler/derek/dr/git/src/core/unix/signal.c:1199 i == 0

The sigaltstack return val is -22=EINVAL, ss_sp is 0, ss_flags is SS_DISABLE

Xref

    /* Although "man sigaltstack" claims ss_sp and ss_size are ignored when
     * SS_DISABLE is set, on Mac we get ENOMEM if we clear ss_sp beforehand.
     */

That's from the size check at the end here, which is after the EINVAL checks:

/extsw/mac/xnu-2422.1.72/bsd/kern/kern_sig.c
    if (ss.ss_size < OLDMINSIGSTKSZ)
        return (ENOMEM);

Or is it? It should return earlier for SS_DISABLE. This is in DrMem's tests/signal.c -- may want to revisit that. And I did: and confirmed I get ENOMEM if ss_size is 0 when flags==SS_DISABLE.

Anyway, we're getting EINVAL. The man page says:

  Trying to disable an active stack will cause sigaltstack to return -1 with errno
  set to EINVAL. 

But we are not currently on the stack:

removing our signal stack 0x4f069000 - 0x4f077000
XXX sigaltstack=>-22 for 0x4f069000 0xe000 0x4 cur=0x4f04eb80

The app crash is inside the handler: does the kernel really track whether we called sigreturn? It looks like it does:

/extsw/mac/xnu-2422.1.72/bsd/kern/kern_sig.c
    if (ss.ss_flags & SA_DISABLE) {
        /* if we are here we are not in the signal handler ;so no need to check */
        if (uth->uu_sigstk.ss_flags & SA_ONSTACK)
            return (EINVAL);

/extsw/mac/xnu-2422.1.72/bsd/dev/i386/unix_signal.c
sendsig()
            ut->uu_sigstk.ss_flags |= SA_ONSTACK;
sigreturn()
        ut->uu_sigstk.ss_flags &= ~SA_ONSTACK;

This doesn't seem like the right thing for the kernel to do, but we'll have to work around it by allowing the syscall to fail.

Assignee
Assign to
Time tracking