xref: /aosp_15_r20/test/vts/tests/kernel_proc_file_api_test/proc_tests/ProcSimpleFileTests.py (revision 9a74111979c139a065a9a7e4d45972320c5732c7)
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