NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/51918: Tracee can prevent tracer to get its signals by masking



>Number:         51918
>Category:       kern
>Synopsis:       Tracee can prevent tracer to get its signals by masking
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 26 02:00:00 +0000 2017
>Originator:     Kamil Rytarowski
>Release:        NetBSD 7.99.59 amd64
>Organization:
TNF
>Environment:
NetBSD chieftec 7.99.59 NetBSD 7.99.59 (GENERIC) #2: Thu Jan 26 00:00:12 CET 2017  root@chieftec:/public/netbsd-tmp-root/sys/arch/amd64/compile/GENERIC amd64

>Description:
Tracee can prevent tracer to get its signals by masking

This causes harm, as e.g. an application can silently disable SIGTRAP and breakpoints won't be triggered.

This scenario works correctly on Linux and FreeBSD, by not limiting a signal from being received by a debugger.

Reported by Chuck Silvers in a private mail.
>How-To-Repeat:
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>

int
main(int argc, char **argv)
{
        int child;
        int status;
        int wpid;
        sigset_t intmask;

        child = fork();
        if (child == 0) {
                ptrace(PT_TRACE_ME, 0, NULL, 0);

                sigemptyset(&intmask);
                sigaddset(&intmask, SIGTRAP);
                sigprocmask(SIG_BLOCK, &intmask, NULL);

                raise(SIGSTOP);

                __asm__ __volatile__("int3;\n");

                raise(SIGSTOP);

                _exit(0);
        }

        wpid = wait(&status);
        if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP)
                errx(EXIT_FAILURE, "SIGSTOP not met");

        ptrace(PT_CONTINUE, child, (void*)1, 0);

        wpid = wait(&status);
        if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP)
                errx(EXIT_FAILURE, "SIGTRAP not met");

        ptrace(PT_CONTINUE, child, (void*)1, 0);

        wpid = wait(&status);
        if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP)
                errx(EXIT_FAILURE, "SIGSTOP not met");

        return 0;
}
>Fix:
N/A



Home | Main Index | Thread Index | Old Index