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}", 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 ProcSchedLatencyNS(KernelProcFileTestBase.KernelProcFileTestBase): 271 '''/proc/sys/kernel/sched_latency_ns is the maximum latency in nanoseconds a 272 task may incur prior to being scheduled. 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 >= 100000 and result <= 1000000000 280 281 def get_path(self): 282 return "/proc/sys/kernel/sched_latency_ns" 283 284 def get_permission_checker(self): 285 return target_file_utils.IsReadWrite 286 287 288class ProcSchedRTPeriodUS(KernelProcFileTestBase.KernelProcFileTestBase): 289 '''/proc/sys/kernel/sched_rt_period_us defines the period length used by the 290 system-wide RT execution limit in microseconds. 291 ''' 292 293 def parse_contents(self, contents): 294 return self.parse_line("{:d}\n", contents)[0] 295 296 def result_correct(self, result): 297 return result >= 1 and result <= math.pow(2,31) 298 299 def get_path(self): 300 return "/proc/sys/kernel/sched_rt_period_us" 301 302 def get_permission_checker(self): 303 return target_file_utils.IsReadWrite 304 305 306class ProcSchedRTRuntimeUS(KernelProcFileTestBase.KernelProcFileTestBase): 307 '''/proc/sys/kernel/sched_rt_runtime_us defines the amount of time in 308 microseconds relative to sched_rt_period_us that the system may execute RT 309 tasks. 310 ''' 311 312 def parse_contents(self, contents): 313 return self.parse_line("{:d}\n", contents)[0] 314 315 def result_correct(self, result): 316 return result >= -1 and result <= (math.pow(2,31) - 1) 317 318 def get_path(self): 319 return "/proc/sys/kernel/sched_rt_runtime_us" 320 321 def get_permission_checker(self): 322 return target_file_utils.IsReadWrite 323 324 325class ProcSchedTunableScaling(KernelProcFileTestBase.KernelProcFileTestBase): 326 '''/proc/sys/kernel/sched_tunable_scaling determines whether 327 sched_latency_ns should be automatically adjusted by the scheduler based on 328 the number of CPUs. 329 ''' 330 331 def parse_contents(self, contents): 332 return self.parse_line("{:d}\n", contents)[0] 333 334 def result_correct(self, result): 335 return result >= 0 and result <= 2 336 337 def get_path(self): 338 return "/proc/sys/kernel/sched_tunable_scaling" 339 340 def get_permission_checker(self): 341 return target_file_utils.IsReadWrite 342 343 344class ProcSchedWakeupGranularityNS( 345 KernelProcFileTestBase.KernelProcFileTestBase): 346 '''/proc/sys/kernel/sched_wakeup_granularity_ns defines how much more 347 virtual runtime task A must have than task B in nanoseconds in order for 348 task B to preempt it. 349 ''' 350 351 def parse_contents(self, contents): 352 return self.parse_line("{:d}\n", contents)[0] 353 354 def result_correct(self, result): 355 return result >= 0 and result <= 1000000000 356 357 def get_path(self): 358 return "/proc/sys/kernel/sched_wakeup_granularity_ns" 359 360 def get_permission_checker(self): 361 return target_file_utils.IsReadWrite 362 363 364class ProcSysRqTest(KernelProcFileTestBase.KernelProcFileTestBase): 365 '''/proc/sys/kernel/sysrq controls the functions allowed to be invoked 366 via the SysRq key.''' 367 368 def parse_contents(self, contents): 369 return self.parse_line("{:d}\n", contents)[0] 370 371 def result_correct(self, result): 372 return result >= 0 and result <= 511 373 374 def get_path(self): 375 return "/proc/sys/kernel/sysrq" 376 377 def get_permission_checker(self): 378 return target_file_utils.IsReadWrite 379 380 381# Tests for /proc/sys/vm/*. 382 383class ProcDirtyBackgroundBytes(KernelProcFileTestBase.KernelProcFileTestBase): 384 '''/proc/sys/vm/dirty_background_bytes contains the amount of dirty memory 385 at which the background kernel flusher threads will start writeback. 386 ''' 387 388 def parse_contents(self, contents): 389 return self.parse_line("{:d}\n", contents)[0] 390 391 def get_path(self): 392 return "/proc/sys/vm/dirty_background_bytes" 393 394 def get_permission_checker(self): 395 return target_file_utils.IsReadWrite 396 397 398class ProcDirtyBackgroundRatio(KernelProcFileTestBase.KernelProcFileTestBase): 399 '''/proc/sys/vm/dirty_background_ratio contains, as a percentage of total 400 available memory that contains free pages and reclaimable pages, the number 401 of pages at which the background kernel flusher threads will start writing 402 out dirty data. 403 ''' 404 405 def parse_contents(self, contents): 406 return self.parse_line("{:d}\n", contents)[0] 407 408 def result_correct(self, result): 409 return result >= 0 and result <= 100 410 411 def get_path(self): 412 return "/proc/sys/vm/dirty_background_ratio" 413 414 def get_permission_checker(self): 415 return target_file_utils.IsReadWrite 416 417 418class ProcDirtyExpireCentisecs(KernelProcFileTestBase.KernelProcFileTestBase): 419 '''/proc/sys/vm/dirty_expire_centisecs is used to define when dirty data is 420 old enough to be eligible for writeout by the kernel flusher threads. 421 ''' 422 423 def parse_contents(self, contents): 424 return self.parse_line("{:d}\n", contents)[0] 425 426 def get_path(self): 427 return "/proc/sys/vm/dirty_expire_centisecs" 428 429 def get_permission_checker(self): 430 return target_file_utils.IsReadWrite 431 432 433class ProcDropCaches(KernelProcFileTestBase.KernelProcFileTestBase): 434 '''Writing to /proc/sys/vm/drop_caches will cause the kernel to drop clean 435 caches. 436 ''' 437 438 def parse_contents(self, contents): 439 # Format of this file is not documented, so don't check that. 440 return '' 441 442 def get_path(self): 443 return "/proc/sys/vm/drop_caches" 444 445 def IsReadWriteOrWriteOnly(self, permission_bits): 446 return (target_file_utils.IsReadWrite(permission_bits) or 447 target_file_utils.IsWriteOnly(permission_bits)) 448 449 def get_permission_checker(self): 450 if self.api_level > api.PLATFORM_API_LEVEL_Q: 451 return target_file_utils.IsWriteOnly 452 else: 453 return self.IsReadWriteOrWriteOnly 454 455 def test_format(self): 456 return False 457 458class ProcExtraFreeKbytes(KernelProcFileTestBase.KernelProcFileTestBase): 459 '''/proc/sys/vm/extra_free_kbytes tells the VM to keep extra free memory 460 between the threshold where background reclaim (kswapd) kicks in, and the 461 threshold where direct reclaim (by allocating processes) kicks in. 462 ''' 463 464 def parse_contents(self, contents): 465 return self.parse_line("{:d}\n", contents)[0] 466 467 def get_path(self): 468 return "/proc/sys/vm/extra_free_kbytes" 469 470 def get_permission_checker(self): 471 return target_file_utils.IsReadWrite 472 473 def file_optional(self, shell=None, dut=None): 474 # This file isn't in Android common kernel. 475 return True 476 477 478class ProcOverCommitMemoryTest(KernelProcFileTestBase.KernelProcFileTestBase): 479 '''/proc/sys/vm/overcommit_memory determines the kernel virtual memory accounting mode. 480 ''' 481 482 def parse_contents(self, contents): 483 return self.parse_line("{:d}\n", contents)[0] 484 485 def result_correct(self, result): 486 return result >= 0 and result <= 2 487 488 def get_path(self): 489 return "/proc/sys/vm/overcommit_memory" 490 491 def get_permission_checker(self): 492 """Get r/w file permission checker. 493 """ 494 return target_file_utils.IsReadWrite 495 496 497class ProcMaxMapCount(KernelProcFileTestBase.KernelProcFileTestBase): 498 '''/proc/sys/vm/max_map_count contains the maximum number of memory map areas a process 499 may have. 500 ''' 501 502 def parse_contents(self, contents): 503 return self.parse_line("{:d}\n", contents)[0] 504 505 def get_path(self): 506 return "/proc/sys/vm/max_map_count" 507 508 def get_permission_checker(self): 509 return target_file_utils.IsReadWrite 510 511 512class ProcMmapMinAddrTest(KernelProcFileTestBase.KernelProcFileTestBase): 513 '''/proc/sys/vm/mmap_min_addr specifies the minimum address that can be mmap'd. 514 ''' 515 516 def parse_contents(self, contents): 517 return self.parse_line("{:d}\n", contents)[0] 518 519 def get_path(self): 520 return "/proc/sys/vm/mmap_min_addr" 521 522 def get_permission_checker(self): 523 """Get r/w file permission checker. 524 """ 525 return target_file_utils.IsReadWrite 526 527 528class ProcMmapRndBitsTest(KernelProcFileTestBase.KernelProcFileTestBase): 529 '''/proc/sys/vm/mmap_rnd_(compat_)bits specifies the amount of randomness in mmap'd 530 addresses. Must be >= 8. 531 ''' 532 533 def parse_contents(self, contents): 534 return self.parse_line("{:d}\n", contents)[0] 535 536 def result_correct(self, result): 537 return result >= 8 538 539 def get_path(self): 540 return "/proc/sys/vm/mmap_rnd_bits" 541 542 def get_permission_checker(self): 543 """Get r/w file permission checker. 544 """ 545 return target_file_utils.IsReadWrite 546 547 548class ProcMmapRndCompatBitsTest(ProcMmapRndBitsTest): 549 def get_path(self): 550 return "/proc/sys/vm/mmap_rnd_compat_bits" 551 552 553class ProcPageCluster(KernelProcFileTestBase.KernelProcFileTestBase): 554 '''/proc/sys/vm/page-cluster controls the number of pages up to which 555 consecutive pages are read in from swap in a single attempt. 556 ''' 557 558 def parse_contents(self, contents): 559 return self.parse_line("{:d}\n", contents)[0] 560 561 def get_path(self): 562 return "/proc/sys/vm/page-cluster" 563 564 def get_permission_checker(self): 565 return target_file_utils.IsReadWrite 566 567 568# Tests for /proc/sys/fs/*. 569 570class ProcPipeMaxSize(KernelProcFileTestBase.KernelProcFileTestBase): 571 '''/proc/sys/fs/pipe-max-size reports the maximum size (in bytes) of 572 individual pipes. 573 ''' 574 575 def parse_contents(self, contents): 576 return self.parse_line("{:d}\n", contents)[0] 577 578 def get_path(self): 579 return "/proc/sys/fs/pipe-max-size" 580 581 def get_permission_checker(self): 582 return target_file_utils.IsReadWrite 583 584 585class ProcProtectedHardlinks(KernelProcFileTestBase.KernelProcFileTestBase): 586 '''/proc/sys/fs/protected_hardlinks reports hardlink creation behavior.''' 587 588 def parse_contents(self, contents): 589 return self.parse_line("{:d}\n", contents)[0] 590 591 def result_correct(self, result): 592 return result in [0, 1] 593 594 def get_path(self): 595 return "/proc/sys/fs/protected_hardlinks" 596 597 def get_permission_checker(self): 598 return target_file_utils.IsReadWrite 599 600 601class ProcProtectedSymlinks(KernelProcFileTestBase.KernelProcFileTestBase): 602 '''/proc/sys/fs/protected_symlinks reports symlink following behavior.''' 603 604 def parse_contents(self, contents): 605 return self.parse_line("{:d}\n", contents)[0] 606 607 def result_correct(self, result): 608 return result in [0, 1] 609 610 def get_path(self): 611 return "/proc/sys/fs/protected_symlinks" 612 613 def get_permission_checker(self): 614 return target_file_utils.IsReadWrite 615 616 617class ProcSuidDumpable(KernelProcFileTestBase.KernelProcFileTestBase): 618 '''/proc/sys/fs/suid_dumpable value can be used to query and set the core 619 dump mode for setuid or otherwise protected/tainted binaries. 620 ''' 621 622 def parse_contents(self, contents): 623 return self.parse_line("{:d}\n", contents)[0] 624 625 def result_correct(self, result): 626 return result in [0, 1, 2] 627 628 def get_path(self): 629 return "/proc/sys/fs/suid_dumpable" 630 631 def get_permission_checker(self): 632 return target_file_utils.IsReadWrite 633 634 635class ProcUptime(KernelProcFileTestBase.KernelProcFileTestBase): 636 '''/proc/uptime tells how long the system has been running.''' 637 638 def parse_contents(self, contents): 639 return self.parse_line("{:f} {:f}\n", contents)[0] 640 641 def get_path(self): 642 return "/proc/uptime" 643