Exemplo n.º 1
0
int
main(int argc, const char *argv[])
{
#    if defined(UNIX)
    intercept_signal(SIGSEGV, (handler_3_t)&handle_signal, false);
    intercept_signal(SIGILL, (handler_3_t)&handle_signal, false);
#    elif defined(WINDOWS)
    SetUnhandledExceptionFilter(&handle_exception);
#    endif

    print("drreg-test running\n");

    test_asm();

    /* Test fault reg restore */
    if (SIGSETJMP(mark) == 0) {
        test_asm_faultA();
    }

    /* Test fault aflags restore */
    if (SIGSETJMP(mark) == 0) {
        test_asm_faultB();
    }

    /* XXX i#511: add more fault tests and other tricky corner cases */

    print("drreg-test finished\n");
    return 0;
}
Exemplo n.º 2
0
static void
test_sandbox_fault(void)
{
    int i;
    print("start fault test\n");
    protect_mem(sandbox_fault_no_ilt, 1024, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC);
    i = SIGSETJMP(mark);
    if (i == 0)
        sandbox_fault(42);
    /* i#1441: test max writes with illegal instr */
    protect_mem(sandbox_illegal_no_ilt, 1024, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC);
    i = SIGSETJMP(mark);
    if (i == 0)
        sandbox_illegal_instr(42);
    print("end fault test\n");
}
Exemplo n.º 3
0
int
main(int argc, char **argv)
{
    pthread_t thread0, thread1;
    void *retval;

#if 0
    /* Get the number of intervals */
    if (argc != 2) {
        print("Usage: %s <intervals>\n", argv[0]);
        exit(0);
    }
    intervals = atoi(argv[1]);
#else /* for batch mode */
    intervals = 10;
#endif

    /* Initialize the lock on pi */
    pthread_mutex_init(&pi_lock, NULL);

    intercept_signal(SIGUSR1, signal_handler, false);
    intercept_signal(SIGSEGV, signal_handler, false);

    /* Make the two threads */
    if (pthread_create(&thread0, NULL, process, (void *)"0") ||
        pthread_create(&thread1, NULL, process, (void *)"1")) {
        print("%s: cannot make thread\n", argv[0]);
        exit(1);
    }

    /* Join (collapse) the two threads */
    if (pthread_join(thread0, &retval) || pthread_join(thread1, &retval)) {
        print("%s: thread join failed\n", argv[0]);
        exit(1);
    }

#if VERBOSE
    print("thread %d sending SIGUSR1\n", getpid());
#endif
    kill(getpid(), SIGUSR1);
#if VERBOSE
    print("thread %d hitting SIGSEGV\n", getpid());
#endif
    if (SIGSETJMP(mark) == 0) {
        *(int *)42 = 0;
    }

    /* Print the result */
    print("Estimation of pi is %16.15f\n", pi);

    struct timespec sleeptime;
    sleeptime.tv_sec = 0;
    sleeptime.tv_nsec = 1000 * 1000 * 1000; /* 100ms */
    nanosleep(&sleeptime, NULL);
}
Exemplo n.º 4
0
int
invalid_ret(int x)
{
    ptr_int_t bad_retaddr = x; /* Sign extend x on X64. */
    where = SIGSETJMP(mark);
    if (where == 0) {
        call_with_retaddr((void *)ring, bad_retaddr);
        print("unexpectedly we came back!");
    } else {
        print("fault caught on " PFX "\n", x);
    }
    return 0;
}
Exemplo n.º 5
0
int R_SelectEx(int  n,  fd_set  *readfds,  fd_set  *writefds,
	       fd_set *exceptfds, struct timeval *timeout,
	       void (*intr)(void))
{
    if (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)
	/* Is it right for select calls with a timeout to be
	   non-interruptable? LT */
	return select(n, readfds, writefds, exceptfds, timeout);
    else {
	volatile sel_intr_handler_t myintr = intr != NULL ? intr : onintr;
	volatile int old_interrupts_suspended = R_interrupts_suspended;
	if (SIGSETJMP(seljmpbuf, 1)) {
	    myintr();
	    R_interrupts_suspended = old_interrupts_suspended;
	    error(_("interrupt handler must not return"));
	    return 0; /* not reached */
	}
	else {
	    int val;

	    /* make sure interrupts are enabled -- this will be
	       restored if there is a LONGJMP from myintr() to another
	       context. */
	    R_interrupts_suspended = FALSE;

	    /* install a temporary signal handler for breaking out of
	       a blocking select */
	    oldSigintHandler = signal(SIGINT, handleSelectInterrupt);

	    /* once the new sinal handler is in place we need to check
	       for and handle any pending interrupt registered by the
	       standard handler. */
	    if (R_interrupts_pending)
		myintr();

	    /* now do the (possibly blocking) select, restore the
	       signal handler, and return the result of the select. */
	    val = select(n, readfds, writefds, exceptfds, timeout);
	    signal(SIGINT, oldSigintHandler);
	    R_interrupts_suspended = old_interrupts_suspended;
	    return val;
	}
    }
}
Exemplo n.º 6
0
int
main(void)
{
    /* XXX: We can also trigger a segfault by trying to execute the buffer. We could
     * get the address of the buffer in the app using some annotation-based approach.
     */
#if defined(UNIX)
    pthread_t thread;
    intercept_signal(SIGSEGV, (handler_3_t)&handle_signal, false);
#elif defined(WINDOWS)
    HANDLE thread;
    DWORD threadId;
    SetUnhandledExceptionFilter(&handle_exception);
#endif

    print("Starting drx_buf threaded test\n");
#if defined(UNIX)
    CHECK(!pthread_create(&thread, NULL, thread_asm_test, NULL), "create failed");
    /* make sure that the buffers are threadsafe */
    (void)thread_asm_test(NULL);
    CHECK(!pthread_join(thread, NULL), "join failed");
#elif defined(WINDOWS)
    CHECK((thread = CreateThread(NULL, 0, thread_asm_test, NULL, 0, &threadId)) != NULL,
          "CreateThread failed");
    /* make sure that the buffers are threadsafe */
    (void)thread_asm_test(NULL);
    WaitForSingleObject(thread, INFINITE);
    CloseHandle(thread);
#endif
    print("Ending drx_buf threaded test\n");
    print("Starting drx_buf signal test\n");
    /* try to cause a segfault and make sure it didn't trigger the buffer to dump */
    if (SIGSETJMP(mark) == 0) {
        int *x = NULL;
        return *x;
    }
    print("Ending drx_buf signal test\n");
    return 0;
}
Exemplo n.º 7
0
/*
 * fvwmSelect - wrapper around the select() system call.
 * This system call may block indefinitely. We don't want
 * to block at all if the "terminate" flag is set - we
 * just want it to fail as quickly as possible.
 */
