aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2014-06-06 17:37:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-06 19:08:13 -0400
commit24fe831c17ab8149413874f2fd4e5c8a41fcd294 (patch)
tree8dfd55de2ff614c628b80e2182ad932e87a83aeb /tools/testing
parentf4aacea2f5d1a5f7e3154e967d70cf3f711bcd61 (diff)
tools/testing/selftests/sysctl: validate sysctl_writes_strict
This adds several behavioral tests to sysctl string and number writing to detect unexpected cases that behaved differently when the sysctl kernel.sysctl_writes_strict != 1. [ original ] root@localhost:~# make test_num == Testing sysctl behavior against /proc/sys/kernel/domainname == Writing test file ... ok Checking sysctl is not set to test value ... ok Writing sysctl from shell ... ok Resetting sysctl to original value ... ok Writing entire sysctl in single write ... ok Writing middle of sysctl after synchronized seek ... FAIL Writing beyond end of sysctl ... FAIL Writing sysctl with multiple long writes ... FAIL Writing entire sysctl in short writes ... FAIL Writing middle of sysctl after unsynchronized seek ... ok Checking sysctl maxlen is at least 65 ... ok Checking sysctl keeps original string on overflow append ... FAIL Checking sysctl stays NULL terminated on write ... ok Checking sysctl stays NULL terminated on overwrite ... ok make: *** [test_num] Error 1 root@localhost:~# make test_string == Testing sysctl behavior against /proc/sys/vm/swappiness == Writing test file ... ok Checking sysctl is not set to test value ... ok Writing sysctl from shell ... ok Resetting sysctl to original value ... ok Writing entire sysctl in single write ... ok Writing middle of sysctl after synchronized seek ... FAIL Writing beyond end of sysctl ... FAIL Writing sysctl with multiple long writes ... ok make: *** [test_string] Error 1 [ with CONFIG_PROC_SYSCTL_STRICT_WRITES ] root@localhost:~# make run_tests == Testing sysctl behavior against /proc/sys/kernel/domainname == Writing test file ... ok Checking sysctl is not set to test value ... ok Writing sysctl from shell ... ok Resetting sysctl to original value ... ok Writing entire sysctl in single write ... ok Writing middle of sysctl after synchronized seek ... ok Writing beyond end of sysctl ... ok Writing sysctl with multiple long writes ... ok Writing entire sysctl in short writes ... ok Writing middle of sysctl after unsynchronized seek ... ok Checking sysctl maxlen is at least 65 ... ok Checking sysctl keeps original string on overflow append ... ok Checking sysctl stays NULL terminated on write ... ok Checking sysctl stays NULL terminated on overwrite ... ok == Testing sysctl behavior against /proc/sys/vm/swappiness == Writing test file ... ok Checking sysctl is not set to test value ... ok Writing sysctl from shell ... ok Resetting sysctl to original value ... ok Writing entire sysctl in single write ... ok Writing middle of sysctl after synchronized seek ... ok Writing beyond end of sysctl ... ok Writing sysctl with multiple long writes ... ok Signed-off-by: Kees Cook <keescook@chromium.org> Cc: Randy Dunlap <rdunlap@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools/testing')
-rw-r--r--tools/testing/selftests/Makefile1
-rw-r--r--tools/testing/selftests/sysctl/Makefile19
-rw-r--r--tools/testing/selftests/sysctl/common_tests109
-rw-r--r--tools/testing/selftests/sysctl/run_numerictests10
-rw-r--r--tools/testing/selftests/sysctl/run_stringtests77
5 files changed, 216 insertions, 0 deletions
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 32487ed18354..e66e710cc595 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -10,6 +10,7 @@ TARGETS += timers
10TARGETS += vm 10TARGETS += vm
11TARGETS += powerpc 11TARGETS += powerpc
12TARGETS += user 12TARGETS += user
13TARGETS += sysctl
13 14
14all: 15all:
15 for TARGET in $(TARGETS); do \ 16 for TARGET in $(TARGETS); do \
diff --git a/tools/testing/selftests/sysctl/Makefile b/tools/testing/selftests/sysctl/Makefile
new file mode 100644
index 000000000000..0a92adaf0865
--- /dev/null
+++ b/tools/testing/selftests/sysctl/Makefile
@@ -0,0 +1,19 @@
1# Makefile for sysctl selftests.
2# Expects kernel.sysctl_writes_strict=1.
3
4# No binaries, but make sure arg-less "make" doesn't trigger "run_tests".
5all:
6
7# Allow specific tests to be selected.
8test_num:
9 @/bin/sh ./run_numerictests
10
11test_string:
12 @/bin/sh ./run_stringtests
13
14run_tests: all test_num test_string
15
16# Nothing to clean up.
17clean:
18
19.PHONY: all run_tests clean test_num test_string
diff --git a/tools/testing/selftests/sysctl/common_tests b/tools/testing/selftests/sysctl/common_tests
new file mode 100644
index 000000000000..17d534b1b7b4
--- /dev/null
+++ b/tools/testing/selftests/sysctl/common_tests
@@ -0,0 +1,109 @@
1#!/bin/sh
2
3TEST_FILE=$(mktemp)
4
5echo "== Testing sysctl behavior against ${TARGET} =="
6
7set_orig()
8{
9 echo "${ORIG}" > "${TARGET}"
10}
11
12set_test()
13{
14 echo "${TEST_STR}" > "${TARGET}"
15}
16
17verify()
18{
19 local seen
20 seen=$(cat "$1")
21 if [ "${seen}" != "${TEST_STR}" ]; then
22 return 1
23 fi
24 return 0
25}
26
27trap 'set_orig; rm -f "${TEST_FILE}"' EXIT
28
29rc=0
30
31echo -n "Writing test file ... "
32echo "${TEST_STR}" > "${TEST_FILE}"
33if ! verify "${TEST_FILE}"; then
34 echo "FAIL" >&2
35 exit 1
36else
37 echo "ok"
38fi
39
40echo -n "Checking sysctl is not set to test value ... "
41if verify "${TARGET}"; then
42 echo "FAIL" >&2
43 exit 1
44else
45 echo "ok"
46fi
47
48echo -n "Writing sysctl from shell ... "
49set_test
50if ! verify "${TARGET}"; then
51 echo "FAIL" >&2
52 exit 1
53else
54 echo "ok"
55fi
56
57echo -n "Resetting sysctl to original value ... "
58set_orig
59if verify "${TARGET}"; then
60 echo "FAIL" >&2
61 exit 1
62else
63 echo "ok"
64fi
65
66# Now that we've validated the sanity of "set_test" and "set_orig",
67# we can use those functions to set starting states before running
68# specific behavioral tests.
69
70echo -n "Writing entire sysctl in single write ... "
71set_orig
72dd if="${TEST_FILE}" of="${TARGET}" bs=4096 2>/dev/null
73if ! verify "${TARGET}"; then
74 echo "FAIL" >&2
75 rc=1
76else
77 echo "ok"
78fi
79
80echo -n "Writing middle of sysctl after synchronized seek ... "
81set_test
82dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 skip=1 2>/dev/null
83if ! verify "${TARGET}"; then
84 echo "FAIL" >&2
85 rc=1
86else
87 echo "ok"
88fi
89
90echo -n "Writing beyond end of sysctl ... "
91set_orig
92dd if="${TEST_FILE}" of="${TARGET}" bs=20 seek=2 2>/dev/null
93if verify "${TARGET}"; then
94 echo "FAIL" >&2
95 rc=1
96else
97 echo "ok"
98fi
99
100echo -n "Writing sysctl with multiple long writes ... "
101set_orig
102(perl -e 'print "A" x 50;'; echo "${TEST_STR}") | \
103 dd of="${TARGET}" bs=50 2>/dev/null
104if verify "${TARGET}"; then
105 echo "FAIL" >&2
106 rc=1
107else
108 echo "ok"
109fi
diff --git a/tools/testing/selftests/sysctl/run_numerictests b/tools/testing/selftests/sysctl/run_numerictests
new file mode 100644
index 000000000000..8510f93f2d14
--- /dev/null
+++ b/tools/testing/selftests/sysctl/run_numerictests
@@ -0,0 +1,10 @@
1#!/bin/sh
2
3SYSCTL="/proc/sys"
4TARGET="${SYSCTL}/vm/swappiness"
5ORIG=$(cat "${TARGET}")
6TEST_STR=$(( $ORIG + 1 ))
7
8. ./common_tests
9
10exit $rc
diff --git a/tools/testing/selftests/sysctl/run_stringtests b/tools/testing/selftests/sysctl/run_stringtests
new file mode 100644
index 000000000000..90a9293d520c
--- /dev/null
+++ b/tools/testing/selftests/sysctl/run_stringtests
@@ -0,0 +1,77 @@
1#!/bin/sh
2
3SYSCTL="/proc/sys"
4TARGET="${SYSCTL}/kernel/domainname"
5ORIG=$(cat "${TARGET}")
6TEST_STR="Testing sysctl"
7
8. ./common_tests
9
10# Only string sysctls support seeking/appending.
11MAXLEN=65
12
13echo -n "Writing entire sysctl in short writes ... "
14set_orig
15dd if="${TEST_FILE}" of="${TARGET}" bs=1 2>/dev/null
16if ! verify "${TARGET}"; then
17 echo "FAIL" >&2
18 rc=1
19else
20 echo "ok"
21fi
22
23echo -n "Writing middle of sysctl after unsynchronized seek ... "
24set_test
25dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 2>/dev/null
26if verify "${TARGET}"; then
27 echo "FAIL" >&2
28 rc=1
29else
30 echo "ok"
31fi
32
33echo -n "Checking sysctl maxlen is at least $MAXLEN ... "
34set_orig
35perl -e 'print "A" x ('"${MAXLEN}"'-2), "B";' | \
36 dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null
37if ! grep -q B "${TARGET}"; then
38 echo "FAIL" >&2
39 rc=1
40else
41 echo "ok"
42fi
43
44echo -n "Checking sysctl keeps original string on overflow append ... "
45set_orig
46perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \
47 dd of="${TARGET}" bs=$(( MAXLEN - 1 )) 2>/dev/null
48if grep -q B "${TARGET}"; then
49 echo "FAIL" >&2
50 rc=1
51else
52 echo "ok"
53fi
54
55echo -n "Checking sysctl stays NULL terminated on write ... "
56set_orig
57perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \
58 dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null
59if grep -q B "${TARGET}"; then
60 echo "FAIL" >&2
61 rc=1
62else
63 echo "ok"
64fi
65
66echo -n "Checking sysctl stays NULL terminated on overwrite ... "
67set_orig
68perl -e 'print "A" x ('"${MAXLEN}"'-1), "BB";' | \
69 dd of="${TARGET}" bs=$(( $MAXLEN + 1 )) 2>/dev/null
70if grep -q B "${TARGET}"; then
71 echo "FAIL" >&2
72 rc=1
73else
74 echo "ok"
75fi
76
77exit $rc