sepolicy : Recommend fuzzers for new services

Adding soong module and tool to check if there is fuzzer present
for every service in private/service_contexts. Whenever a service is
added, its is recommended to update
$ANDROID_BUILD_TOP/system/sepolicy/soong/build/service_fuzzer_bindings.go
with service name and its corresponding fuzzer.

Test: m
Bug: 242104782
Change-Id: Id9bc45f50bebf464de7c91c7469d4bb6ff153ebd
diff --git a/Android.mk b/Android.mk
index c3728fd..8f0b37c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -324,6 +324,7 @@
     plat_service_contexts_test \
     plat_hwservice_contexts \
     plat_hwservice_contexts_test \
+    fuzzer_bindings_test \
     plat_bug_map \
     searchpolicy \
 
diff --git a/build/soong/Android.bp b/build/soong/Android.bp
index 99dd662..83b31b4 100644
--- a/build/soong/Android.bp
+++ b/build/soong/Android.bp
@@ -43,6 +43,8 @@
         "sepolicy_neverallow.go",
         "sepolicy_vers.go",
         "versioned_policy.go",
+        "service_fuzzer_bindings.go",
+        "validate_bindings.go",
     ],
     pluginFor: ["soong_build"],
 }
diff --git a/build/soong/service_fuzzer_bindings.go b/build/soong/service_fuzzer_bindings.go
new file mode 100644
index 0000000..7a7f61f
--- /dev/null
+++ b/build/soong/service_fuzzer_bindings.go
@@ -0,0 +1,406 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package selinux
+
+var (
+	ServiceFuzzerBindings = map[string][]string{
+		"android.hardware.audio.core.IConfig/default":                             []string{},
+		"android.hardware.audio.core.IModule/default":                             []string{},
+		"android.hardware.audio.effect.IFactory/default":                          []string{},
+		"android.hardware.authsecret.IAuthSecret/default":                         []string{},
+		"android.hardware.automotive.evs.IEvsEnumerator/hw/0":                     []string{},
+		"android.hardware.boot.IBootControl/default":                              []string{},
+		"android.hardware.automotive.evs.IEvsEnumerator/hw/1":                     []string{},
+		"android.hardware.automotive.vehicle.IVehicle/default":                    []string{},
+		"android.hardware.automotive.audiocontrol.IAudioControl/default":          []string{},
+		"android.hardware.biometrics.face.IFace/default":                          []string{},
+		"android.hardware.biometrics.fingerprint.IFingerprint/default":            []string{},
+		"android.hardware.biometrics.fingerprint.IFingerprint/virtual":            []string{},
+		"android.hardware.bluetooth.audio.IBluetoothAudioProviderFactory/default": []string{},
+		"android.hardware.camera.provider.ICameraProvider/internal/0":             []string{},
+		"android.hardware.contexthub.IContextHub/default":                         []string{},
+		"android.hardware.drm.IDrmFactory/clearkey":                               []string{},
+		"android.hardware.drm.ICryptoFactory/clearkey":                            []string{},
+		"android.hardware.dumpstate.IDumpstateDevice/default":                     []string{},
+		"android.hardware.gnss.IGnss/default":                                     []string{},
+		"android.hardware.graphics.allocator.IAllocator/default":                  []string{},
+		"android.hardware.graphics.composer3.IComposer/default":                   []string{},
+		"android.hardware.health.storage.IStorage/default":                        []string{},
+		"android.hardware.health.IHealth/default":                                 []string{},
+		"android.hardware.identity.IIdentityCredentialStore/default":              []string{},
+		"android.hardware.input.processor.IInputProcessor/default":                []string{},
+		"android.hardware.ir.IConsumerIr/default":                                 []string{},
+		"android.hardware.light.ILights/default":                                  []string{},
+		"android.hardware.memtrack.IMemtrack/default":                             []string{},
+		"android.hardware.net.nlinterceptor.IInterceptor/default":                 []string{},
+		"android.hardware.nfc.INfc/default":                                       []string{},
+		"android.hardware.oemlock.IOemLock/default":                               []string{},
+		"android.hardware.power.IPower/default":                                   []string{},
+		"android.hardware.power.stats.IPowerStats/default":                        []string{},
+		"android.hardware.radio.config.IRadioConfig/default":                      []string{},
+		"android.hardware.radio.data.IRadioData/slot1":                            []string{},
+		"android.hardware.radio.data.IRadioData/slot2":                            []string{},
+		"android.hardware.radio.data.IRadioData/slot3":                            []string{},
+		"android.hardware.radio.messaging.IRadioMessaging/slot1":                  []string{},
+		"android.hardware.radio.messaging.IRadioMessaging/slot2":                  []string{},
+		"android.hardware.radio.messaging.IRadioMessaging/slot3":                  []string{},
+		"android.hardware.radio.modem.IRadioModem/slot1":                          []string{},
+		"android.hardware.radio.modem.IRadioModem/slot2":                          []string{},
+		"android.hardware.radio.modem.IRadioModem/slot3":                          []string{},
+		"android.hardware.radio.network.IRadioNetwork/slot1":                      []string{},
+		"android.hardware.radio.network.IRadioNetwork/slot2":                      []string{},
+		"android.hardware.radio.network.IRadioNetwork/slot3":                      []string{},
+		"android.hardware.radio.sim.IRadioSim/slot1":                              []string{},
+		"android.hardware.radio.sim.IRadioSim/slot2":                              []string{},
+		"android.hardware.radio.sim.IRadioSim/slot3":                              []string{},
+		"android.hardware.radio.voice.IRadioVoice/slot1":                          []string{},
+		"android.hardware.radio.voice.IRadioVoice/slot2":                          []string{},
+		"android.hardware.radio.voice.IRadioVoice/slot3":                          []string{},
+		"android.hardware.rebootescrow.IRebootEscrow/default":                     []string{},
+		"android.hardware.security.dice.IDiceDevice/default":                      []string{},
+		"android.hardware.security.keymint.IKeyMintDevice/default":                []string{},
+		"android.hardware.security.keymint.IRemotelyProvisionedComponent/default": []string{},
+		"android.hardware.security.secureclock.ISecureClock/default":              []string{},
+		"android.hardware.security.sharedsecret.ISharedSecret/default":            []string{},
+		"android.hardware.sensors.ISensors/default":                               []string{},
+		"android.hardware.soundtrigger3.ISoundTriggerHw/default":                  []string{},
+		"android.hardware.tv.input.ITvInput/default":                              []string{},
+		"android.hardware.tv.tuner.ITuner/default":                                []string{},
+		"android.hardware.usb.IUsb/default":                                       []string{},
+		"android.hardware.uwb.IUwb/default":                                       []string{},
+		"android.hardware.vibrator.IVibrator/default":                             []string{},
+		"android.hardware.vibrator.IVibratorManager/default":                      []string{},
+		"android.hardware.weaver.IWeaver/default":                                 []string{},
+		"android.hardware.wifi.hostapd.IHostapd/default":                          []string{},
+		"android.hardware.wifi.supplicant.ISupplicant/default":                    []string{},
+		"android.frameworks.stats.IStats/default":                                 []string{},
+		"android.se.omapi.ISecureElementService/default":                          []string{},
+		"android.system.keystore2.IKeystoreService/default":                       []string{},
+		"android.system.net.netd.INetd/default":                                   []string{},
+		"android.system.suspend.ISystemSuspend/default":                           []string{},
+		"accessibility":      []string{},
+		"account":            []string{},
+		"activity":           []string{},
+		"activity_task":      []string{},
+		"adb":                []string{},
+		"adservices_manager": []string{},
+		"aidl_lazy_test_1":   []string{},
+		"aidl_lazy_test_2":   []string{},
+		"aidl_lazy_cb_test":  []string{},
+		"alarm":              []string{},
+		"android.hardware.automotive.evs.IEvsEnumerator/default":          []string{},
+		"android.os.UpdateEngineService":                                  []string{},
+		"android.os.UpdateEngineStableService":                            []string{},
+		"android.frameworks.automotive.display.ICarDisplayProxy/default":  []string{},
+		"android.security.apc":                                            []string{},
+		"android.security.authorization":                                  []string{},
+		"android.security.compat":                                         []string{},
+		"android.security.dice.IDiceMaintenance":                          []string{},
+		"android.security.dice.IDiceNode":                                 []string{},
+		"android.security.identity":                                       []string{},
+		"android.security.keystore":                                       []string{},
+		"android.security.legacykeystore":                                 []string{},
+		"android.security.maintenance":                                    []string{},
+		"android.security.metrics":                                        []string{},
+		"android.security.remoteprovisioning":                             []string{},
+		"android.security.remoteprovisioning.IRemotelyProvisionedKeyPool": []string{},
+		"android.service.gatekeeper.IGateKeeperService":                   []string{},
+		"android.system.composd":                                          []string{},
+		"android.system.virtualizationservice":                            []string{},
+		"ambient_context":                                                 []string{},
+		"app_binding":                                                     []string{},
+		"app_hibernation":                                                 []string{},
+		"app_integrity":                                                   []string{},
+		"app_prediction":                                                  []string{},
+		"app_search":                                                      []string{},
+		"apexservice":                                                     []string{},
+		"attestation_verification":                                        []string{},
+		"blob_store":                                                      []string{},
+		"gsiservice":                                                      []string{},
+		"appops":                                                          []string{},
+		"appwidget":                                                       []string{},
+		"artd":                                                            []string{},
+		"assetatlas":                                                      []string{},
+		"attention":                                                       []string{},
+		"audio":                                                           []string{},
+		"auth":                                                            []string{},
+		"autofill":                                                        []string{},
+		"backup":                                                          []string{},
+		"batteryproperties":                                               []string{},
+		"batterystats":                                                    []string{},
+		"battery":                                                         []string{},
+		"binder_calls_stats":                                              []string{},
+		"biometric":                                                       []string{},
+		"bluetooth_manager":                                               []string{},
+		"bluetooth":                                                       []string{},
+		"broadcastradio":                                                  []string{},
+		"bugreport":                                                       []string{},
+		"cacheinfo":                                                       []string{},
+		"carrier_config":                                                  []string{},
+		"clipboard":                                                       []string{},
+		"cloudsearch":                                                     []string{},
+		"cloudsearch_service":                                             []string{},
+		"com.android.net.IProxyService":                                   []string{},
+		"companiondevice":                                                 []string{},
+		"communal":                                                        []string{},
+		"platform_compat":                                                 []string{},
+		"platform_compat_native":                                          []string{},
+		"connectivity":                                                    []string{},
+		"connectivity_native":                                             []string{},
+		"connmetrics":                                                     []string{},
+		"consumer_ir":                                                     []string{},
+		"content":                                                         []string{},
+		"content_capture":                                                 []string{},
+		"content_suggestions":                                             []string{},
+		"contexthub":                                                      []string{},
+		"country_detector":                                                []string{},
+		"coverage":                                                        []string{},
+		"cpuinfo":                                                         []string{},
+		"crossprofileapps":                                                []string{},
+		"dataloader_manager":                                              []string{},
+		"dbinfo":                                                          []string{},
+		"device_config":                                                   []string{},
+		"device_policy":                                                   []string{},
+		"device_identifiers":                                              []string{},
+		"deviceidle":                                                      []string{},
+		"device_state":                                                    []string{},
+		"devicestoragemonitor":                                            []string{},
+		"diskstats":                                                       []string{},
+		"display":                                                         []string{},
+		"dnsresolver":                                                     []string{},
+		"domain_verification":                                             []string{},
+		"color_display":                                                   []string{},
+		"netd_listener":                                                   []string{},
+		"network_watchlist":                                               []string{},
+		"DockObserver":                                                    []string{},
+		"dreams":                                                          []string{},
+		"drm.drmManager":                                                  []string{},
+		"dropbox":                                                         []string{},
+		"dumpstate":                                                       []string{},
+		"dynamic_system":                                                  []string{},
+		"econtroller":                                                     []string{},
+		"emergency_affordance":                                            []string{},
+		"euicc_card_controller":                                           []string{},
+		"external_vibrator_service":                                       []string{},
+		"ethernet":                                                        []string{},
+		"face":                                                            []string{},
+		"file_integrity":                                                  []string{},
+		"fingerprint":                                                     []string{},
+		"font":                                                            []string{},
+		"android.hardware.fingerprint.IFingerprintDaemon": []string{},
+		"game":                         []string{},
+		"gfxinfo":                      []string{},
+		"gnss_time_update_service":     []string{},
+		"graphicsstats":                []string{},
+		"gpu":                          []string{},
+		"hardware":                     []string{},
+		"hardware_properties":          []string{},
+		"hdmi_control":                 []string{},
+		"ions":                         []string{},
+		"idmap":                        []string{},
+		"incident":                     []string{},
+		"incidentcompanion":            []string{},
+		"inputflinger":                 []string{},
+		"input_method":                 []string{},
+		"input":                        []string{},
+		"installd":                     []string{},
+		"iphonesubinfo_msim":           []string{},
+		"iphonesubinfo2":               []string{},
+		"iphonesubinfo":                []string{},
+		"ims":                          []string{},
+		"imms":                         []string{},
+		"incremental":                  []string{},
+		"ipsec":                        []string{},
+		"ircsmessage":                  []string{},
+		"iris":                         []string{},
+		"isms_msim":                    []string{},
+		"isms2":                        []string{},
+		"isms":                         []string{},
+		"isub":                         []string{},
+		"jobscheduler":                 []string{},
+		"launcherapps":                 []string{},
+		"legacy_permission":            []string{},
+		"lights":                       []string{},
+		"locale":                       []string{},
+		"location":                     []string{},
+		"location_time_zone_manager":   []string{},
+		"lock_settings":                []string{},
+		"logcat":                       []string{},
+		"logd":                         []string{},
+		"looper_stats":                 []string{},
+		"lpdump_service":               []string{},
+		"mdns":                         []string{},
+		"media.aaudio":                 []string{},
+		"media.audio_flinger":          []string{},
+		"media.audio_policy":           []string{},
+		"media.camera":                 []string{},
+		"media.camera.proxy":           []string{},
+		"media.log":                    []string{},
+		"media.player":                 []string{},
+		"media.metrics":                []string{},
+		"media.extractor":              []string{},
+		"media.transcoding":            []string{},
+		"media.resource_manager":       []string{},
+		"media.resource_observer":      []string{},
+		"media.sound_trigger_hw":       []string{},
+		"media.drm":                    []string{},
+		"media.tuner":                  []string{},
+		"media_communication":          []string{},
+		"media_metrics":                []string{},
+		"media_projection":             []string{},
+		"media_resource_monitor":       []string{},
+		"media_router":                 []string{},
+		"media_session":                []string{},
+		"meminfo":                      []string{},
+		"memtrack.proxy":               []string{},
+		"midi":                         []string{},
+		"mount":                        []string{},
+		"music_recognition":            []string{},
+		"nearby":                       []string{},
+		"netd":                         []string{},
+		"netpolicy":                    []string{},
+		"netstats":                     []string{},
+		"network_stack":                []string{},
+		"network_management":           []string{},
+		"network_score":                []string{},
+		"network_time_update_service":  []string{},
+		"nfc":                          []string{},
+		"notification":                 []string{},
+		"oem_lock":                     []string{},
+		"otadexopt":                    []string{},
+		"overlay":                      []string{},
+		"pac_proxy":                    []string{},
+		"package":                      []string{},
+		"package_native":               []string{},
+		"people":                       []string{},
+		"performance_hint":             []string{},
+		"permission":                   []string{},
+		"permissionmgr":                []string{},
+		"permission_checker":           []string{},
+		"persistent_data_block":        []string{},
+		"phone_msim":                   []string{},
+		"phone1":                       []string{},
+		"phone2":                       []string{},
+		"phone":                        []string{},
+		"pinner":                       []string{},
+		"powerstats":                   []string{},
+		"power":                        []string{},
+		"print":                        []string{},
+		"processinfo":                  []string{},
+		"procstats":                    []string{},
+		"profcollectd":                 []string{},
+		"radio.phonesubinfo":           []string{},
+		"radio.phone":                  []string{},
+		"radio.sms":                    []string{},
+		"rcs":                          []string{},
+		"reboot_readiness":             []string{},
+		"recovery":                     []string{},
+		"resolver":                     []string{},
+		"resources":                    []string{},
+		"restrictions":                 []string{},
+		"role":                         []string{},
+		"rollback":                     []string{},
+		"rttmanager":                   []string{},
+		"runtime":                      []string{},
+		"safety_center":                []string{},
+		"samplingprofiler":             []string{},
+		"scheduling_policy":            []string{},
+		"search":                       []string{},
+		"search_ui":                    []string{},
+		"secure_element":               []string{},
+		"sec_key_att_app_id_provider":  []string{},
+		"selection_toolbar":            []string{},
+		"sensorservice":                []string{},
+		"sensor_privacy":               []string{},
+		"serial":                       []string{},
+		"servicediscovery":             []string{},
+		"manager":                      []string{},
+		"settings":                     []string{},
+		"shortcut":                     []string{},
+		"simphonebook_msim":            []string{},
+		"simphonebook2":                []string{},
+		"simphonebook":                 []string{},
+		"sip":                          []string{},
+		"slice":                        []string{},
+		"smartspace":                   []string{},
+		"speech_recognition":           []string{},
+		"stats":                        []string{},
+		"statsbootstrap":               []string{},
+		"statscompanion":               []string{},
+		"statsmanager":                 []string{},
+		"soundtrigger":                 []string{},
+		"soundtrigger_middleware":      []string{},
+		"statusbar":                    []string{},
+		"storaged":                     []string{},
+		"storaged_pri":                 []string{},
+		"storagestats":                 []string{},
+		"sdk_sandbox":                  []string{},
+		"SurfaceFlinger":               []string{},
+		"SurfaceFlingerAIDL":           []string{},
+		"suspend_control":              []string{},
+		"suspend_control_internal":     []string{},
+		"system_config":                []string{},
+		"system_server_dumper":         []string{},
+		"system_update":                []string{},
+		"tare":                         []string{},
+		"task":                         []string{},
+		"telecom":                      []string{},
+		"telephony.registry":           []string{},
+		"telephony_ims":                []string{},
+		"testharness":                  []string{},
+		"tethering":                    []string{},
+		"textclassification":           []string{},
+		"textservices":                 []string{},
+		"texttospeech":                 []string{},
+		"time_detector":                []string{},
+		"time_zone_detector":           []string{},
+		"thermalservice":               []string{},
+		"tracing.proxy":                []string{},
+		"translation":                  []string{},
+		"transparency":                 []string{},
+		"trust":                        []string{},
+		"tv_interactive_app":           []string{},
+		"tv_input":                     []string{},
+		"tv_tuner_resource_mgr":        []string{},
+		"uce":                          []string{},
+		"uimode":                       []string{},
+		"updatelock":                   []string{},
+		"uri_grants":                   []string{},
+		"usagestats":                   []string{},
+		"usb":                          []string{},
+		"user":                         []string{},
+		"uwb":                          []string{},
+		"vcn_management":               []string{},
+		"vibrator":                     []string{},
+		"vibrator_manager":             []string{},
+		"virtualdevice":                []string{},
+		"virtual_touchpad":             []string{},
+		"voiceinteraction":             []string{},
+		"vold":                         []string{},
+		"vpn_management":               []string{},
+		"vrmanager":                    []string{},
+		"wallpaper":                    []string{},
+		"wallpaper_effects_generation": []string{},
+		"webviewupdate":                []string{},
+		"wifip2p":                      []string{},
+		"wifiscanner":                  []string{},
+		"wifi":                         []string{},
+		"wifinl80211":                  []string{},
+		"wifiaware":                    []string{},
+		"wifirtt":                      []string{},
+		"window":                       []string{},
+		"*":                            []string{},
+	}
+)
diff --git a/build/soong/validate_bindings.go b/build/soong/validate_bindings.go
new file mode 100644
index 0000000..3132453
--- /dev/null
+++ b/build/soong/validate_bindings.go
@@ -0,0 +1,109 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package selinux
+
+import (
+	"encoding/json"
+	"fmt"
+
+	"android/soong/android"
+)
+
+func init() {
+	android.RegisterModuleType("fuzzer_bindings_test", fuzzerBindingsTestFactory)
+	android.PreArchMutators(registerFuzzerMutators)
+}
+
+func registerFuzzerMutators(ctx android.RegisterMutatorsContext) {
+	ctx.BottomUp("addFuzzerConfigDeps", addFuzzerConfigDeps).Parallel()
+}
+
+func addFuzzerConfigDeps(ctx android.BottomUpMutatorContext) {
+	if _, ok := ctx.Module().(*fuzzerBindingsTestModule); ok {
+		for _, fuzzers := range ServiceFuzzerBindings {
+			for _, fuzzer := range fuzzers {
+				if !ctx.OtherModuleExists(fuzzer) {
+					panic(fmt.Errorf("Fuzzer doesn't exist : %s", fuzzer))
+				}
+			}
+		}
+	}
+}
+
+type bindingsTestProperties struct {
+	// Contexts files to be tested.
+	Srcs []string `android:"path"`
+}
+
+type fuzzerBindingsTestModule struct {
+	android.ModuleBase
+	tool          string
+	properties    bindingsTestProperties
+	testTimestamp android.ModuleOutPath
+}
+
+// fuzzer_bindings_test checks if a fuzzer is implemented for every service in service_contexts
+func fuzzerBindingsTestFactory() android.Module {
+	m := &fuzzerBindingsTestModule{tool: "fuzzer_bindings_check"}
+	m.AddProperties(&m.properties)
+	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+	return m
+}
+
+func (m *fuzzerBindingsTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	tool := m.tool
+	if tool != "fuzzer_bindings_check" {
+		panic(fmt.Errorf("%q: unknown tool name: %q", ctx.ModuleName(), tool))
+	}
+
+	if len(m.properties.Srcs) == 0 {
+		ctx.PropertyErrorf("srcs", "can't be empty")
+		return
+	}
+
+	// Generate a json file which contains existing bindings
+	rootPath := android.PathForIntermediates(ctx, "bindings.json")
+	jsonString, parseError := json.Marshal(ServiceFuzzerBindings)
+	if parseError != nil {
+		panic(fmt.Errorf("Error while marshalling ServiceFuzzerBindings dict. Check Format"))
+	}
+	android.WriteFileRule(ctx, rootPath, string(jsonString))
+
+	//input module json, service context and binding files here
+	srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs)
+	rule := android.NewRuleBuilder(pctx, ctx)
+
+	rule.Command().BuiltTool(tool).Flag("-s").Inputs(srcs).Flag("-b").Input(rootPath)
+
+	// Every Soong module needs to generate an output even if it doesn't require it
+	m.testTimestamp = android.PathForModuleOut(ctx, "timestamp")
+	rule.Command().Text("touch").Output(m.testTimestamp)
+	rule.Build("fuzzer_bindings_test", "running service:fuzzer bindings test: "+ctx.ModuleName())
+}
+
+func (m *fuzzerBindingsTestModule) AndroidMkEntries() []android.AndroidMkEntries {
+	return []android.AndroidMkEntries{android.AndroidMkEntries{
+		Class: "FAKE",
+		// OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it.
+		// Without OutputFile this module won't be exported to Makefile.
+		OutputFile: android.OptionalPathForPath(m.testTimestamp),
+		Include:    "$(BUILD_PHONY_PACKAGE)",
+		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+				entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", m.testTimestamp.String())
+			},
+		},
+	}}
+}
diff --git a/contexts/Android.bp b/contexts/Android.bp
index 04a0c11..82f42ba 100644
--- a/contexts/Android.bp
+++ b/contexts/Android.bp
@@ -520,3 +520,8 @@
     srcs: [":vndservice_contexts"],
     sepolicy: ":precompiled_sepolicy",
 }
