Bug 5820 - kernel does not supply address of SIGSEGV signal in si_addr field.
kernel does not supply address of SIGSEGV signal in si_addr field.
Status: CLOSED DEFERRED
Product: Red Hat Linux
Classification: Retired
Component: kernel (Show other bugs)
6.1
i386 Linux
high Severity high
: ---
: ---
Assigned To: David Miller
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 1999-10-11 02:24 EDT by geocaris
Modified: 2008-05-01 11:37 EDT (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 1999-10-11 15:30:20 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Description geocaris 1999-10-11 02:24:30 EDT
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 09:40:34 EDT
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.