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 os 18 19from vts.utils.python.os import path_utils 20 21from vts.testcases.fuzz.template.libfuzzer_test import libfuzzer_test_config as config 22 23 24class LibFuzzerTestCase(object): 25 """Represents libfuzzer test case. 26 27 Attributes: 28 _bin_host_path: string, path to binary on host. 29 _bin_name: string, name of the binary. 30 _test_name: string, name of the test case. 31 _libfuzzer_params: dict, libfuzzer-specific parameters. 32 _additional_params: dict, additional parameters. 33 """ 34 35 def __init__(self, bin_host_path, libfuzzer_params, additional_params): 36 self._bin_host_path = bin_host_path 37 self._libfuzzer_params = libfuzzer_params 38 self._additional_params = additional_params 39 self._binary_name = os.path.basename(bin_host_path) 40 self._test_name = self._binary_name 41 42 def GetCorpusName(self): 43 """Returns corpus directory name on target.""" 44 corpus_dir = path_utils.JoinTargetPath( 45 config.FUZZER_TEST_DIR, '%s_corpus' % self._test_name) 46 return corpus_dir 47 48 def CreateFuzzerFlags(self): 49 """Creates flags for the fuzzer executable. 50 51 Returns: 52 string, of form '-<flag0>=<val0> -<flag1>=<val1> ... ' 53 """ 54 # Used to separate additional and libfuzzer flags. 55 DELIMITER = '--' 56 additional_flags = ' '.join( 57 ['--%s=%s' % (k, v) for k, v in self._additional_params.items()]) 58 libfuzzer_flags = ' '.join( 59 ['-%s=%s' % (k, v) for k, v in self._libfuzzer_params.items()]) 60 if not additional_flags: 61 flags = libfuzzer_flags 62 else: 63 flags = '%s %s %s' % (additional_flags, DELIMITER, libfuzzer_flags) 64 return flags 65 66 def GetRunCommand(self): 67 """Returns target shell command to run the fuzzer binary.""" 68 test_flags = self.CreateFuzzerFlags() 69 corpus_dir = self.GetCorpusName() 70 71 cd_cmd = 'cd %s' % config.FUZZER_TEST_DIR 72 chmod_cmd = 'chmod 777 %s' % self._binary_name 73 ld_path = 'LD_LIBRARY_PATH=/data/local/tmp/64:/data/local/tmp/32:$LD_LIBRARY_PATH' 74 test_cmd = '%s ./%s %s %s > /dev/null' % (ld_path, self._binary_name, 75 corpus_dir, test_flags) 76 return ' && '.join([cd_cmd, chmod_cmd, test_cmd]) 77 78 @property 79 def test_name(self): 80 """Name of this test case.""" 81 return str(self._test_name) 82 83 @test_name.setter 84 def test_name(self, name): 85 """Set name of this test case.""" 86 self._test_name = name 87 88 @property 89 def bin_host_path(self): 90 """Host path to binary for this test case.""" 91 return self._bin_host_path 92