+
+fuzzer_bindings_test {
+    name: "fuzzer_bindings_test",
+    srcs: [":plat_service_contexts"],
+}
diff --git a/tools/Android.bp b/tools/Android.bp
index 8e40575..057b073 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -77,3 +77,8 @@
     libs: ["mini_cil_parser", "pysepolwrap"],
     data: [":libsepolwrap"],
 }
+
+python_binary_host {
+    name: "fuzzer_bindings_check",
+    srcs: ["fuzzer_bindings_check.py"],
+}
diff --git a/tools/README b/tools/README
index 5e340a0..8976c68 100644
--- a/tools/README
+++ b/tools/README
@@ -70,3 +70,15 @@
 sepolicy-analyze
     A tool for performing various kinds of analysis on a sepolicy
     file.
+
+fuzzer_bindings_check
+    Tool to check if fuzzer is added for new services. it is used by fuzzer_bindings_test soong module internally.
+    Error will be generated if there is no fuzzer binding present for service added in service_contexts in
+    system/sepolicy/soong/build/service_fuzzer_bindings.go
+
+    Usage:
+    fuzzer_bindings_check.py -s [SRCs...] -b /path/to/binding.json
+
+    -s [SRCs...]                         list of service_contexts files. Tool will check if there is fuzzer for every service
+                                         in the context file.
+    -b /path/to/binding.json             Path to json file containing "service":[fuzzers...] bindings.
diff --git a/tools/fuzzer_bindings_check.py b/tools/fuzzer_bindings_check.py
new file mode 100644
index 0000000..d2cc3ae
--- /dev/null
+++ b/tools/fuzzer_bindings_check.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+import json
+import sys
+import os
+import argparse
+
+def check_file_exists(file_name):
+  if not os.path.exists(file_name):
+    sys.exit("File doesn't exist : {0}".format(file_name))
+
+def read_bindings(binding_file):
+  check_file_exists(binding_file)
+  with open(binding_file) as jsonFile:
+   bindings = json.loads(jsonFile.read())
+  return bindings
+
+def check_fuzzer_exists(context_file, bindings):
+  with open(context_file) as file:
+    for line in file:
+       # Ignore empty lines and comments
+       line = line.strip()
+       if line.startswith("#"):
+         logging.debug("Found a comment..skipping")
+         continue
+
+       tokens = line.split()
+       if len(tokens) == 0:
+         logging.debug("Skipping empty lines in service_contexts")
+         continue
+
+       # For a valid service_context file, there will be only two tokens
+       # First will be service name and second will be its label.
+       service_name = tokens[0]
+       if service_name not in bindings:
+         sys.exit("\nerror: Service {0} is being added, but we have no fuzzer on file for it. "
+                  "Fuzzers are listed at $ANDROID_BUILD_TOP/system/sepolicy/build/soong/service_fuzzer_bindings.go \n\n"
+                  "NOTE: automatic service fuzzers are currently not supported in Java (b/232439254) "
+                  "and Rust (b/164122727). In this case, please ignore this for now. \n\n"
+                  "If you are writing a new service, it may be subject to attack from other "
+                  "potentially malicious processes. A fuzzer can be written automatically "
+                  "by adding these things: \n"
+                  "- a cc_fuzz Android.bp entry \n"
+                  "- a main file that constructs your service and calls 'fuzzService' \n\n"
+                  "An example can be found here: \n "
+                  "$ANDROID_BUILD_TOP/hardware/interfaces/vibrator/aidl/default/fuzzer.cpp \n\n"
+                  "This is only ~30 lines of configuration. It requires dependency injection "
+                  "for your service which is a good practice, and (in AOSP) you will get bugs "
+                  "automatically filed on you. You will find out about issues without needing "
+                  "to backport changes years later, and the system will automatically find ways "
+                  "to reproduce difficult to solve issues for you. \n\n"
+                  "- Android Fuzzing and Security teams".format(service_name))
+  return
+
+def validate_bindings(args):
+  bindings = read_bindings(args.bindings)
+  for file in args.srcs:
+    check_file_exists(file)
+    check_fuzzer_exists(file, bindings)
+  return
+
+def get_args():
+  parser =  argparse.ArgumentParser(description="Tool to check if fuzzer is "
+                                                "added for new services")
+  parser.add_argument('-b', help='Path to json file containing '
+                                 '"service":[fuzzers...] bindings.',
+                      required=True, dest='bindings')
+  parser.add_argument('-s', '--list', nargs='+',
+                      help='list of service_contexts files. Tool will check if '
+                           'there is fuzzer for every service in the context '
+                           'file.', required=True, dest='srcs')
+  parsed_args = parser.parse_args()
+  return parsed_args
+
+if __name__ == "__main__":
+  args = get_args()
+  validate_bindings(args)