1# 2# Copyright (C) 2020 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17import math 18 19import target_file_utils 20 21from parse import with_pattern 22from proc_tests import KernelProcFileTestBase 23from vts.utils.python.android import api 24 25 26# Test for /proc/sys/kernel/*. 27class ProcCorePattern(KernelProcFileTestBase.KernelProcFileTestBase): 28 '''/proc/sys/kernel/core_pattern is used to specify a core dumpfile pattern 29 name. 30 ''' 31 32 def parse_contents(self, contents): 33 pass 34 35 def get_path(self): 36 return "/proc/sys/kernel/core_pattern" 37 38 def get_permission_checker(self): 39 return target_file_utils.IsReadWrite 40 41 42class ProcCorePipeLimit(KernelProcFileTestBase.KernelProcFileTestBase): 43 '''/proc/sys/kernel/core_pipe_limit defines how many concurrent crashing 44 processes may be piped to user space applications in parallel. 45 ''' 46 47 def parse_contents(self, contents): 48 return self.parse_line("{:d}\n", contents)[0] 49 50 def get_path(self): 51 return "/proc/sys/kernel/core_pipe_limit" 52 53 def get_permission_checker(self): 54 return target_file_utils.IsReadWrite 55 56 57class ProcDmesgRestrict(KernelProcFileTestBase.KernelProcFileTestBase): 58 '''/proc/sys/kernel/dmesg_restrict indicates whether unprivileged users are 59 prevented from using dmesg. 60 ''' 61 62 def parse_contents(self, contents): 63 return self.parse_line("{:d}\n", contents)[0] 64 65 def result_correct(self, result): 66 return result in [0, 1] 67 68 def get_path(self): 69 return "/proc/sys/kernel/dmesg_restrict" 70 71 def get_permission_checker(self): 72 return target_file_utils.IsReadWrite 73 74 75class ProcDomainname(KernelProcFileTestBase.KernelProcFileTestBase): 76 '''/proc/sys/kernel/domainname determines YP/NIS domain name of the system.''' 77 78 def parse_contents(self, contents): 79 pass 80 81 def get_path(self): 82 return "/proc/sys/kernel/domainname" 83 84 def get_permission_checker(self): 85 return target_file_utils.IsReadWrite 86 87 88class ProcHostname(KernelProcFileTestBase.KernelProcFileTestBase): 89 '''/proc/sys/kernel/hostname determines the system's host name.''' 90 91 def parse_contents(self, contents): 92 pass 93 94 def get_path(self): 95 return "/proc/sys/kernel/hostname" 96 97 def get_permission_checker(self): 98 return target_file_utils.IsReadWrite 99 100 101class ProcHungTaskTimeoutSecs(KernelProcFileTestBase.KernelProcFileTestBase): 102 '''/proc/sys/kernel/hung_task_timeout_secs controls the default timeout 103 (in seconds) used to determine when a task has become non-responsive and 104 should be considered hung. 105 ''' 106 107 def parse_contents(self, contents): 108 return self.parse_line("{:d}\n", contents)[0] 109 110 def get_path(self): 111 return "/proc/sys/kernel/hung_task_timeout_secs" 112 113 def get_permission_checker(self): 114 return target_file_utils.IsReadWrite 115 116 def file_optional(self, shell=None, dut=None): 117 return True 118 119class ProcKptrRestrictTest(KernelProcFileTestBase.KernelProcFileTestBase): 120 '''/proc/sys/kernel/kptr_restrict determines whether kernel pointers are printed 121 in proc files. 122 ''' 123 124 def parse_contents(self, contents): 125 return self.parse_line("{:d}\n", contents)[0] 126 127 def result_correct(self, result): 128 return result >= 0 and result <= 4 129 130 def get_path(self): 131 return "/proc/sys/kernel/kptr_restrict" 132 133 def get_permission_checker(self): 134 """Get r/w file permission checker. 135 """ 136 return target_file_utils.IsReadWrite 137 138 139class ProcModulesDisabled(KernelProcFileTestBase.KernelProcFileTestBase): 140 '''/proc/sys/kernel/modules_disabled indicates if modules are allowed to be 141 loaded. 142 ''' 143 144 def parse_contents(self, contents): 145 return self.parse_line("{:d}\n", contents)[0] 146 147 def result_correct(self, result): 148 return result in [0, 1] 149 150 def get_path(self): 151 return "/proc/sys/kernel/modules_disabled" 152 153 def get_permission_checker(self): 154 return target_file_utils.IsReadWrite 155 156 157class ProcPanicOnOops(KernelProcFileTestBase.KernelProcFileTestBase): 158 '''/proc/sys/kernel/panic_on_oops controls kernel's behaviour on oops.''' 159 160 def parse_contents(self, contents): 161 return self.parse_line("{:d}\n", contents)[0] 162 163 def result_correct(self, result): 164 return result in [0, 1] 165 166 def get_path(self): 167 return "/proc/sys/kernel/panic_on_oops" 168 169 def get_permission_checker(self): 170 return target_file_utils.IsReadWrite 171 172 173class ProcPerfEventMaxSampleRate(KernelProcFileTestBase.KernelProcFileTestBase): 174 '''/proc/sys/kernel/perf_event_max_sample_rate sets the maximum sample rate 175 of performance events. 176 ''' 177 178 def parse_contents(self, contents): 179 return self.parse_line("{:d}\n", contents)[0] 180 181 def get_path(self): 182 return "/proc/sys/kernel/perf_event_max_sample_rate" 183 184 def get_permission_checker(self): 185 return target_file_utils.IsReadWrite 186 187 188class ProcPerfEventParanoid(KernelProcFileTestBase.KernelProcFileTestBase): 189 '''/proc/sys/kernel/perf_event_paranoid controls use of the performance 190 events system by unprivileged users. 191 ''' 192 193 def parse_contents(self, contents): 194 return self.parse_line("{:d}\n", contents)[0] 195 196 def get_path(self): 197 return "/proc/sys/kernel/perf_event_paranoid" 198 199 def get_permission_checker(self): 200 return target_file_utils.IsReadWrite 201 202 203class ProcPidMax(KernelProcFileTestBase.KernelProcFileTestBase): 204 '''/proc/sys/kernel/pid_max is the pid allocation wrap value.''' 205 206 def parse_contents(self, contents): 207 return self.parse_line("{:d}\n", contents)[0] 208 209 def get_path(self): 210 return "/proc/sys/kernel/pid_max" 211 212 def get_permission_checker(self): 213 return target_file_utils.IsReadWrite 214 215 216@with_pattern( 217 r"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" 218) 219def token_uuid(text): 220 return text 221 222class ProcSysKernelRandomBootId(KernelProcFileTestBase.KernelProcFileTestBase): 223 '''/proc/sys/kernel/random/boot_id generates a random ID each boot.''' 224 225 def parse_contents(self, contents): 226 return self.parse_line("{:uuid}\n", contents, dict(uuid=token_uuid))[0] 227 228 def get_path(self): 229 return "/proc/sys/kernel/random/boot_id" 230 231 def get_permission_checker(self): 232 return target_file_utils.IsReadOnly 233 234 235class ProcRandomizeVaSpaceTest(KernelProcFileTestBase.KernelProcFileTestBase): 236 '''/proc/sys/kernel/randomize_va_space determines the address layout randomization 237 policy for the system. 238 ''' 239 240 def parse_contents(self, contents): 241 return self.parse_line("{:d}\n", contents)[0] 242 243 def result_correct(self, result): 244 return result >= 0 and result <= 2 245 246 def get_path(self): 247 return "/proc/sys/kernel/randomize_va_space" 248 249 def get_permission_checker(self): 250 """Get r/w file permission checker. 251 """ 252 return target_file_utils.IsReadWrite 253 254 255class ProcSchedChildRunsFirst(KernelProcFileTestBase.KernelProcFileTestBase): 256 '''/proc/sys/kernel/sched_child_runs_first causes newly forked tasks to 257 be favored in scheduling over their parents. 258 ''' 259 260 def parse_contents(self, contents): 261 return self.parse_line("{:d}\n", contents)[0] 262 263 def get_path(self): 264 return "/proc/sys/kernel/sched_child_runs_first" 265 266 def get_permission_checker(self): 267 return target_file_utils.IsReadWrite 268 269 270class ProcSchedRTPeriodUS(KernelProcFileTestBase.KernelProcFileTestBase): 271 '''/proc/sys/kernel/sched_rt_period_us defines the period length used by the 272 system-wide RT execution limit in microseconds. 273 ''' 274 275 def parse_contents(self, contents): 276 return self.parse_line("{:d}\n", contents)[0] 277 278 def result_correct(self, result): 279 return result >= 1 and result <= math.pow(2,31) 280 281 def get_path(self): 282 return "/proc/sys/kernel/sched_rt_period_us" 283 284 def get_permission_checker(self): 285 return target_file_utils.IsReadWrite 286 287 288class ProcSchedRTRuntimeUS(KernelProcFileTestBase.KernelProcFileTestBase): 289 '''/proc/sys/kernel/sched_rt_runtime_us defines the amount of time in 290 microseconds relative to sched_rt_period_us that the system may execute RT 291 tasks. 292 ''' 293 294 def parse_contents(self, contents): 295 return self.parse_line("{:d}\n", contents)[0] 296 297 def result_correct(self, result): 298 return result >= -1 and result <= (math.pow(2,31) - 1) 299 300 def get_path(self): 301 return "/proc/sys/kernel/sched_rt_runtime_us" 302 303 def get_permission_checker(self): 304 return target_file_utils.IsReadWrite 305 306 307class ProcSysRqTest(KernelProcFileTestBase.KernelProcFileTestBase): 308 '''/proc/sys/kernel/sysrq controls the functions allowed to be invoked 309 via the SysRq key.''' 310 311 def parse_contents(self, contents): 312 return self.parse_line("{:d}\n", contents)[0] 313 314 def result_correct(self, result): 315 return result >= 0 and result <= 511 316 317 def get_path(self): 318 return "/proc/sys/kernel/sysrq" 319 320 def get_permission_checker(self): 321 return target_file_utils.IsReadWrite 322 323 324# Tests for /proc/sys/vm/*. 325 326class ProcDirtyBackgroundBytes(KernelProcFileTestBase.KernelProcFileTestBase): 327 '''/proc/sys/vm/dirty_background_bytes contains the amount of dirty memory 328 at which the background kernel flusher threads will start writeback. 329 ''' 330 331 def parse_contents(self, contents): 332 return self.parse_line("{:d}\n", contents)[0] 333 334 def get_path(self): 335 return "/proc/sys/vm/dirty_background_bytes" 336 337 def get_permission_checker(self): 338 return target_file_utils.IsReadWrite 339 340 341class ProcDirtyBackgroundRatio(KernelProcFileTestBase.KernelProcFileTestBase): 342 '''/proc/sys/vm/dirty_background_ratio contains, as a percentage of total 343 available memory that contains free pages and reclaimable pages, the number 344 of pages at which the background kernel flusher threads will start writing 345 out dirty data. 346 ''' 347 348 def parse_contents(self, contents): 349 return self.parse_line("{:d}\n", contents)[0] 350 351 def result_correct(self, result): 352 return result >= 0 and result <= 100 353 354 def get_path(self): 355 return "/proc/sys/vm/dirty_background_ratio" 356 357 def get_permission_checker(self): 358 return target_file_utils.IsReadWrite 359 360 361class ProcDirtyExpireCentisecs(KernelProcFileTestBase.KernelProcFileTestBase): 362 '''/proc/sys/vm/dirty_expire_centisecs is used to define when dirty data is 363 old enough to be eligible for writeout by the kernel flusher threads. 364 ''' 365 366 def parse_contents(self, contents): 367 return self.parse_line("{:d}\n", contents)[0] 368 369 def get_path(self): 370 return "/proc/sys/vm/dirty_expire_centisecs" 371 372 def get_permission_checker(self): 373 return target_file_utils.IsReadWrite 374 375 376class ProcDropCaches(KernelProcFileTestBase.KernelProcFileTestBase): 377 '''Writing to /proc/sys/vm/drop_caches will cause the kernel to drop clean 378 caches. 379 ''' 380 381 def parse_contents(self, contents): 382 # Format of this file is not documented, so don't check that. 383 return '' 384 385 def get_path(self): 386 return "/proc/sys/vm/drop_caches" 387 388 def IsReadWriteOrWriteOnly(self, permission_bits): 389 return (target_file_utils.IsReadWrite(permission_bits) or 390 target_file_utils.IsWriteOnly(permission_bits)) 391 392 def get_permission_checker(self): 393 if self.api_level > api.PLATFORM_API_LEVEL_Q: 394 return target_file_utils.IsWriteOnly 395 else: 396 return self.IsReadWriteOrWriteOnly 397 398 def test_format(self): 399 return False 400 401class ProcExtraFreeKbytes(KernelProcFileTestBase.KernelProcFileTestBase): 402 '''/proc/sys/vm/extra_free_kbytes tells the VM to keep extra free memory 403 between the threshold where background reclaim (kswapd) kicks in, and the 404 threshold where direct reclaim (by allocating processes) kicks in. 405 ''' 406 407 def parse_contents(self, contents): 408 return self.parse_line("{:d}\n", contents)[0] 409 410 def get_path(self): 411 return "/proc/sys/vm/extra_free_kbytes" 412 413 def get_permission_checker(self): 414 return target_file_utils.IsReadWrite 415 416 def file_optional(self, shell=None, dut=None): 417 # This file isn't in Android common kernel. 418 return True 419 420 421class ProcOverCommitMemoryTest(KernelProcFileTestBase.KernelProcFileTestBase): 422 '''/proc/sys/vm/overcommit_memory determines the kernel virtual memory accounting mode. 423 ''' 424 425 def parse_contents(self, contents): 426 return self.parse_line("{:d}\n", contents)[0] 427 428 def result_correct(self, result): 429 return result >= 0 and result <= 2 430 431 def get_path(self): 432 return "/proc/sys/vm/overcommit_memory" 433 434 def get_permission_checker(self): 435 """Get r/w file permission checker. 436 """ 437 return target_file_utils.IsReadWrite 438 439 440class ProcMaxMapCount(KernelProcFileTestBase.KernelProcFileTestBase): 441 '''/proc/sys/vm/max_map_count contains the maximum number of memory map areas a process 442 may have. 443 ''' 444 445 def parse_contents(self, contents): 446 return self.parse_line("{:d}\n", contents)[0] 447 448 def get_path(self): 449 return "/proc/sys/vm/max_map_count" 450 451 def get_permission_checker(self): 452 return target_file_utils.IsReadWrite 453 454 455class ProcMmapMinAddrTest(KernelProcFileTestBase.KernelProcFileTestBase): 456 '''/proc/sys/vm/mmap_min_addr specifies the minimum address that can be mmap'd. 457 ''' 458 459 def parse_contents(self, contents): 460 return self.parse_line("{:d}\n", contents)[0] 461 462 def get_path(self): 463 return "/proc/sys/vm/mmap_min_addr" 464 465 def get_permission_checker(self): 466 """Get r/w file permission checker. 467 """ 468 return target_file_utils.IsReadWrite 469 470 471class ProcMmapRndBitsTest(KernelProcFileTestBase.KernelProcFileTestBase): 472 '''/proc/sys/vm/mmap_rnd_(compat_)bits specifies the amount of randomness in mmap'd 473 addresses. Must be >= 8. 474 ''' 475 476 def parse_contents(self, contents): 477 return self.parse_line("{:d}\n", contents)[0] 478 479 def result_correct(self, result): 480 return result >= 8 481 482 def get_path(self): 483 return "/proc/sys/vm/mmap_rnd_bits" 484 485 def get_permission_checker(self): 486 """Get r/w file permission checker. 487 """ 488 return target_file_utils.IsReadWrite 489 490 491class ProcMmapRndCompatBitsTest(ProcMmapRndBitsTest): 492 def get_path(self): 493 return "/proc/sys/vm/mmap_rnd_compat_bits" 494 495 496class ProcPageCluster(KernelProcFileTestBase.KernelProcFileTestBase): 497 '''/proc/sys/vm/page-cluster controls the number of pages up to which 498 consecutive pages are read in from swap in a single attempt. 499 ''' 500 501 def parse_contents(self, contents): 502 return self.parse_line("{:d}\n", contents)[0] 503 504 def get_path(self): 505 return "/proc/sys/vm/page-cluster" 506 507 def get_permission_checker(self): 508 return target_file_utils.IsReadWrite 509 510 511# Tests for /proc/sys/fs/*. 512 513class ProcPipeMaxSize(KernelProcFileTestBase.KernelProcFileTestBase): 514 '''/proc/sys/fs/pipe-max-size reports the maximum size (in bytes) of 515 individual pipes. 516 ''' 517 518 def parse_contents(self, contents): 519 return self.parse_line("{:d}\n", contents)[0] 520 521 def get_path(self): 522 return "/proc/sys/fs/pipe-max-size" 523 524 def get_permission_checker(self): 525 return target_file_utils.IsReadWrite 526 527 528class ProcProtectedHardlinks(KernelProcFileTestBase.KernelProcFileTestBase): 529 '''/proc/sys/fs/protected_hardlinks reports hardlink creation behavior.''' 530 531 def parse_contents(self, contents): 532 return self.parse_line("{:d}\n", contents)[0] 533 534 def result_correct(self, result): 535 return result in [0, 1] 536 537 def get_path(self): 538 return "/proc/sys/fs/protected_hardlinks" 539 540 def get_permission_checker(self): 541 return target_file_utils.IsReadWrite 542 543 544class ProcProtectedSymlinks(KernelProcFileTestBase.KernelProcFileTestBase): 545 '''/proc/sys/fs/protected_symlinks reports symlink following behavior.''' 546 547 def parse_contents(self, contents): 548 return self.parse_line("{:d}\n", contents)[0] 549 550 def result_correct(self, result): 551 return result in [0, 1] 552 553 def get_path(self): 554 return "/proc/sys/fs/protected_symlinks" 555 556 def get_permission_checker(self): 557 return target_file_utils.IsReadWrite 558 559 560class ProcSuidDumpable(KernelProcFileTestBase.KernelProcFileTestBase): 561 '''/proc/sys/fs/suid_dumpable value can be used to query and set the core 562 dump mode for setuid or otherwise protected/tainted binaries. 563 ''' 564 565 def parse_contents(self, contents): 566 return self.parse_line("{:d}\n", contents)[0] 567 568 def result_correct(self, result): 569 return result in [0, 1, 2] 570 571 def get_path(self): 572 return "/proc/sys/fs/suid_dumpable" 573 574 def get_permission_checker(self): 575 return target_file_utils.IsReadWrite 576 577 578class ProcUptime(KernelProcFileTestBase.KernelProcFileTestBase): 579 '''/proc/uptime tells how long the system has been running.''' 580 581 def parse_contents(self, contents): 582 return self.parse_line("{:f} {:f}\n", contents)[0] 583 584 def get_path(self): 585 return "/proc/uptime" 586