SA_ONSTACK/sigaltstack() ignored on iOS

Originator:landon.j.fuller
Number:rdar://13002712 Date Originated:11-Jan-2013 09:57 PM
Status:Closed Resolved:Won't Fix
Product:iOS Product Version:
Classification: Reproducible:
 
11-Jan-2013 09:57 PM Landon Fuller:
Summary:

The kernel appears to have stopped respecting sigaltstack()/SA_ONSTACK.

Steps to Reproduce:

Test code that will demonstrate this bug. It will configure an alternative stack, a signal handler, and then trigger a stack overflow. If you uncomment the raise() call, it will instead simply raise SIGABRT.

#import <Foundation/Foundation.h>

#include <signal.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <execinfo.h>
#include <unistd.h>
#include <errno.h>

static void signal_handler (int signal, siginfo_t *info, void *uap) {
    /*
     * If we're actually running on a new stack, this should:
     * A) Not crash, if a stack overflow occured.
     * B) Show an empty stack trace.
     *
     * Yes, this is not async-safe. It's demo code.
     */
    NSLog(@"Handler ran\n");
    NSLog(@"%@", [NSThread callStackSymbols]);
    _exit(0);
}

void stackFrame (void) {
    stackFrame();
}

int main (int argc, char *argv[]) {
    /* Configure signal stack */
    stack_t sigstk;
    sigstk.ss_size = SIGSTKSZ;
    sigstk.ss_sp = malloc(sigstk.ss_size);
    sigstk.ss_flags = 0;
    if (sigaltstack(&sigstk, 0) < 0) {
        fprintf(stderr, "sigaltstack() failed: %s\n", strerror(errno));
        _exit(1);
    }
    
    /* Configure action */
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction = &signal_handler;
    sigaction(SIGABRT, &sa, NULL);
    sigaction(SIGSEGV, &sa, NULL);
    sigaction(SIGBUS, &sa, NULL);

    //raise(SIGABRT);
    stackFrame();

    return 0;
}

Expected Results:

The signal handler executes, printing an empty call stack.

Actual Results:

On iOS, the stack is left unchanged, and the signal handler either doesn't run (in the case of a stack overflow), or runs on the old stack (in the case of SIGABRT).

On Mac OS X, the thread's stack is switched to the alternative stack, and the test passes successfully.

Regression:

I believe the tests pass on iOS 4.x and earlier. I know they pass in iOS 2.x.

Notes:

I've previously reproduced this on earlier devices, including the iPhone 4.

Comments

Apple Developer Relations - 16-Nov-2015 02:46 PM

There are no plans to address this based on the following:

We don’t support sigaltstack on iOS.

We are now closing this report.

If you have questions about the resolution, or if this is still a critical issue for you, then please update your bug report with that information.

Please be sure to regularly check new Apple releases for any updates that might affect this issue.

By landon.j.fuller at Nov. 17, 2015, 12:06 a.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!