1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Kernel module for testing 'strscpy' family of functions. |
4 | */ |
5 | |
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
7 | |
8 | #include <kunit/test.h> |
9 | #include <linux/string.h> |
10 | |
11 | /* |
12 | * tc() - Run a specific test case. |
13 | * @src: Source string, argument to strscpy_pad() |
14 | * @count: Size of destination buffer, argument to strscpy_pad() |
15 | * @expected: Expected return value from call to strscpy_pad() |
16 | * @terminator: 1 if there should be a terminating null byte 0 otherwise. |
17 | * @chars: Number of characters from the src string expected to be |
18 | * written to the dst buffer. |
19 | * @pad: Number of pad characters expected (in the tail of dst buffer). |
20 | * (@pad does not include the null terminator byte.) |
21 | * |
22 | * Calls strscpy_pad() and verifies the return value and state of the |
23 | * destination buffer after the call returns. |
24 | */ |
25 | static void tc(struct kunit *test, char *src, int count, int expected, |
26 | int chars, int terminator, int pad) |
27 | { |
28 | int nr_bytes_poison; |
29 | int max_expected; |
30 | int max_count; |
31 | int written; |
32 | char buf[6]; |
33 | int index, i; |
34 | const char POISON = 'z'; |
35 | |
36 | KUNIT_ASSERT_TRUE_MSG(test, src != NULL, |
37 | "null source string not supported" ); |
38 | |
39 | memset(buf, POISON, sizeof(buf)); |
40 | /* Future proofing test suite, validate args */ |
41 | max_count = sizeof(buf) - 2; /* Space for null and to verify overflow */ |
42 | max_expected = count - 1; /* Space for the null */ |
43 | |
44 | KUNIT_ASSERT_LE_MSG(test, count, max_count, |
45 | "count (%d) is too big (%d) ... aborting" , count, max_count); |
46 | KUNIT_EXPECT_LE_MSG(test, expected, max_expected, |
47 | "expected (%d) is bigger than can possibly be returned (%d)" , |
48 | expected, max_expected); |
49 | |
50 | written = strscpy_pad(dest: buf, src, count); |
51 | KUNIT_ASSERT_EQ(test, written, expected); |
52 | |
53 | if (count && written == -E2BIG) { |
54 | KUNIT_ASSERT_EQ_MSG(test, 0, strncmp(buf, src, count - 1), |
55 | "buffer state invalid for -E2BIG" ); |
56 | KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', |
57 | "too big string is not null terminated correctly" ); |
58 | } |
59 | |
60 | for (i = 0; i < chars; i++) |
61 | KUNIT_ASSERT_EQ_MSG(test, buf[i], src[i], |
62 | "buf[i]==%c != src[i]==%c" , buf[i], src[i]); |
63 | |
64 | if (terminator) |
65 | KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', |
66 | "string is not null terminated correctly" ); |
67 | |
68 | for (i = 0; i < pad; i++) { |
69 | index = chars + terminator + i; |
70 | KUNIT_ASSERT_EQ_MSG(test, buf[index], '\0', |
71 | "padding missing at index: %d" , i); |
72 | } |
73 | |
74 | nr_bytes_poison = sizeof(buf) - chars - terminator - pad; |
75 | for (i = 0; i < nr_bytes_poison; i++) { |
76 | index = sizeof(buf) - 1 - i; /* Check from the end back */ |
77 | KUNIT_ASSERT_EQ_MSG(test, buf[index], POISON, |
78 | "poison value missing at index: %d" , i); |
79 | } |
80 | } |
81 | |
82 | static void strscpy_test(struct kunit *test) |
83 | { |
84 | char dest[8]; |
85 | |
86 | /* |
87 | * tc() uses a destination buffer of size 6 and needs at |
88 | * least 2 characters spare (one for null and one to check for |
89 | * overflow). This means we should only call tc() with |
90 | * strings up to a maximum of 4 characters long and 'count' |
91 | * should not exceed 4. To test with longer strings increase |
92 | * the buffer size in tc(). |
93 | */ |
94 | |
95 | /* tc(test, src, count, expected, chars, terminator, pad) */ |
96 | tc(test, src: "a" , count: 0, expected: -E2BIG, chars: 0, terminator: 0, pad: 0); |
97 | tc(test, src: "" , count: 0, expected: -E2BIG, chars: 0, terminator: 0, pad: 0); |
98 | |
99 | tc(test, src: "a" , count: 1, expected: -E2BIG, chars: 0, terminator: 1, pad: 0); |
100 | tc(test, src: "" , count: 1, expected: 0, chars: 0, terminator: 1, pad: 0); |
101 | |
102 | tc(test, src: "ab" , count: 2, expected: -E2BIG, chars: 1, terminator: 1, pad: 0); |
103 | tc(test, src: "a" , count: 2, expected: 1, chars: 1, terminator: 1, pad: 0); |
104 | tc(test, src: "" , count: 2, expected: 0, chars: 0, terminator: 1, pad: 1); |
105 | |
106 | tc(test, src: "abc" , count: 3, expected: -E2BIG, chars: 2, terminator: 1, pad: 0); |
107 | tc(test, src: "ab" , count: 3, expected: 2, chars: 2, terminator: 1, pad: 0); |
108 | tc(test, src: "a" , count: 3, expected: 1, chars: 1, terminator: 1, pad: 1); |
109 | tc(test, src: "" , count: 3, expected: 0, chars: 0, terminator: 1, pad: 2); |
110 | |
111 | tc(test, src: "abcd" , count: 4, expected: -E2BIG, chars: 3, terminator: 1, pad: 0); |
112 | tc(test, src: "abc" , count: 4, expected: 3, chars: 3, terminator: 1, pad: 0); |
113 | tc(test, src: "ab" , count: 4, expected: 2, chars: 2, terminator: 1, pad: 1); |
114 | tc(test, src: "a" , count: 4, expected: 1, chars: 1, terminator: 1, pad: 2); |
115 | tc(test, src: "" , count: 4, expected: 0, chars: 0, terminator: 1, pad: 3); |
116 | |
117 | /* Compile-time-known source strings. */ |
118 | KUNIT_EXPECT_EQ(test, strscpy(dest, "" , ARRAY_SIZE(dest)), 0); |
119 | KUNIT_EXPECT_EQ(test, strscpy(dest, "" , 3), 0); |
120 | KUNIT_EXPECT_EQ(test, strscpy(dest, "" , 1), 0); |
121 | KUNIT_EXPECT_EQ(test, strscpy(dest, "" , 0), -E2BIG); |
122 | KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed" , ARRAY_SIZE(dest)), 5); |
123 | KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed" , 3), -E2BIG); |
124 | KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed" , 1), -E2BIG); |
125 | KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed" , 0), -E2BIG); |
126 | KUNIT_EXPECT_EQ(test, strscpy(dest, "This is too long" , ARRAY_SIZE(dest)), -E2BIG); |
127 | } |
128 | |
129 | static struct kunit_case strscpy_test_cases[] = { |
130 | KUNIT_CASE(strscpy_test), |
131 | {} |
132 | }; |
133 | |
134 | static struct kunit_suite strscpy_test_suite = { |
135 | .name = "strscpy" , |
136 | .test_cases = strscpy_test_cases, |
137 | }; |
138 | |
139 | kunit_test_suite(strscpy_test_suite); |
140 | |
141 | MODULE_AUTHOR("Tobin C. Harding <tobin@kernel.org>" ); |
142 | MODULE_LICENSE("GPL" ); |
143 | |