int
fvwmSelect(fd_set_size_t nfds,
	   fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
	   struct timeval *timeout)
{
	volatile int iRet = -1;  /* This variable MUST NOT be in a register */

#ifdef C_ALLOCA
	/* If we're using the C version of alloca, see if anything needs to be
	 * freed up.
	 */
	alloca(0);
#endif

	/*
	 * Yes, we trash errno here, but you're only supposed to check
	 * errno immediately after a function fails anyway. If we fail,
	 * then it's because we received a signal. If we succeed, we
	 * shouldn't be checking errno. And if somebody calls us expecting
	 * us to preserve errno then that's their bug.
	 *
	 * NOTE: We mustn't call any function that might trash errno
	 *       ourselves, except select() itself of course. I believe
	 *       that sigsetjmp() does NOT trash errno.
	 */
	errno = EINTR;

	/*
	 * Now initialise the non-local jump. Between here and the end of
	 * the routine (more-or-less) we must NOT call any non-reentrant
	 * functions! This is because we might need to abandon them half
	 * way through execution and return here!
	 */
	if ( SIGSETJMP(deadJump, 1) == SIG_INIT )
	{
		/*
		 * Activate the non-local jump. Between now and when we turn the
		 * jump off again, we must NOT call any non-reentrant functions
		 * because we could be interrupted halfway through ...
		 */
		canJump = true;

		/*
		 * If we have already been told to terminate then we will not
		 * execute the select() because the flag will be set. If a
		 * "terminate" signal arrives between testing the flag and
		 * calling select() then we will jump back to the non-local
		 * jump point ...
		 */
		if ( !isTerminated )
		{
			/*
			 * The "die" signal will interrupt this system call:
			 * that IS the whole point, after all :-)
			 */
			iRet = select(nfds,
				      SELECT_FD_SET_CAST readfds,
				      SELECT_FD_SET_CAST writefds,
				      SELECT_FD_SET_CAST exceptfds,
				      timeout);
		}

		/*
		 * The non-local jump is about to go out of scope,
		 * so we must deactivate it. Note that the return-
		 * value from select() will be safely stored in the
		 * local variable before the jump is disabled.
		 */
		canJump = false;
	}

