mmap problems on several Linux versions including 2.3.13

Richard B. Johnson (root@chaos.analogic.com)
Thu, 9 Sep 1999 09:30:04 -0400 (EDT)


Hello!

The following code shows that something is wrong with mmap on version
2.3.13. Reading physical memory at an address that did not fail to be
mapped, will segfault. One of the (many) such addresses is put into
the test code.

Most low addresses work. This is not a physical memory problem, no
exceptions are generated on Intel machines while reading nonexistant
memory. You just get all ones.

This has been tried on three machines with different versions of compilers
and 'C' runtime libraries, all with the same results.

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

#define DEBUG

#if !defined(PAGE_SIZE)
#define PAGE_SIZE 0x1000
#endif
#if !defined(MAKE_MASK)
#define PAGE_MASK ~(PAGE_SIZE - 1)
#endif
#if !defined(MAP_FAILED)
#define MAP_FAILED (void *) -1
#endif
#define UL unsigned long

#define ERRORS \
{ fprintf(stderr, errmsg, __LINE__,\
__FILE__, errno, strerror(errno));\
exit(EXIT_FAILURE); }

#ifdef DEBUG
#define DEB(f) (f)
#else
#define DEB(f)
#endif

static const char errmsg[]="Error at line %d, file %s (%d) [%s]\n";
static const char mapfile[]="/dev/mem";
#define PROT (PROT_READ|PROT_WRITE)
#define FLAGS (MAP_FIXED|MAP_SHARED)
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*
* This writes a 'debug-like' dump out the screen. It always writes
* 16 lines of 16 characters. It returns the last address displayed.
*/
static off_t dump(off_t addr)
{
size_t i, j;
int fd;
caddr_t mem;
off_t next;
unsigned char c, *buf;
next = addr;
addr &= PAGE_MASK;
if((fd = open(mapfile, O_RDWR)) < 0)
ERRORS;

if((mem = mmap((caddr_t)addr, PAGE_SIZE, PROT, FLAGS, fd, addr)) == MAP_FAILED)
{
(void)close(fd);
fprintf(stderr, "\tCan't map address %08lX\n", (UL) addr);
return addr;
}
buf = (unsigned char *) next;
DEB(fprintf(stderr, "Mapped address = 0x%lx\n", addr));
DEB(fprintf(stderr, "Buffer address = %p\n", buf));
for(i=0; i< 0x10; i++)
{
fprintf(stdout, "\n%08lX ", (UL) next);
next += 0x10;
for(j=0; j< 0x10; j++)
fprintf(stdout, "%02X ", (unsigned int) *buf++);
buf -= 0x10;
for(j=0; j<0x10; j++)
{
c = *buf++;
if((c < (unsigned char) ' ') || (c > (unsigned char) 'z'))
c = (unsigned char) '.';
fprintf(stdout, "%c", c);
}
}
fprintf(stdout, "\n");
(void)close(fd);
if(munmap(mem, PAGE_SIZE)< 0)
ERRORS;
return next;
}

int main()
{

off_t addr = 0xbfffc000;
for(;;)
addr = dump(addr);
return 0;
}

Cheers,
Dick Johnson
**** FILE SYSTEM WAS MODIFIED ****
Penguin : Linux version 2.3.13 on an i686 machine (400.59 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/