blob: 65b54de7d82dff171dfb0d2569aac5ad707a22c7 [file] [log] [blame]
Pawan0ecf99d2022-09-12 23:20:53 +00001#!/usr/bin/env python3
2#
3# Copyright 2022 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
17import logging
18import json
19import sys
20import os
21import argparse
22
23def check_file_exists(file_name):
24 if not os.path.exists(file_name):
25 sys.exit("File doesn't exist : {0}".format(file_name))
26
27def read_bindings(binding_file):
28 check_file_exists(binding_file)
29 with open(binding_file) as jsonFile:
30 bindings = json.loads(jsonFile.read())
31 return bindings
32
33def check_fuzzer_exists(context_file, bindings):
34 with open(context_file) as file:
35 for line in file:
36 # Ignore empty lines and comments
37 line = line.strip()
38 if line.startswith("#"):
39 logging.debug("Found a comment..skipping")
40 continue
41
42 tokens = line.split()
43 if len(tokens) == 0:
44 logging.debug("Skipping empty lines in service_contexts")
45 continue
46
47 # For a valid service_context file, there will be only two tokens
48 # First will be service name and second will be its label.
49 service_name = tokens[0]
50 if service_name not in bindings:
Pawan588ebd52022-09-14 23:34:05 +000051 sys.exit("\nerror: Service '{0}' is being added, but we have no fuzzer on file for it. "
Pawan0ecf99d2022-09-12 23:20:53 +000052 "Fuzzers are listed at $ANDROID_BUILD_TOP/system/sepolicy/build/soong/service_fuzzer_bindings.go \n\n"
Pawan Waghab859472024-08-15 00:20:41 +000053 "NOTE: automatic service fuzzers are currently not supported in Java (b/287102710.)"
54 "In this case, please ignore this for now and add an entry for your"
Pawan Wagha103fde2022-09-28 19:38:31 +000055 "new service in service_fuzzer_bindings.go \n\n"
Pawan0ecf99d2022-09-12 23:20:53 +000056 "If you are writing a new service, it may be subject to attack from other "
57 "potentially malicious processes. A fuzzer can be written automatically "
58 "by adding these things: \n"
59 "- a cc_fuzz Android.bp entry \n"
60 "- a main file that constructs your service and calls 'fuzzService' \n\n"
Pawan588ebd52022-09-14 23:34:05 +000061 "An examples can be found here: \n"
62 "- $ANDROID_BUILD_TOP/hardware/interfaces/vibrator/aidl/default/fuzzer.cpp \n"
63 "- https://source.android.com/docs/core/architecture/aidl/aidl-fuzzing \n\n"
Pawan0ecf99d2022-09-12 23:20:53 +000064 "This is only ~30 lines of configuration. It requires dependency injection "
65 "for your service which is a good practice, and (in AOSP) you will get bugs "
66 "automatically filed on you. You will find out about issues without needing "
67 "to backport changes years later, and the system will automatically find ways "
68 "to reproduce difficult to solve issues for you. \n\n"
Pawan Wagha103fde2022-09-28 19:38:31 +000069 "This error can be bypassed by adding entry "
70 "for new service in $ANDROID_BUILD_TOP/system/sepolicy/build/soong/service_fuzzer_bindings.go \n\n"
Pawan0ecf99d2022-09-12 23:20:53 +000071 "- Android Fuzzing and Security teams".format(service_name))
72 return
73
74def validate_bindings(args):
75 bindings = read_bindings(args.bindings)
76 for file in args.srcs:
77 check_file_exists(file)
78 check_fuzzer_exists(file, bindings)
79 return
80
81def get_args():
82 parser = argparse.ArgumentParser(description="Tool to check if fuzzer is "
83 "added for new services")
84 parser.add_argument('-b', help='Path to json file containing '
85 '"service":[fuzzers...] bindings.',
86 required=True, dest='bindings')
87 parser.add_argument('-s', '--list', nargs='+',
88 help='list of service_contexts files. Tool will check if '
89 'there is fuzzer for every service in the context '
90 'file.', required=True, dest='srcs')
91 parsed_args = parser.parse_args()
92 return parsed_args
93
94if __name__ == "__main__":
95 args = get_args()
96 validate_bindings(args)