	return iRet;
}
Exemplo n.º 8
0
int
my_setjmp(sigjmp_buf env)
{
    return SIGSETJMP(env);
}
Exemplo n.º 9
0
int
main(int argc, char *argv[])
{
    double res = 0.;
    int i;
#    ifndef X64
    int j;
#    endif
    char *buf;
#    ifdef UNIX
    stack_t sigstack;
#    endif

#    ifdef UNIX
    /* our modrm16 tests clobber esp so we need an alternate stack */
    sigstack.ss_sp = (char *)malloc(ALT_STACK_SIZE);
    sigstack.ss_size = ALT_STACK_SIZE;
    sigstack.ss_flags = SS_ONSTACK;
    i = sigaltstack(&sigstack, NULL);
    assert(i == 0);
    intercept_signal(SIGILL, (handler_3_t)signal_handler, true);
    intercept_signal(SIGSEGV, (handler_3_t)signal_handler, true);
#    else
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)our_top_handler);
#    endif

    buf = allocate_mem(7 * 256 + 1, ALLOW_READ | ALLOW_WRITE | ALLOW_EXEC);
    assert(buf != NULL);

#    ifndef X64
    print("Jumping to a sequence of every addr16 modrm byte\n");
    for (j = 0; j < 256; j++) {
        int mod = ((j >> 6) & 0x3); /* top 2 bits */
        int reg = ((j >> 3) & 0x7); /* middle 3 bits */
        int rm = (j & 0x7);         /* bottom 3 bits */
#        if defined(UNIX) || defined(X64)
        buf[j * 7 + 0] = 0x65; /* gs: */
#        else
        buf[j * 7 + 0] = 0x64; /* fs: */
#        endif
        buf[j * 7 + 1] = 0x67; /* addr16 */
        buf[j * 7 + 2] = 0x8b; /* load */
#        ifdef WINDOWS
        /* Windows can't handle stack pointer being off */
        if (reg == 4) { /* xsp */
            buf[j * 7 + 3] = j | 0x8;
        } else
            buf[j * 7 + 3] = j; /* nearly every single modrm byte */
#        else
        buf[j * 7 + 3] = j;    /* every single modrm byte */
#        endif
        if (mod == 1) {
            buf[j * 7 + 4] = 0x03; /* disp */
            buf[j * 7 + 5] = 0xc3;
        } else if (mod == 2 || (mod == 0 && rm == 6)) {
            buf[j * 7 + 4] = 0x03; /* disp */
            buf[j * 7 + 5] = 0x00; /* disp */
        } else {
            buf[j * 7 + 4] = 0xc3; /* ret */
            buf[j * 7 + 5] = 0xc3;
        }
        buf[j * 7 + 6] = 0xc3;
    }
    buf[256 * 7] = 0xcc;
    print_access_vio = false;
    for (j = 0; j < 256; j++) {
        i = SIGSETJMP(mark);
        if (i == 0)
            test_modrm16(&buf[j * 7]);
        else
            continue;
    }
    print("Done with modrm test: tested %d\n", j);
    count = 0;
    print_access_vio = true;
