changeset 11598:58b1732d052a

Check that memchr does not read past the first occurrence of the byte.
author Bruno Haible <bruno@clisp.org>
date Sun, 31 May 2009 14:38:11 +0200
parents 2305ee9778fb
children 9ef2eb4b8fe1
files ChangeLog tests/test-memchr.c tests/test-strstr.c tests/zerosize-ptr.h
diffstat 4 files changed, 47 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-05-31  Bruno Haible  <bruno@clisp.org>
+
+	* tests/zerosize-ptr.h (zerosize_ptr): Specify more details.
+	* tests/test-memchr.c (main): Check that memchr does not read past the
+	first occurrence of the byte.
+	* tests/test-strstr.c (main): Update comment.
+	Suggested by Eric Blake.
+
 2009-05-30  Bruno Haible  <bruno@clisp.org>
 
 	* doc/ld-output-def.texi (Visual Studio Compatibility): Explain in more
--- a/tests/test-memchr.c
+++ b/tests/test-memchr.c
@@ -94,6 +94,36 @@
       }
   }
 
+  /* Check that memchr() does not read past the first occurrence of the
+     byte being searched.  See the Austin Group's clarification
+     <http://www.opengroup.org/austin/docs/austin_454.txt>.  */
+  {
+    char *page_boundary = (char *) zerosize_ptr ();
+
+    if (page_boundary != NULL)
+      {
+	int n;
+
+	for (n = 1; n <= 500; n++)
+	  {
+	    char *mem = page_boundary - n;
+	    memset (mem, 'X', n);
+	    ASSERT (MEMCHR (mem, 'U', n) == NULL);
+
+	    {
+	      int i;
+
+	      for (i = 0; i < n; i++)
+		{
+		  mem[i] = 'U';
+		  ASSERT (MEMCHR (mem, 'U', 4000) == mem + i);
+		  mem[i] = 'X';
+		}
+	    }
+	  }
+      }
+  }
+
   free (input);
 
   return 0;
--- a/tests/test-strstr.c
+++ b/tests/test-strstr.c
@@ -61,7 +61,12 @@
   }
 
   {
-    /* See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737 */
+    /* 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 *input = malloc (strlen (fix) + 1);
     const char *result;
--- a/tests/zerosize-ptr.h
+++ b/tests/zerosize-ptr.h
@@ -35,7 +35,9 @@
 # endif
 #endif
 
-/* Return a pointer to a zero-size object in memory, if possible.
+/* 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 *