1#!/usr/bin/env python
2#
3# Copyright (C) 2016 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18import logging
19
20from vts.runners.host import const
21from vts.runners.host import asserts
22from vts.runners.host import base_test
23from vts.runners.host import test_runner
24from vts.utils.python.controllers import android_device
25
26
27class SyscallExistenceTest(base_test.BaseTestClass):
28    """Tests to verify kernel syscall interface."""
29    TEST_SHELL_NAME = "my_shell1"
30    AARCH64__NR_name_to_handle_at = 264
31    AARCH64__NR_open_by_handle_at = 265
32    AARCH64__NR_uselib = 1077
33
34    def setUpClass(self):
35        self.dut = self.registerController(android_device)[0]
36        self.dut.shell.InvokeTerminal(self.TEST_SHELL_NAME)
37
38    def tearDown(self):
39        self.dut.shell.InvokeTerminal(self.TEST_SHELL_NAME)
40        results = getattr(self.dut.shell, self.TEST_SHELL_NAME).Execute("which ls")
41        logging.info(str(results[const.STDOUT]))
42        asserts.assertEqual(len(results[const.STDOUT]), 1)
43        asserts.assertEqual(results[const.STDOUT][0].strip(), "/system/bin/ls")
44        asserts.assertEqual(results[const.EXIT_CODE][0], 0)
45
46    def testSyscall_name_to_handle_at(self):
47        """Testcase to verify syscall [name_to_handle_at] is disabled."""
48        if self.dut.is64Bit:
49            logging.info("testing syscall: name_to_handle_at [%d]",
50                         self.AARCH64__NR_name_to_handle_at)
51            asserts.assertTrue(self.SyscallDisabled(self.AARCH64__NR_name_to_handle_at),
52                               "syscall [name_to_handle_at] should be disabled")
53        else:
54            asserts.skip("32-bit not supported")
55
56    def testSyscall_open_by_handle_at(self):
57        """Testcase to verify syscall [open_by_handle_at] is disabled."""
58        if self.dut.is64Bit:
59            logging.info("testing syscall: open_by_handle_at [%d]",
60                         self.AARCH64__NR_open_by_handle_at)
61            asserts.assertTrue(self.SyscallDisabled(self.AARCH64__NR_open_by_handle_at),
62                               "syscall [open_by_handle_at] should be disabled")
63        else:
64            asserts.skip("32-bit not supported")
65
66    def testSyscall_uselib(self):
67        """Testcase to verify syscall [uselib] is disabled."""
68        if self.dut.is64Bit:
69            logging.info("testing syscall: uselib [%d]",
70                         self.AARCH64__NR_uselib)
71            asserts.assertTrue(self.SyscallDisabled(self.AARCH64__NR_uselib),
72                               "syscall [uselib] should be disabled")
73        else:
74            asserts.skip("32-bit not supported")
75
76    def SyscallDisabled(self, syscallid):
77        """Helper function to check if a syscall is disabled."""
78        target = "/data/local/tmp/64/vts_test_binary_syscall_exists"
79        results = getattr(self.dut.shell, self.TEST_SHELL_NAME).Execute([
80            "chmod 755 %s" % target,
81            "%s %d" % (target, syscallid)
82        ])
83        return len(results[const.STDOUT]) == 2 and results[const.STDOUT][1].strip() == "n"
84
85
86if __name__ == "__main__":
87    test_runner.main()
88