1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * KUnit test of proc sysctl. 3 * KUnit test of proc sysctl. 4 */ 4 */ 5 5 6 #include <kunit/test.h> 6 #include <kunit/test.h> 7 #include <linux/sysctl.h> 7 #include <linux/sysctl.h> 8 8 9 #define KUNIT_PROC_READ 0 9 #define KUNIT_PROC_READ 0 10 #define KUNIT_PROC_WRITE 1 10 #define KUNIT_PROC_WRITE 1 11 11 12 /* 12 /* 13 * Test that proc_dointvec will not try to use 13 * Test that proc_dointvec will not try to use a NULL .data field even when the 14 * length is non-zero. 14 * length is non-zero. 15 */ 15 */ 16 static void sysctl_test_api_dointvec_null_tbl_ 16 static void sysctl_test_api_dointvec_null_tbl_data(struct kunit *test) 17 { 17 { 18 struct ctl_table null_data_table = { 18 struct ctl_table null_data_table = { 19 .procname = "foo", 19 .procname = "foo", 20 /* 20 /* 21 * Here we are testing that pr 21 * Here we are testing that proc_dointvec behaves correctly when 22 * we give it a NULL .data fie 22 * we give it a NULL .data field. Normally this would point to a 23 * piece of memory where the v 23 * piece of memory where the value would be stored. 24 */ 24 */ 25 .data = NULL, 25 .data = NULL, 26 .maxlen = sizeof(int), 26 .maxlen = sizeof(int), 27 .mode = 0644, 27 .mode = 0644, 28 .proc_handler = proc_dointve 28 .proc_handler = proc_dointvec, 29 .extra1 = SYSCTL_ZERO, 29 .extra1 = SYSCTL_ZERO, 30 .extra2 = SYSCTL_ONE_H 30 .extra2 = SYSCTL_ONE_HUNDRED, 31 }; 31 }; 32 /* 32 /* 33 * proc_dointvec expects a buffer in u 33 * proc_dointvec expects a buffer in user space, so we allocate one. We 34 * also need to cast it to __user so s 34 * also need to cast it to __user so sparse doesn't get mad. 35 */ 35 */ 36 void __user *buffer = (void __user *)k 36 void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int), 37 37 GFP_USER); 38 size_t len; 38 size_t len; 39 loff_t pos; 39 loff_t pos; 40 40 41 /* 41 /* 42 * We don't care what the starting len 42 * We don't care what the starting length is since proc_dointvec should 43 * not try to read because .data is NU 43 * not try to read because .data is NULL. 44 */ 44 */ 45 len = 1234; 45 len = 1234; 46 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 46 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&null_data_table, 47 47 KUNIT_PROC_READ, buffer, &len, 48 48 &pos)); 49 KUNIT_EXPECT_EQ(test, 0, len); 49 KUNIT_EXPECT_EQ(test, 0, len); 50 50 51 /* 51 /* 52 * See above. 52 * See above. 53 */ 53 */ 54 len = 1234; 54 len = 1234; 55 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 55 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&null_data_table, 56 56 KUNIT_PROC_WRITE, buffer, &len, 57 57 &pos)); 58 KUNIT_EXPECT_EQ(test, 0, len); 58 KUNIT_EXPECT_EQ(test, 0, len); 59 } 59 } 60 60 61 /* 61 /* 62 * Similar to the previous test, we create a s 62 * Similar to the previous test, we create a struct ctrl_table that has a .data 63 * field that proc_dointvec cannot do anything 63 * field that proc_dointvec cannot do anything with; however, this time it is 64 * because we tell proc_dointvec that the size 64 * because we tell proc_dointvec that the size is 0. 65 */ 65 */ 66 static void sysctl_test_api_dointvec_table_max 66 static void sysctl_test_api_dointvec_table_maxlen_unset(struct kunit *test) 67 { 67 { 68 int data = 0; 68 int data = 0; 69 struct ctl_table data_maxlen_unset_tab 69 struct ctl_table data_maxlen_unset_table = { 70 .procname = "foo", 70 .procname = "foo", 71 .data = &data, 71 .data = &data, 72 /* 72 /* 73 * So .data is no longer NULL, 73 * So .data is no longer NULL, but we tell proc_dointvec its 74 * length is 0, so it still sh 74 * length is 0, so it still shouldn't try to use it. 75 */ 75 */ 76 .maxlen = 0, 76 .maxlen = 0, 77 .mode = 0644, 77 .mode = 0644, 78 .proc_handler = proc_dointve 78 .proc_handler = proc_dointvec, 79 .extra1 = SYSCTL_ZERO, 79 .extra1 = SYSCTL_ZERO, 80 .extra2 = SYSCTL_ONE_H 80 .extra2 = SYSCTL_ONE_HUNDRED, 81 }; 81 }; 82 void __user *buffer = (void __user *)k 82 void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int), 83 83 GFP_USER); 84 size_t len; 84 size_t len; 85 loff_t pos; 85 loff_t pos; 86 86 87 /* 87 /* 88 * As before, we don't care what buffe 88 * As before, we don't care what buffer length is because proc_dointvec 89 * cannot do anything because its inte 89 * cannot do anything because its internal .data buffer has zero length. 90 */ 90 */ 91 len = 1234; 91 len = 1234; 92 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 92 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&data_maxlen_unset_table, 93 93 KUNIT_PROC_READ, buffer, &len, 94 94 &pos)); 95 KUNIT_EXPECT_EQ(test, 0, len); 95 KUNIT_EXPECT_EQ(test, 0, len); 96 96 97 /* 97 /* 98 * See previous comment. 98 * See previous comment. 99 */ 99 */ 100 len = 1234; 100 len = 1234; 101 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 101 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&data_maxlen_unset_table, 102 102 KUNIT_PROC_WRITE, buffer, &len, 103 103 &pos)); 104 KUNIT_EXPECT_EQ(test, 0, len); 104 KUNIT_EXPECT_EQ(test, 0, len); 105 } 105 } 106 106 107 /* 107 /* 108 * Here we provide a valid struct ctl_table, b 108 * Here we provide a valid struct ctl_table, but we try to read and write from 109 * it using a buffer of zero length, so it sho 109 * it using a buffer of zero length, so it should still fail in a similar way as 110 * before. 110 * before. 111 */ 111 */ 112 static void sysctl_test_api_dointvec_table_len 112 static void sysctl_test_api_dointvec_table_len_is_zero(struct kunit *test) 113 { 113 { 114 int data = 0; 114 int data = 0; 115 /* Good table. */ 115 /* Good table. */ 116 struct ctl_table table = { 116 struct ctl_table table = { 117 .procname = "foo", 117 .procname = "foo", 118 .data = &data, 118 .data = &data, 119 .maxlen = sizeof(int), 119 .maxlen = sizeof(int), 120 .mode = 0644, 120 .mode = 0644, 121 .proc_handler = proc_dointve 121 .proc_handler = proc_dointvec, 122 .extra1 = SYSCTL_ZERO, 122 .extra1 = SYSCTL_ZERO, 123 .extra2 = SYSCTL_ONE_H 123 .extra2 = SYSCTL_ONE_HUNDRED, 124 }; 124 }; 125 void __user *buffer = (void __user *)k 125 void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int), 126 126 GFP_USER); 127 /* 127 /* 128 * However, now our read/write buffer 128 * However, now our read/write buffer has zero length. 129 */ 129 */ 130 size_t len = 0; 130 size_t len = 0; 131 loff_t pos; 131 loff_t pos; 132 132 133 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 133 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, KUNIT_PROC_READ, buffer, 134 134 &len, &pos)); 135 KUNIT_EXPECT_EQ(test, 0, len); 135 KUNIT_EXPECT_EQ(test, 0, len); 136 136 137 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 137 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, KUNIT_PROC_WRITE, buffer, 138 138 &len, &pos)); 139 KUNIT_EXPECT_EQ(test, 0, len); 139 KUNIT_EXPECT_EQ(test, 0, len); 140 } 140 } 141 141 142 /* 142 /* 143 * Test that proc_dointvec refuses to read whe 143 * Test that proc_dointvec refuses to read when the file position is non-zero. 144 */ 144 */ 145 static void sysctl_test_api_dointvec_table_rea 145 static void sysctl_test_api_dointvec_table_read_but_position_set( 146 struct kunit *test) 146 struct kunit *test) 147 { 147 { 148 int data = 0; 148 int data = 0; 149 /* Good table. */ 149 /* Good table. */ 150 struct ctl_table table = { 150 struct ctl_table table = { 151 .procname = "foo", 151 .procname = "foo", 152 .data = &data, 152 .data = &data, 153 .maxlen = sizeof(int), 153 .maxlen = sizeof(int), 154 .mode = 0644, 154 .mode = 0644, 155 .proc_handler = proc_dointve 155 .proc_handler = proc_dointvec, 156 .extra1 = SYSCTL_ZERO, 156 .extra1 = SYSCTL_ZERO, 157 .extra2 = SYSCTL_ONE_H 157 .extra2 = SYSCTL_ONE_HUNDRED, 158 }; 158 }; 159 void __user *buffer = (void __user *)k 159 void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int), 160 160 GFP_USER); 161 /* 161 /* 162 * We don't care about our buffer leng 162 * We don't care about our buffer length because we start off with a 163 * non-zero file position. 163 * non-zero file position. 164 */ 164 */ 165 size_t len = 1234; 165 size_t len = 1234; 166 /* 166 /* 167 * proc_dointvec should refuse to read 167 * proc_dointvec should refuse to read into the buffer since the file 168 * pos is non-zero. 168 * pos is non-zero. 169 */ 169 */ 170 loff_t pos = 1; 170 loff_t pos = 1; 171 171 172 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 172 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, KUNIT_PROC_READ, buffer, 173 173 &len, &pos)); 174 KUNIT_EXPECT_EQ(test, 0, len); 174 KUNIT_EXPECT_EQ(test, 0, len); 175 } 175 } 176 176 177 /* 177 /* 178 * Test that we can read a two digit number in 178 * Test that we can read a two digit number in a sufficiently size buffer. 179 * Nothing fancy. 179 * Nothing fancy. 180 */ 180 */ 181 static void sysctl_test_dointvec_read_happy_si 181 static void sysctl_test_dointvec_read_happy_single_positive(struct kunit *test) 182 { 182 { 183 int data = 0; 183 int data = 0; 184 /* Good table. */ 184 /* Good table. */ 185 struct ctl_table table = { 185 struct ctl_table table = { 186 .procname = "foo", 186 .procname = "foo", 187 .data = &data, 187 .data = &data, 188 .maxlen = sizeof(int), 188 .maxlen = sizeof(int), 189 .mode = 0644, 189 .mode = 0644, 190 .proc_handler = proc_dointve 190 .proc_handler = proc_dointvec, 191 .extra1 = SYSCTL_ZERO, 191 .extra1 = SYSCTL_ZERO, 192 .extra2 = SYSCTL_ONE_H 192 .extra2 = SYSCTL_ONE_HUNDRED, 193 }; 193 }; 194 size_t len = 4; 194 size_t len = 4; 195 loff_t pos = 0; 195 loff_t pos = 0; 196 char *buffer = kunit_kzalloc(test, len 196 char *buffer = kunit_kzalloc(test, len, GFP_USER); 197 char __user *user_buffer = (char __use 197 char __user *user_buffer = (char __user *)buffer; 198 /* Store 13 in the data field. */ 198 /* Store 13 in the data field. */ 199 *((int *)table.data) = 13; 199 *((int *)table.data) = 13; 200 200 201 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 201 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, KUNIT_PROC_READ, 202 202 user_buffer, &len, &pos)); 203 KUNIT_ASSERT_EQ(test, 3, len); 203 KUNIT_ASSERT_EQ(test, 3, len); 204 buffer[len] = '\0'; 204 buffer[len] = '\0'; 205 /* And we read 13 back out. */ 205 /* And we read 13 back out. */ 206 KUNIT_EXPECT_STREQ(test, "13\n", buffe 206 KUNIT_EXPECT_STREQ(test, "13\n", buffer); 207 } 207 } 208 208 209 /* 209 /* 210 * Same as previous test, just now with negati 210 * Same as previous test, just now with negative numbers. 211 */ 211 */ 212 static void sysctl_test_dointvec_read_happy_si 212 static void sysctl_test_dointvec_read_happy_single_negative(struct kunit *test) 213 { 213 { 214 int data = 0; 214 int data = 0; 215 /* Good table. */ 215 /* Good table. */ 216 struct ctl_table table = { 216 struct ctl_table table = { 217 .procname = "foo", 217 .procname = "foo", 218 .data = &data, 218 .data = &data, 219 .maxlen = sizeof(int), 219 .maxlen = sizeof(int), 220 .mode = 0644, 220 .mode = 0644, 221 .proc_handler = proc_dointve 221 .proc_handler = proc_dointvec, 222 .extra1 = SYSCTL_ZERO, 222 .extra1 = SYSCTL_ZERO, 223 .extra2 = SYSCTL_ONE_H 223 .extra2 = SYSCTL_ONE_HUNDRED, 224 }; 224 }; 225 size_t len = 5; 225 size_t len = 5; 226 loff_t pos = 0; 226 loff_t pos = 0; 227 char *buffer = kunit_kzalloc(test, len 227 char *buffer = kunit_kzalloc(test, len, GFP_USER); 228 char __user *user_buffer = (char __use 228 char __user *user_buffer = (char __user *)buffer; 229 *((int *)table.data) = -16; 229 *((int *)table.data) = -16; 230 230 231 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 231 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, KUNIT_PROC_READ, 232 232 user_buffer, &len, &pos)); 233 KUNIT_ASSERT_EQ(test, 4, len); 233 KUNIT_ASSERT_EQ(test, 4, len); 234 buffer[len] = '\0'; 234 buffer[len] = '\0'; 235 KUNIT_EXPECT_STREQ(test, "-16\n", buff 235 KUNIT_EXPECT_STREQ(test, "-16\n", buffer); 236 } 236 } 237 237 238 /* 238 /* 239 * Test that a simple positive write works. 239 * Test that a simple positive write works. 240 */ 240 */ 241 static void sysctl_test_dointvec_write_happy_s 241 static void sysctl_test_dointvec_write_happy_single_positive(struct kunit *test) 242 { 242 { 243 int data = 0; 243 int data = 0; 244 /* Good table. */ 244 /* Good table. */ 245 struct ctl_table table = { 245 struct ctl_table table = { 246 .procname = "foo", 246 .procname = "foo", 247 .data = &data, 247 .data = &data, 248 .maxlen = sizeof(int), 248 .maxlen = sizeof(int), 249 .mode = 0644, 249 .mode = 0644, 250 .proc_handler = proc_dointve 250 .proc_handler = proc_dointvec, 251 .extra1 = SYSCTL_ZERO, 251 .extra1 = SYSCTL_ZERO, 252 .extra2 = SYSCTL_ONE_H 252 .extra2 = SYSCTL_ONE_HUNDRED, 253 }; 253 }; 254 char input[] = "9"; 254 char input[] = "9"; 255 size_t len = sizeof(input) - 1; 255 size_t len = sizeof(input) - 1; 256 loff_t pos = 0; 256 loff_t pos = 0; 257 char *buffer = kunit_kzalloc(test, len 257 char *buffer = kunit_kzalloc(test, len, GFP_USER); 258 char __user *user_buffer = (char __use 258 char __user *user_buffer = (char __user *)buffer; 259 259 260 memcpy(buffer, input, len); 260 memcpy(buffer, input, len); 261 261 262 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 262 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, KUNIT_PROC_WRITE, 263 263 user_buffer, &len, &pos)); 264 KUNIT_EXPECT_EQ(test, sizeof(input) - 264 KUNIT_EXPECT_EQ(test, sizeof(input) - 1, len); 265 KUNIT_EXPECT_EQ(test, sizeof(input) - 265 KUNIT_EXPECT_EQ(test, sizeof(input) - 1, pos); 266 KUNIT_EXPECT_EQ(test, 9, *((int *)tabl 266 KUNIT_EXPECT_EQ(test, 9, *((int *)table.data)); 267 } 267 } 268 268 269 /* 269 /* 270 * Same as previous test, but now with negativ 270 * Same as previous test, but now with negative numbers. 271 */ 271 */ 272 static void sysctl_test_dointvec_write_happy_s 272 static void sysctl_test_dointvec_write_happy_single_negative(struct kunit *test) 273 { 273 { 274 int data = 0; 274 int data = 0; 275 struct ctl_table table = { 275 struct ctl_table table = { 276 .procname = "foo", 276 .procname = "foo", 277 .data = &data, 277 .data = &data, 278 .maxlen = sizeof(int), 278 .maxlen = sizeof(int), 279 .mode = 0644, 279 .mode = 0644, 280 .proc_handler = proc_dointve 280 .proc_handler = proc_dointvec, 281 .extra1 = SYSCTL_ZERO, 281 .extra1 = SYSCTL_ZERO, 282 .extra2 = SYSCTL_ONE_H 282 .extra2 = SYSCTL_ONE_HUNDRED, 283 }; 283 }; 284 char input[] = "-9"; 284 char input[] = "-9"; 285 size_t len = sizeof(input) - 1; 285 size_t len = sizeof(input) - 1; 286 loff_t pos = 0; 286 loff_t pos = 0; 287 char *buffer = kunit_kzalloc(test, len 287 char *buffer = kunit_kzalloc(test, len, GFP_USER); 288 char __user *user_buffer = (char __use 288 char __user *user_buffer = (char __user *)buffer; 289 289 290 memcpy(buffer, input, len); 290 memcpy(buffer, input, len); 291 291 292 KUNIT_EXPECT_EQ(test, 0, proc_dointvec 292 KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, KUNIT_PROC_WRITE, 293 293 user_buffer, &len, &pos)); 294 KUNIT_EXPECT_EQ(test, sizeof(input) - 294 KUNIT_EXPECT_EQ(test, sizeof(input) - 1, len); 295 KUNIT_EXPECT_EQ(test, sizeof(input) - 295 KUNIT_EXPECT_EQ(test, sizeof(input) - 1, pos); 296 KUNIT_EXPECT_EQ(test, -9, *((int *)tab 296 KUNIT_EXPECT_EQ(test, -9, *((int *)table.data)); 297 } 297 } 298 298 299 /* 299 /* 300 * Test that writing a value smaller than the 300 * Test that writing a value smaller than the minimum possible value is not 301 * allowed. 301 * allowed. 302 */ 302 */ 303 static void sysctl_test_api_dointvec_write_sin 303 static void sysctl_test_api_dointvec_write_single_less_int_min( 304 struct kunit *test) 304 struct kunit *test) 305 { 305 { 306 int data = 0; 306 int data = 0; 307 struct ctl_table table = { 307 struct ctl_table table = { 308 .procname = "foo", 308 .procname = "foo", 309 .data = &data, 309 .data = &data, 310 .maxlen = sizeof(int), 310 .maxlen = sizeof(int), 311 .mode = 0644, 311 .mode = 0644, 312 .proc_handler = proc_dointve 312 .proc_handler = proc_dointvec, 313 .extra1 = SYSCTL_ZERO, 313 .extra1 = SYSCTL_ZERO, 314 .extra2 = SYSCTL_ONE_H 314 .extra2 = SYSCTL_ONE_HUNDRED, 315 }; 315 }; 316 size_t max_len = 32, len = max_len; 316 size_t max_len = 32, len = max_len; 317 loff_t pos = 0; 317 loff_t pos = 0; 318 char *buffer = kunit_kzalloc(test, max 318 char *buffer = kunit_kzalloc(test, max_len, GFP_USER); 319 char __user *user_buffer = (char __use 319 char __user *user_buffer = (char __user *)buffer; 320 unsigned long abs_of_less_than_min = ( 320 unsigned long abs_of_less_than_min = (unsigned long)INT_MAX 321 - 321 - (INT_MAX + INT_MIN) + 1; 322 322 323 /* 323 /* 324 * We use this rigmarole to create a s 324 * We use this rigmarole to create a string that contains a value one 325 * less than the minimum accepted valu 325 * less than the minimum accepted value. 326 */ 326 */ 327 KUNIT_ASSERT_LT(test, 327 KUNIT_ASSERT_LT(test, 328 (size_t)snprintf(buffe 328 (size_t)snprintf(buffer, max_len, "-%lu", 329 abs_o 329 abs_of_less_than_min), 330 max_len); 330 max_len); 331 331 332 KUNIT_EXPECT_EQ(test, -EINVAL, proc_do 332 KUNIT_EXPECT_EQ(test, -EINVAL, proc_dointvec(&table, KUNIT_PROC_WRITE, 333 333 user_buffer, &len, &pos)); 334 KUNIT_EXPECT_EQ(test, max_len, len); 334 KUNIT_EXPECT_EQ(test, max_len, len); 335 KUNIT_EXPECT_EQ(test, 0, *((int *)tabl 335 KUNIT_EXPECT_EQ(test, 0, *((int *)table.data)); 336 } 336 } 337 337 338 /* 338 /* 339 * Test that writing the maximum possible valu 339 * Test that writing the maximum possible value works. 340 */ 340 */ 341 static void sysctl_test_api_dointvec_write_sin 341 static void sysctl_test_api_dointvec_write_single_greater_int_max( 342 struct kunit *test) 342 struct kunit *test) 343 { 343 { 344 int data = 0; 344 int data = 0; 345 struct ctl_table table = { 345 struct ctl_table table = { 346 .procname = "foo", 346 .procname = "foo", 347 .data = &data, 347 .data = &data, 348 .maxlen = sizeof(int), 348 .maxlen = sizeof(int), 349 .mode = 0644, 349 .mode = 0644, 350 .proc_handler = proc_dointve 350 .proc_handler = proc_dointvec, 351 .extra1 = SYSCTL_ZERO, 351 .extra1 = SYSCTL_ZERO, 352 .extra2 = SYSCTL_ONE_H 352 .extra2 = SYSCTL_ONE_HUNDRED, 353 }; 353 }; 354 size_t max_len = 32, len = max_len; 354 size_t max_len = 32, len = max_len; 355 loff_t pos = 0; 355 loff_t pos = 0; 356 char *buffer = kunit_kzalloc(test, max 356 char *buffer = kunit_kzalloc(test, max_len, GFP_USER); 357 char __user *user_buffer = (char __use 357 char __user *user_buffer = (char __user *)buffer; 358 unsigned long greater_than_max = (unsi 358 unsigned long greater_than_max = (unsigned long)INT_MAX + 1; 359 359 360 KUNIT_ASSERT_GT(test, greater_than_max 360 KUNIT_ASSERT_GT(test, greater_than_max, (unsigned long)INT_MAX); 361 KUNIT_ASSERT_LT(test, (size_t)snprintf 361 KUNIT_ASSERT_LT(test, (size_t)snprintf(buffer, max_len, "%lu", 362 362 greater_than_max), 363 max_len); 363 max_len); 364 KUNIT_EXPECT_EQ(test, -EINVAL, proc_do 364 KUNIT_EXPECT_EQ(test, -EINVAL, proc_dointvec(&table, KUNIT_PROC_WRITE, 365 365 user_buffer, &len, &pos)); 366 KUNIT_ASSERT_EQ(test, max_len, len); 366 KUNIT_ASSERT_EQ(test, max_len, len); 367 KUNIT_EXPECT_EQ(test, 0, *((int *)tabl 367 KUNIT_EXPECT_EQ(test, 0, *((int *)table.data)); 368 } 368 } 369 369 370 /* 370 /* 371 * Test that registering an invalid extra valu 371 * Test that registering an invalid extra value is not allowed. 372 */ 372 */ 373 static void sysctl_test_register_sysctl_sz_inv 373 static void sysctl_test_register_sysctl_sz_invalid_extra_value( 374 struct kunit *test) 374 struct kunit *test) 375 { 375 { 376 unsigned char data = 0; 376 unsigned char data = 0; 377 struct ctl_table table_foo[] = { 377 struct ctl_table table_foo[] = { 378 { 378 { 379 .procname = "foo 379 .procname = "foo", 380 .data = &dat 380 .data = &data, 381 .maxlen = size 381 .maxlen = sizeof(u8), 382 .mode = 0644 382 .mode = 0644, 383 .proc_handler = proc 383 .proc_handler = proc_dou8vec_minmax, 384 .extra1 = SYSC 384 .extra1 = SYSCTL_FOUR, 385 .extra2 = SYSC 385 .extra2 = SYSCTL_ONE_THOUSAND, 386 }, 386 }, 387 }; 387 }; 388 388 389 struct ctl_table table_bar[] = { 389 struct ctl_table table_bar[] = { 390 { 390 { 391 .procname = "bar 391 .procname = "bar", 392 .data = &dat 392 .data = &data, 393 .maxlen = size 393 .maxlen = sizeof(u8), 394 .mode = 0644 394 .mode = 0644, 395 .proc_handler = proc 395 .proc_handler = proc_dou8vec_minmax, 396 .extra1 = SYSC 396 .extra1 = SYSCTL_NEG_ONE, 397 .extra2 = SYSC 397 .extra2 = SYSCTL_ONE_HUNDRED, 398 }, 398 }, 399 }; 399 }; 400 400 401 struct ctl_table table_qux[] = { 401 struct ctl_table table_qux[] = { 402 { 402 { 403 .procname = "qux 403 .procname = "qux", 404 .data = &dat 404 .data = &data, 405 .maxlen = size 405 .maxlen = sizeof(u8), 406 .mode = 0644 406 .mode = 0644, 407 .proc_handler = proc 407 .proc_handler = proc_dou8vec_minmax, 408 .extra1 = SYSC 408 .extra1 = SYSCTL_ZERO, 409 .extra2 = SYSC 409 .extra2 = SYSCTL_TWO_HUNDRED, 410 }, 410 }, 411 }; 411 }; 412 412 413 KUNIT_EXPECT_NULL(test, register_sysct 413 KUNIT_EXPECT_NULL(test, register_sysctl("foo", table_foo)); 414 KUNIT_EXPECT_NULL(test, register_sysct 414 KUNIT_EXPECT_NULL(test, register_sysctl("foo", table_bar)); 415 KUNIT_EXPECT_NOT_NULL(test, register_s 415 KUNIT_EXPECT_NOT_NULL(test, register_sysctl("foo", table_qux)); 416 } 416 } 417 417 418 static struct kunit_case sysctl_test_cases[] = 418 static struct kunit_case sysctl_test_cases[] = { 419 KUNIT_CASE(sysctl_test_api_dointvec_nu 419 KUNIT_CASE(sysctl_test_api_dointvec_null_tbl_data), 420 KUNIT_CASE(sysctl_test_api_dointvec_ta 420 KUNIT_CASE(sysctl_test_api_dointvec_table_maxlen_unset), 421 KUNIT_CASE(sysctl_test_api_dointvec_ta 421 KUNIT_CASE(sysctl_test_api_dointvec_table_len_is_zero), 422 KUNIT_CASE(sysctl_test_api_dointvec_ta 422 KUNIT_CASE(sysctl_test_api_dointvec_table_read_but_position_set), 423 KUNIT_CASE(sysctl_test_dointvec_read_h 423 KUNIT_CASE(sysctl_test_dointvec_read_happy_single_positive), 424 KUNIT_CASE(sysctl_test_dointvec_read_h 424 KUNIT_CASE(sysctl_test_dointvec_read_happy_single_negative), 425 KUNIT_CASE(sysctl_test_dointvec_write_ 425 KUNIT_CASE(sysctl_test_dointvec_write_happy_single_positive), 426 KUNIT_CASE(sysctl_test_dointvec_write_ 426 KUNIT_CASE(sysctl_test_dointvec_write_happy_single_negative), 427 KUNIT_CASE(sysctl_test_api_dointvec_wr 427 KUNIT_CASE(sysctl_test_api_dointvec_write_single_less_int_min), 428 KUNIT_CASE(sysctl_test_api_dointvec_wr 428 KUNIT_CASE(sysctl_test_api_dointvec_write_single_greater_int_max), 429 KUNIT_CASE(sysctl_test_register_sysctl 429 KUNIT_CASE(sysctl_test_register_sysctl_sz_invalid_extra_value), 430 {} 430 {} 431 }; 431 }; 432 432 433 static struct kunit_suite sysctl_test_suite = 433 static struct kunit_suite sysctl_test_suite = { 434 .name = "sysctl_test", 434 .name = "sysctl_test", 435 .test_cases = sysctl_test_cases, 435 .test_cases = sysctl_test_cases, 436 }; 436 }; 437 437 438 kunit_test_suites(&sysctl_test_suite); 438 kunit_test_suites(&sysctl_test_suite); 439 439 440 MODULE_DESCRIPTION("KUnit test of proc sysctl" 440 MODULE_DESCRIPTION("KUnit test of proc sysctl"); 441 MODULE_LICENSE("GPL v2"); 441 MODULE_LICENSE("GPL v2"); 442 442
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.