#    endif /* !X64 */

    /* multi-byte nop tests (case 9862) */
    i = SIGSETJMP(mark);
    if (i == 0) {
        print("Testing nops\n");
        test_nops();
        print("Done with nops\n");
    }

    /* SSE3 and 3DNow instrs will not run on all processors so we can't have this
     * regression test fully test everything: for now its main use is running
     * manually on the proper machines, or manually verifying decoding of these,
     * but we'll leave as a suite/ regression test.
     */

    /* SSE3 tests: mostly w/ modrm of (%edx) */
    i = SIGSETJMP(mark);
    if (i == 0) {
        print("Testing SSE3\n");
        test_sse3(buf);
        print("Should not get here\n");
    }

    /* 3D-Now tests: mostly w/ modrm of (%ebx) */
    i = SIGSETJMP(mark);
    if (i == 0) {
        print("Testing 3D-Now\n");
        test_3dnow(buf);
        print("Should not get here\n");
    }

    /* case 6962: far call/jmp tests
     * Note that DR currently gets the target address wrong for all of these
     * since we skip the segment and only care about the address:
     * not going to fix that anytime soon.
     */
    print("Testing far call/jmp\n");
    test_far_cti();

#    ifdef WINDOWS /* FIXME i#105: crashing on Linux so disabling for now */
    /* PR 242815: data16 mbr */
    print("Testing data16 mbr\n");
    test_data16_mbr();
#    endif

    /* i#1024: rip-rel ind branch */
    print("Testing rip-rel ind branch\n");
    func_ptr = actual_call_target;
    test_rip_rel_ind();

    /* i#1118: subtle prefix opcode issues */
    test_bsr();
    i = SIGSETJMP(mark);
    if (i == 0) {
        test_SSE2();
    }

    /* i#1493: segment register mangling */
    test_mangle_seg();

#    ifdef UNIX
    free(sigstack.ss_sp);
#    endif

    print("All done\n");
    return 0;
}
Exemplo n.º 10
0
int main(int argc, char *argv[])
{
    double res = 0.;
    int i;

#ifdef UNIX
    intercept_signal(SIGILL, (handler_3_t) signal_handler, false);
    intercept_signal(SIGSEGV, (handler_3_t) signal_handler, false);
#else
# ifdef X64_DEBUGGER
    /* FIXME: the vectored handler works fine in the debugger, but natively
     * the app crashes here: yet the SetUnhandled hits infinite fault loops
     * in the debugger, and works fine natively!
     */
    AddVectoredExceptionHandler(1/*first*/,
                                (PVECTORED_EXCEPTION_HANDLER) our_top_handler);
# else
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) our_top_handler);
# endif
#endif

    /* privileged instructions */
    print("Privileged instructions about to happen\n");
    count = 0;
    i = SIGSETJMP(mark);
    switch (i) {
    case 0: test_priv_0();
    case 1: test_priv_1();
    case 2: test_priv_2();
    case 3: test_priv_3();
    }

    /* prefix tests */
    print("OK instr about to happen\n");
    /* multiple prefixes */
    /* FIXME: actually these prefixes on a jmp are "reserved" but this seems to work */
    test_prefix_0();
    print("Bad instr about to happen\n");
    /* lock prefix, which is illegal instruction if placed on jmp */
    count = 0;
    invalid_lock = true;
    if (SIGSETJMP(mark) == 0) {
        test_prefix_1();
    }
    invalid_lock = false;

    print("Invalid instructions about to happen\n");
    count = 0;
    i = SIGSETJMP(mark);
    switch (i) {
        /* note that we decode until a CTI, so for every case the suffix is decoded
         * and changes in later cases may fail even the earlier ones.
         */
    case 0: test_inval_0();
    case 1: test_inval_1();
    case 2: test_inval_2();
    case 3: test_inval_3();
    case 4: test_inval_4();
    case 5: test_inval_5();
    case 6: test_inval_6();
    case 7: test_inval_7();
    default: ;
    }

    print("All done\n");
    return 0;
}
Exemplo n.º 11
0
int
main()
{
    int *pc;
    int release_build = 0; /* 1 == release, 0 == debug */
    void *dcontext;
    int *dstack;
    int tls_offs;
    ptr_int_t owning_thread;
    INIT();

#ifdef UNIX
    intercept_signal(SIGSEGV, (handler_3_t) signal_handler, false);
#else
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) our_top_handler);
#endif

