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