This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/12019] New: memchr overshoots on Alpha


Gnulib testing revealed that memchr mistakenly reads memory past a match on
Alpha when given an over-estimated size.  This can lead to spurious SEGV in a
variety of methods, such as strstr().

$ uname -a
Linux xxx 2.6.34-gentoo-r1 #1 SMP Sun Aug 8 17:45:07 MDT 2010 alpha GNU/Linux
$ cat foo.c
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>

/* Return a pointer to a zero-size object in memory (that is, actually, a
   pointer to a page boundary where the previous page is readable and writable
   and the next page is neither readable not writable), if possible.
   Return NULL otherwise.  */

static void *
zerosize_ptr (void)
{
  const int flags = MAP_ANONYMOUS | MAP_PRIVATE;
  const int fd = -1;
    {
      int pagesize = getpagesize ();
      char *two_pages =
        (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,
                       flags, fd, 0);
      if (two_pages != (char *)(-1)
          && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)
        return two_pages + pagesize;
    }
  return NULL;
}


int
main (int argc, char *argv[])
{
  {
    /* On some platforms, the memchr() functions reads past the first
       occurrence of the byte to be searched, leading to an out-of-bounds
       read access for strstr().
       See <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737>.
       This is a bug in memchr(), see the Austin Group's clarification
       <http://www.opengroup.org/austin/docs/austin_454.txt>.  */
    const char *fix = "aBaaaaaaaaaaax";
    char *page_boundary = (char *) zerosize_ptr ();
    size_t len = strlen (fix) + 1;
    char *input = page_boundary ? page_boundary - len : malloc (len);
    const char *result;

    strcpy (input, fix);
    result = strstr (input, "B1x");
    assert (result == NULL);
    if (!page_boundary)
      free (input);
  }
  return 0;
}
$ ./foo
Segmentation fault (core dumped)
$ gdb ./foo
...
(gdb) r
Starting program: /tmp/foo 

Program received signal SIGSEGV, Segmentation fault.
0x00000200000c3330 in memchr () from /lib/libc.so.6.1
(gdb) bt
#0  0x00000200000c3330 in memchr () from /lib/libc.so.6.1
#1  0x00000200000c2fe4 in strstr () from /lib/libc.so.6.1
#2  0x0000000120000a54 in main (argc=1, argv=0x11ff585f8) at foo.c:49

-- 
           Summary: memchr overshoots on Alpha
           Product: glibc
           Version: 2.11
            Status: NEW
          Severity: critical
          Priority: P2
         Component: libc
        AssignedTo: drepper at gmail dot com
        ReportedBy: eblake at redhat dot com
                CC: glibc-bugs at sources dot redhat dot com


http://sourceware.org/bugzilla/show_bug.cgi?id=12019

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]