#ifdef WINDOWS
    /* brute force loop over all TLS entries,
     * and see whether owning_thread is GetCurrentThreadId()
     *     0:001> dt getdc owning_thread
     *        +0x05c owning_thread : 0xed8
     *
     *      0:001> dt _TEB TLS64
     *        +0xe10 TLS64 : [64] Ptr32 Void
     */
    for (tls_offs = 63; tls_offs >=0; tls_offs--) {
        enum {offsetof_TLS64_in_TEB = IF_X64_ELSE(0x1480, 0xe10)};
        dcontext_tls_offset = offsetof_TLS64_in_TEB +
            tls_offs*sizeof(void*);
        GET_DCONTEXT(dcontext);
#if VERBOSE
        print("%d idx, %x offs\n", tls_offs, dcontext_tls_offset);
#endif
        where = SIGSETJMP(mark);
        if (where == 0) {
            owning_thread = *(ptr_int_t *)(((char *)dcontext) +
                                           OWNING_THREAD_OFFSET_IN_DCONTEXT);
            /* we didn't crash reading, is it really thread ID? */
#if VERBOSE
            print("     %d thread %d vs %d\n", tls_offs, owning_thread, GetCurrentThreadId());
#endif
            if (owning_thread == GetCurrentThreadId()) {
#if VERBOSE
                print("     %d is dcontext!\n", tls_offs);
#endif
                break;
            }
        } else {
#if VERBOSE
            print("     %d crashed\n", tls_offs);
#endif
            /* we crashed reading, try next offset */
        }
    }
    if (tls_offs < 0) {
        print("error obtaining dcontext (TLS offset not found): "
              "are you running natively?!?\n");
        exit(1);
    }
#endif
    where = SIGSETJMP(mark);
    if (where != 0) {
        print("error obtaining dcontext (SIGSETJMP failed): "
              "are you running natively?!?\n");
        exit(1);
    }
    GET_DCONTEXT(dcontext)
#if VERBOSE
    print("dcontext is "PFX"\n", dcontext);
#endif
    dstack = *(int **)(((char *)dcontext) + DSTACK_OFFSET_IN_DCONTEXT);
    if (dstack == NULL || !ALIGNED(dstack, PAGE_SIZE)) {
        print("can't find dstack: old build, or new where dstack offset changed?\n");
        while (1)
            ;
        exit(-1);
    }
    dstack_base = (int *) (((char *)dstack) - DSTACK_SIZE);
#if VERBOSE
    print("dstack is "PFX"-"PFX"\n", dstack_base, dstack);
#endif
    print("dcontext->dstack successfully obtained\n");
    where = SIGSETJMP(mark);
#if VERBOSE
    print("SIGSETJMP returned %d\n", where);
#endif
    if (where == 0) {
        /* if we do the copy in a C loop, trace heads cause us to exit before
         * we've hit the cxt switch return address, so we crash rather than taking
         * control -- so we hand-code a copy that in C looks like this:
         *          for (pc = dstack_base; pc++; pc < dstack)
         *              *pc = (int) evil;
         * we assume df is cleared
         * FIXME: popf in old fcache_return can trigger a trap crash before
         * get to ret that goes to evil!
         * FIXME: I had this getting to evil w/o crashing first, but it's
         * a little fragile, and on win32 I get issues later b/c we have
         * trampolines, etc. and so don't completely lose control.
         * But, in all cases we fail, so whether it's a nice shell code
         * execution or a crash doesn't matter -- the test does what it's supposed
         * to do!
         */
        evil_copy(dstack_base, DSTACK_SIZE / sizeof(int), (ptr_int_t)evil);
        print("wrote to entire dstack without incident!\n");
    } else if (where == 1) {
        print("error writing to "PFX" in expected dstack "PFX"-"PFX"\n",
              pc, dstack_base, dstack);
    } else if (where == 2) {
        print("DR has been cracked!  Malicious code is now runnning...\n");
    }
}