This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] string: Add tests for zero length string inputs
- From: Will Newton <will dot newton at linaro dot org>
- To: libc-alpha <libc-alpha at sourceware dot org>
- Date: Wed, 15 Oct 2014 10:41:15 +0100
- Subject: Re: [PATCH] string: Add tests for zero length string inputs
- Authentication-results: sourceware.org; auth=none
- References: <1410910830-20900-1-git-send-email-will dot newton at linaro dot org>
On 17 September 2014 00:40, Will Newton <will.newton@linaro.org> wrote:
> For the string functions that take string lengths as an argument we
> should ensure that no data is read or written if a length of zero is
> specified. Pointers to PROT_NONE memory are used to ensure that any
> reads or writes will cause a fault.
>
> ChangeLog:
>
> 2014-09-16 Will Newton <will.newton@linaro.org>
>
> * string/test-memccpy.c (do_test_zero_length): New function.
> (test_main): Call do_test_zero_length.
> * string/test-memchr.c: Likewise.
> * string/test-memcmp.c: Likewise.
> * string/test-memcpy.c: Likewise.
> * string/test-memmem.c: Likewise.
> * string/test-memmove.c: Likewise.
> * string/test-memrchr.c: Likewise.
> * string/test-memset.c: Likewise.
> * string/test-strncmp.c: Likewise.
> * string/test-strncpy.c: Likewise.
> * string/test-strnlen.c: Likewise.
> * string/test-strncasecmp.c (do_test_zero_length): New function.
> (test_locale): Call do_test_zero_length.
> * string/test-strncat.c (do_test_zero_length): New function.
> (main): Call do_test_zero_length.
> ---
> string/test-memccpy.c | 10 ++++++++++
> string/test-memchr.c | 9 +++++++++
> string/test-memcmp.c | 11 +++++++++++
> string/test-memcpy.c | 11 +++++++++++
> string/test-memmem.c | 10 ++++++++++
> string/test-memmove.c | 12 ++++++++++++
> string/test-memrchr.c | 10 ++++++++++
> string/test-memset.c | 11 +++++++++++
> string/test-strncasecmp.c | 15 +++++++++++++++
> string/test-strncat.c | 24 ++++++++++++++++++++++++
> string/test-strncmp.c | 11 +++++++++++
> string/test-strncpy.c | 11 +++++++++++
> string/test-strnlen.c | 10 ++++++++++
> 13 files changed, 155 insertions(+)
Is there any consensus that this patch is useful or should I drop it?
Thanks,
> diff --git a/string/test-memccpy.c b/string/test-memccpy.c
> index 725d640..6192e5e 100644
> --- a/string/test-memccpy.c
> +++ b/string/test-memccpy.c
> @@ -230,6 +230,15 @@ do_random_tests (void)
> }
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointers to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, buf2 + page_size, buf1 + BUF1PAGES * page_size, 0, 1, 0);
> +}
> +
> int
> test_main (void)
> {
> @@ -263,6 +272,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> diff --git a/string/test-memchr.c b/string/test-memchr.c
> index 0ba79b8..29904d1 100644
> --- a/string/test-memchr.c
> +++ b/string/test-memchr.c
> @@ -141,6 +141,14 @@ do_random_tests (void)
> }
> }
>
> +static void do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointer to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size), 'a', 0, NULL);
> +}
> +
> int
> test_main (void)
> {
> @@ -167,6 +175,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> diff --git a/string/test-memcmp.c b/string/test-memcmp.c
> index 14090ed..80436c6 100644
> --- a/string/test-memcmp.c
> +++ b/string/test-memcmp.c
> @@ -471,6 +471,16 @@ check2 (void)
> }
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointers to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (CHAR *) (buf2 + page_size),
> + (CHAR *) (buf1 + BUF1PAGES * page_size), 0, 0);
> +}
> +
> int
> test_main (void)
> {
> @@ -519,6 +529,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
> #include "../test-skeleton.c"
> diff --git a/string/test-memcpy.c b/string/test-memcpy.c
> index 136c985..4d2f65b 100644
> --- a/string/test-memcpy.c
> +++ b/string/test-memcpy.c
> @@ -206,6 +206,16 @@ do_random_tests (void)
> }
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointers to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size),
> + (char *) (buf1 + BUF1PAGES * page_size), 0);
> +}
> +
> int
> test_main (void)
> {
> @@ -247,6 +257,7 @@ test_main (void)
> do_test (0, 0, getpagesize ());
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> diff --git a/string/test-memmem.c b/string/test-memmem.c
> index caaa191..6199c22 100644
> --- a/string/test-memmem.c
> +++ b/string/test-memmem.c
> @@ -151,6 +151,15 @@ static const char *const strs[] =
> "abc0", "aaaa0", "abcabc0"
> };
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointer to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size), 0,
> + strs[0], strlen (strs[0]), NULL);
> +}
>
> int
> test_main (void)
> @@ -178,6 +187,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> diff --git a/string/test-memmove.c b/string/test-memmove.c
> index 7e1c41c..25abb57 100644
> --- a/string/test-memmove.c
> +++ b/string/test-memmove.c
> @@ -244,6 +244,17 @@ do_random_tests (void)
> }
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointers to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size),
> + (char *) (buf1 + BUF1PAGES * page_size),
> + (char *) (buf1 + BUF1PAGES * page_size), 0);
> +}
> +
> int
> test_main (void)
> {
> @@ -283,6 +294,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> diff --git a/string/test-memrchr.c b/string/test-memrchr.c
> index efe4e9f..23c4a8b 100644
> --- a/string/test-memrchr.c
> +++ b/string/test-memrchr.c
> @@ -137,6 +137,15 @@ do_random_tests (void)
> }
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointer to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size), 'a', 0, NULL);
> +}
> +
> int
> test_main (void)
> {
> @@ -163,6 +172,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> diff --git a/string/test-memset.c b/string/test-memset.c
> index 2171b0d..b5432ce 100644
> --- a/string/test-memset.c
> +++ b/string/test-memset.c
> @@ -192,6 +192,15 @@ do_random_tests (void)
> }
> #endif
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointer to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size), 0, 0);
> +}
> +
> int
> test_main (void)
> {
> @@ -227,6 +236,8 @@ test_main (void)
> do_random_tests ();
> #endif
>
> + do_test_zero_length ();
> +
> return ret;
> }
>
> diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c
> index 6ad54e0..78d2dec 100644
> --- a/string/test-strncasecmp.c
> +++ b/string/test-strncasecmp.c
> @@ -53,9 +53,13 @@ simple_strncasecmp (const char *s1, const char *s2, size_t n)
> static int
> stupid_strncasecmp (const char *s1, const char *s2, size_t max)
> {
> + if (max == 0)
> + return 0;
> +
> size_t ns1 = strlen (s1) + 1;
> size_t ns2 = strlen (s2) + 1;
> size_t n = ns1 < ns2 ? ns1 : ns2;
> +
> if (n > max)
> n = max;
> int ret = 0;
> @@ -258,6 +262,16 @@ bz14195 (void)
> }
>
> static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointers to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size),
> + (char *) (buf1 + BUF1PAGES * page_size), 0, 0);
> +}
> +
> +static void
> test_locale (const char *locale)
> {
> size_t i;
> @@ -270,6 +284,7 @@ test_locale (const char *locale)
>
> bz12205 ();
> bz14195 ();
> + do_test_zero_length ();
>
> printf ("%23s", locale);
> FOR_EACH_IMPL (impl, 0)
> diff --git a/string/test-strncat.c b/string/test-strncat.c
> index 4915c59..4eef967 100644
> --- a/string/test-strncat.c
> +++ b/string/test-strncat.c
> @@ -31,6 +31,10 @@ char *
> stupid_strncat (char *dst, const char *src, size_t n)
> {
> char *ret = dst;
> +
> + if (n == 0)
> + return ret;
> +
> while (*dst++ != '\0');
> --dst;
> while (n--)
> @@ -232,6 +236,25 @@ do_random_tests (void)
> }
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + char dst[1];
> + char *src = (char *) (buf2 + page_size);
> + dst[0] = '\0';
> +
> + /* Test for behaviour with zero length and pointer to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + if (CALL (impl, dst, src, 0) != dst)
> + {
> + error (0, 0, "Wrong result in function %s %p != %p", impl->name,
> + CALL (impl, dst, src, 0), dst);
> + ret = 1;
> + return;
> + }
> +}
> +
> int
> main (void)
> {
> @@ -269,5 +292,6 @@ main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
> diff --git a/string/test-strncmp.c b/string/test-strncmp.c
> index f3b2c68..225bab5 100644
> --- a/string/test-strncmp.c
> +++ b/string/test-strncmp.c
> @@ -317,6 +317,16 @@ check2 (void)
> free (s2);
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointers to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size),
> + (char *) (buf1 + BUF1PAGES * page_size), 0, 0);
> +}
> +
> int
> test_main (void)
> {
> @@ -387,6 +397,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> diff --git a/string/test-strncpy.c b/string/test-strncpy.c
> index 2326acc..455da43 100644
> --- a/string/test-strncpy.c
> +++ b/string/test-strncpy.c
> @@ -245,6 +245,16 @@ do_random_tests (void)
> }
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointers to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size),
> + (char *) (buf1 + BUF1PAGES * page_size), 0, 0);
> +}
> +
> int
> test_main (void)
> {
> @@ -278,6 +288,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> diff --git a/string/test-strnlen.c b/string/test-strnlen.c
> index be9edd2..c8fd05a 100644
> --- a/string/test-strnlen.c
> +++ b/string/test-strnlen.c
> @@ -122,6 +122,15 @@ do_random_tests (void)
> }
> }
>
> +static void
> +do_test_zero_length (void)
> +{
> + /* Test for behaviour with zero length and pointer to PROT_NONE
> + memory. */
> + FOR_EACH_IMPL (impl, 0)
> + do_one_test (impl, (char *) (buf2 + page_size), 0, 0);
> +}
> +
> int
> test_main (void)
> {
> @@ -167,6 +176,7 @@ test_main (void)
> }
>
> do_random_tests ();
> + do_test_zero_length ();
> return ret;
> }
>
> --
> 1.9.3
>
--
Will Newton
Toolchain Working Group, Linaro