tech-kern archive

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

SIGBUS + coredump



I've prepared a patch to fix tests for SIGBUS core generation:

http://netbsd.org/~kamil/patch-00077-sigbus-coredump.txt

The problem is that when we are in coredump_getseghdrs_elf64() and call
copyin_proc() -> copyin_vmspace() -> copyin() we trigger a trap that is
translated through trap() -> ... -> genfs_getpages() to EINVAL as there
are no pages assigned to a mamory address.

I've added a kludge to tolerate EINVAL in coredump_getseghdrs_elf64()
and locally initialize the buffer with zeros.

I don't know what would be a better solution. As a more complicated
workaround I could try to assign pages/mapping to the allocation during
core-dumping process.  However it's a little bit more complex (too
complex?) compared to handling EINVAL in coredump_getseghdrs_elf64().

The expected result is to get zeroed region that is represented by
appropriate pointer that triggers a fault.

With the linked patch we pass all ptrace(2) + SIGBUS tests.

Is it fine to commit?

Reproducer:

$ cat bus.c
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

static void
trigger_bus(void)
{
        FILE *fp;
        char *p;

        /* Open an empty file for writing. */
        fp = tmpfile();
        p = mmap(0, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(fp), 0);
        *p = 'a';

}


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

        child = vfork();
        if (child == 0) {
                ptrace(PT_TRACE_ME, 0, NULL, 0);
                trigger_bus();
        }
        wpid = waitpid(child, &status, 0);
        int x = !!WCOREDUMP(status);
        printf("core=%d\n", x);
        return 0;
}

Attachment: signature.asc
Description: OpenPGP digital signature



Home | Main Index | Thread Index | Old Index