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

mprotect



Greetings!  In porting gcl, I'm trying to read the fault address on
writing to an array mprotect'ed to PROT_READ.  This gives a SIGSEGV on
all Debian arches except s390.  Anyone know why?  Is there an
equivalent mechanism here?

Take care,

=============================================================================
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>

/*  #ifndef PAGESIZE */
/*  #define PAGESIZE 4096 */
/*  #endif */

#define NP 1024

long i,j,k,ps;
char *b1,*b;

#if defined(__i386__) || defined(__alpha__)

#include <asm/sigcontext.h>

void
s1(int sig,int code) {

  struct sigaction sa={0};

  i++;
#if defined(__i386__)
  if (((struct sigcontext *)(&code))->cr2!=(long)(b+j)) {
    printf("Mismatch: %p %p\n",((struct sigcontext *)(&sig+1))->cr2,(long)(b+j));
    exit(1);
#elif defined (__alpha__)
  if (((struct sigcontext *)(&code))->sc_sbase!=(char *)(b+j)) {
    printf("Mismatch: %p %p\n",((struct sigcontext *)(&sig+1))->sc_sbase,(long)(b+j));
    exit(1);
#endif
    k=1;
  }

  if (mprotect(b+(j&~(ps-1)),1+(j&(ps-1)),PROT_READ|PROT_WRITE)) {
    perror("cannot mprotect");
    exit(errno);
  }

}
#endif
  

void
segvh(int s,siginfo_t *si,void *p) {

  struct sigaction sa={0};

  i++;
  if (si->si_addr!=(b+j)) {
    printf("Mismatch: %p %p\n",si->si_addr,(long)(b+j));
    exit(1);
    k=1;
  }

  if (mprotect(b+(j&~(ps-1)),1+(j&(ps-1)),PROT_READ|PROT_WRITE)) {
    perror("cannot mprotect");
    exit(errno);
  }


}

int
main(int argc,char * argv[]) {

  struct sigaction sa={0};
  time_t tt;
  int ii;

  if (!(ps=getpagesize())) {
    perror("Cannot get pagesize");
    return errno;
  }

  if (!(b1=malloc(ps*NP+ps-1))) {
    perror("Cannot malloc");
    return errno;
  }

  b=(char *)(((long)b1+ps-1) & ~(ps-1));

  if (mprotect(b,ps*NP,PROT_READ)) {
    perror("cannot mprotect");
    exit(errno);
  }

  srand(time(&tt));
  k=0;
  
#if defined(__i386__) || defined(__alpha__)
  if (argc>1) {
#endif
    sa.sa_sigaction=segvh;
    sa.sa_flags=SA_RESTART|SA_SIGINFO;
    sigaction(SIGSEGV,&sa,NULL);
#if defined(__i386__) || defined(__alpha__)
  } else {
    sa.sa_handler=s1;
    sa.sa_flags=SA_RESTART;
    sigaction(SIGSEGV,&sa,NULL);
  }
#endif
  
  for (ii=i=0;i<100 && ii<1000;ii++) {

    j=ps*NP*(float)rand()/RAND_MAX;

    b[j]=0;

    if (mprotect(b,ps*NP,PROT_READ)) {
      perror("cannot mprotect");
      exit(errno);
    }

  }

  return  i==100 ? k : 1;

}

=============================================================================

-- 
Camm Maguire			     			camm@enhanced.com
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah


-- 
To UNSUBSCRIBE, email to debian-s390-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org



Reply to: