On Fri, Feb 10, 2017 at 4:36 PM, Luis R. Rodriguez <mcg...@kernel.org> wrote:
> Add a few initial respective tests for an array:
>
>   o Echoing values separated by spaces works
>   o Echoing only first elements will set first elements
>   o Confirm PAGE_SIZE limit still applies even if an array is used
>
> Signed-off-by: Luis R. Rodriguez <mcg...@kernel.org>
> ---
>  lib/test_sysctl.c                        | 13 +++++
>  tools/testing/selftests/sysctl/sysctl.sh | 89 
> ++++++++++++++++++++++++++++++++
>  2 files changed, 102 insertions(+)
>
> diff --git a/lib/test_sysctl.c b/lib/test_sysctl.c
> index 1654f41961b7..603c24b2f6cb 100644
> --- a/lib/test_sysctl.c
> +++ b/lib/test_sysctl.c
> @@ -35,6 +35,7 @@ static int i_one_hundred = 100;
>  struct test_sysctl_data {
>         int int_0001;
>         int int_0002;
> +       int int_0003[4];
>
>         unsigned int uint_0001;
>
> @@ -45,6 +46,11 @@ static struct test_sysctl_data test_data = {
>         .int_0001 = 60,
>         .int_0002 = 1,
>
> +       .int_0003[0] = 0,
> +       .int_0003[1] = 1,
> +       .int_0003[2] = 2,
> +       .int_0003[3] = 3,
> +
>         .uint_0001 = 314,
>
>         .string_0001 = "(none)",
> @@ -69,6 +75,13 @@ static struct ctl_table test_table[] = {
>                 .proc_handler   = proc_dointvec,
>         },
>         {
> +               .procname       = "int_0003",
> +               .data           = &test_data.int_0003,
> +               .maxlen         = sizeof(test_data.int_0003),
> +               .mode           = 0644,
> +               .proc_handler   = proc_dointvec,
> +       },
> +       {
>                 .procname       = "uint_0001",
>                 .data           = &test_data.uint_0001,
>                 .maxlen         = sizeof(unsigned int),
> diff --git a/tools/testing/selftests/sysctl/sysctl.sh 
> b/tools/testing/selftests/sysctl/sysctl.sh
> index eedfba6f0a57..963d572155b1 100755
> --- a/tools/testing/selftests/sysctl/sysctl.sh
> +++ b/tools/testing/selftests/sysctl/sysctl.sh
> @@ -26,6 +26,7 @@ ALL_TESTS="0001:1:1"
>  ALL_TESTS="$ALL_TESTS 0002:1:1"
>  ALL_TESTS="$ALL_TESTS 0003:1:1"
>  ALL_TESTS="$ALL_TESTS 0004:1:1"
> +ALL_TESTS="$ALL_TESTS 0005:3:1"
>
>  test_modprobe()
>  {
> @@ -78,6 +79,10 @@ test_reqs()
>                 echo "$0: You need getconf installed"
>                 exit 1
>         fi
> +       if ! which diff 2> /dev/null > /dev/null; then
> +               echo "$0: You need diff installed"
> +               exit 1
> +       fi
>  }
>
>  function load_req_mod()
> @@ -137,6 +142,12 @@ verify()
>         return 0
>  }
>
> +verify_diff_w()
> +{
> +       echo "$TEST_STR" | diff -w -u - $1 2>&1 > /dev/null

Instead of shell redirection, just use -q ?

> +       return $?
> +}
> +
>  test_rc()
>  {
>         if [[ $rc != 0 ]]; then
> @@ -317,6 +328,74 @@ run_limit_digit_int()
>         test_rc
>  }
>
> +# You used an int array
> +run_limit_digit_int_array()
> +{
> +       echo -n "Testing array works as expected ... "
> +       TEST_STR="4 3 2 1"
> +       echo -n $TEST_STR > $TARGET
> +
> +       if ! verify_diff_w "${TARGET}"; then
> +               echo "FAIL" >&2
> +               rc=1
> +       else
> +               echo "ok"
> +       fi
> +       test_rc
> +
> +       echo -n "Testing skipping trailing array elements works ... "
> +       # Do not reset_vals, carry on the values from the last test.
> +       # If we only echo in two digits the last two are left intact
> +       TEST_STR="100 101"
> +       echo -n $TEST_STR > $TARGET
> +       # After we echo in, to help diff we need to set on TEST_STR what
> +       # we expect the result to be.
> +       TEST_STR="100 101 2 1"
> +
> +       if ! verify_diff_w "${TARGET}"; then
> +               echo "FAIL" >&2
> +               rc=1
> +       else
> +               echo "ok"
> +       fi
> +       test_rc
> +
> +       echo -n "Testing PAGE_SIZE limit on array works ... "
> +       # Do not reset_vals, carry on the values from the last test.
> +       # Even if you use an int array, you are still restricted to
> +       # MAX_DIGITS, this is a known limitation. Test limit works.
> +       LIMIT=$((MAX_DIGITS -1))
> +       TEST_STR="9"
> +       (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
> +               dd of="${TARGET}" 2>/dev/null
> +
> +       TEST_STR="9 101 2 1"
> +       if ! verify_diff_w "${TARGET}"; then
> +               echo "FAIL" >&2
> +               rc=1
> +       else
> +               echo "ok"
> +       fi
> +       test_rc
> +
> +       echo -n "Testing exceeding PAGE_SIZE limit fails as expected ... "
> +       # Do not reset_vals, carry on the values from the last test.
> +       # Now go over limit.
> +       LIMIT=$((MAX_DIGITS))
> +       TEST_STR="7"
> +       (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
> +               dd of="${TARGET}" 2>/dev/null
> +
> +       TEST_STR="7 101 2 1"
> +       if verify_diff_w "${TARGET}"; then
> +               echo "FAIL" >&2
> +               rc=1
> +       else
> +               echo "ok"
> +       fi
> +       test_rc
> +}
> +
>  # You are using an unsigned int
>  run_limit_digit_uint()
>  {
> @@ -477,6 +556,15 @@ sysctl_test_0004()
>         run_limit_digit_uint
>  }
>
> +sysctl_test_0005()
> +{
> +       TARGET="${SYSCTL}/int_0003"
> +       reset_vals
> +       ORIG=$(cat "${TARGET}")
> +
> +       run_limit_digit_int_array
> +}
> +
>  list_tests()
>  {
>         echo "Test ID list:"
> @@ -489,6 +577,7 @@ list_tests()
>         echo "0002 x $(get_test_count 0002) - tests proc_dostring()"
>         echo "0003 x $(get_test_count 0003) - tests proc_dointvec()"
>         echo "0004 x $(get_test_count 0004) - tests proc_douintvec()"
> +       echo "0005 x $(get_test_count 0005) - tests proc_douintvec() array"
>  }
>
>  test_reqs
> --
> 2.11.0
>

I love seeing these tests added. I have one other change I'd like to
add to sysctl, but I haven't had time to make sure it doesn't break
stuff. I haven't been able to prove it to myself, but I think it's
safe; I just need to update the tests to handle it:

http://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/commit/?h=sysctl/writes_strict&id=b63a38ca45bd9fb61545ce6ce66093147eb96a7c

It'd need an update for the uint handler...

-Kees

-- 
Kees Cook
Pixel Security

Reply via email to