Note: This is a beta release of Red Hat Bugzilla 5.0. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Also email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback here.
Bug 5820 - kernel does not supply address of SIGSEGV signal in si_addr field.
Summary: kernel does not supply address of SIGSEGV signal in si_addr field.
Keywords:
Status: CLOSED DEFERRED
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: kernel
Version: 6.1
Hardware: i386
OS: Linux
high
high
Target Milestone: ---
Assignee: David Miller
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 1999-10-11 06:24 UTC by geocaris
Modified: 2008-05-01 15:37 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 1999-10-11 19:30:20 UTC


Attachments (Terms of Use)

Description geocaris 1999-10-11 06:24:30 UTC
The kernel does not pass the memory address which caused a
SIGSEGV signal to the signal handler. The si_addr field in
the siginfo_t structure. The field is always zero. This
mechanism is used inconjunction with mmap to detect
reads/writes to regions of memory by a process. For example,

the following program should print "hello world", but it
exits in the signal handler because the kernel passes in
the si_addr field, instead of the address which was returned
by mmap() in main().

Tom Geocaris

/////////////////////// code ///////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <signal.h>

void segv_handler( int sig, siginfo_t *info, void
*user_context );

void install_signal_handlers();

static struct sigaction old_sigsegv;

void install_signal_handlers()
{
    struct sigaction action;

    sigaction( SIGSEGV, NULL, &old_sigsegv );

    action = old_sigsegv;
    action.sa_sigaction = segv_handler;
    sigemptyset( &action.sa_mask );
    action.sa_flags |= SA_SIGINFO;
    sigaction( SIGSEGV, &action, NULL );
}

void
segv_handler( int sig, siginfo_t *info, void *user_context )
{
   printf("SEGV at %x with type %d\n", info->si_addr,
info->si_code );

   if ( info->si_addr )
       mprotect( info->si_addr, 4096, PROT_WRITE );
   else
       exit(1);
}

main()
{
    int fd;
    install_signal_handlers();

    fd = open( "/dev/zero", O_RDWR );

    if ( fd <= 0 )
    {
        printf("Cannot open zero\n");
        exit(1);
    }

    caddr_t b;

    b = (caddr_t) mmap( 0, 8192, PROT_NONE,
MAP_PRIVATE|MAP_NORESERVE|MAP_ANON, fd, 0 );

    close(fd);

    if ( b == (void *) -1 )
    {
        printf("Cannot create mapping \n" );
        exit(1);
    }

    *b = 1;
    printf( "hello world\n");
}

Comment 1 Alan Cox 2000-08-08 13:40:34 UTC
This feature should be in the 2.4 kernel.



Note You need to log in before you can comment on or make changes to this bug.