Merge "Add overlay support for hostapd" into main
diff --git a/hostapd/aidl/hostapd.cpp b/hostapd/aidl/hostapd.cpp
index 58963cb..12d0d9e 100644
--- a/hostapd/aidl/hostapd.cpp
+++ b/hostapd/aidl/hostapd.cpp
@@ -1136,6 +1136,12 @@
 	return setDebugParamsInternal(level);
 }
 
+::ndk::ScopedAStatus Hostapd::removeLinkFromMultipleLinkBridgedApIface(
+        const std::string& iface_name, const std::string& linkIdentity)
+{
+	return removeLinkFromMultipleLinkBridgedApIfaceInternal(iface_name, linkIdentity);
+}
+
 ::ndk::ScopedAStatus Hostapd::addAccessPointInternal(
 	const IfaceParams& iface_params,
 	const NetworkParams& nw_params)
@@ -1580,6 +1586,23 @@
 	return ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus Hostapd::removeLinkFromMultipleLinkBridgedApIfaceInternal(
+const std::string& iface_name, const std::string& linkIdentity)
+{
+	if (!hostapd_get_iface(interfaces_, iface_name.c_str())) {
+		wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	struct hostapd_data* iface_hapd =
+		hostapd_get_iface_by_link_id(interfaces_, (size_t) linkIdentity.c_str());
+	if (iface_hapd) {
+		if (0 == hostapd_link_remove(iface_hapd, 1)) {
+			return ndk::ScopedAStatus::ok();
+		}
+	}
+	return createStatus(HostapdStatusCode::FAILURE_ARGS_INVALID);
+}
+
 }  // namespace hostapd
 }  // namespace wifi
 }  // namespace hardware
diff --git a/hostapd/aidl/hostapd.h b/hostapd/aidl/hostapd.h
index ffdbd8e..ba47810 100644
--- a/hostapd/aidl/hostapd.h
+++ b/hostapd/aidl/hostapd.h
@@ -55,6 +55,8 @@
 	    const std::vector<uint8_t>& client_address,
 	    Ieee80211ReasonCode reason_code) override;
 	::ndk::ScopedAStatus setDebugParams(DebugLevel level) override;
+	::ndk::ScopedAStatus removeLinkFromMultipleLinkBridgedApIface(
+		const std::string& iface_name, const std::string& linkIdentity) override;
 private:
 	// Corresponding worker functions for the AIDL methods.
 	::ndk::ScopedAStatus addAccessPointInternal(
@@ -77,7 +79,8 @@
 	    const std::vector<uint8_t>& client_address,
 	    Ieee80211ReasonCode reason_code);
 	::ndk::ScopedAStatus setDebugParamsInternal(DebugLevel level);
-
+	::ndk::ScopedAStatus removeLinkFromMultipleLinkBridgedApIfaceInternal(
+		const std::string& iface_name, const std::string& linkIdentity);
 	// Raw pointer to the global structure maintained by the core.
 	struct hapd_interfaces* interfaces_;
 	// Callbacks registered.
diff --git a/wpa_supplicant/Android.bp b/wpa_supplicant/Android.bp
index 210325b..f66d45b 100644
--- a/wpa_supplicant/Android.bp
+++ b/wpa_supplicant/Android.bp
@@ -1016,9 +1016,6 @@
     }) + select(soong_config_variable("wpa_supplicant_8", "board_hostapd_config_80211w_mfp_optional"), {
         true: ["-DENABLE_HOSTAPD_CONFIG_80211W_MFP_OPTIONAL"],
         default: [],
-    }) + select(soong_config_variable("wpa_supplicant_8", "board_wpa_supplicant_private_lib_event"), {
-        true: ["-DANDROID_LIB_EVENT"],
-        default: [],
     }) + select(soong_config_variable("wpa_supplicant_8", "wifi_priv_cmd_update_mbo_cell_status"), {
         true: ["-DENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS"],
         default: [],
@@ -1422,6 +1419,45 @@
     ],
 }
 
+cc_fuzz {
+    name: "mainline_supplicant_service_fuzzer",
+    team: "trendy_team_fwk_wifi_hal",
+    srcs: [
+        "aidl/mainline/fuzzers/mainline_supplicant_service_fuzzer.cpp",
+    ],
+    defaults: [
+        "fuzzer_disable_leaks",
+        "service_fuzzer_defaults",
+        "wpa_supplicant_includes_default",
+        "wpa_supplicant_mainline_cflags_default",
+        "wpa_supplicant_srcs_default",
+    ],
+    shared_libs: [
+        "android.system.wifi.mainline_supplicant-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libc",
+        "libcrypto",
+        "libcutils_sockets",
+        "liblog",
+        "libnl",
+        "libssl",
+    ],
+    static_libs: [
+        "mainline_supplicant_aidl_bp",
+    ],
+    cflags: [
+        "-DSUPPLICANT_SERVICE_FUZZER",
+    ],
+    fuzz_config: {
+        triage_assignee: "android-wifi-team@google.com",
+    },
+    proto: {
+        type: "lite",
+        static: true,
+    },
+}
+
 //## Aidl service library ###
 //#######################
 cc_library_static {
diff --git a/wpa_supplicant/aidl/mainline/fuzzers/mainline_supplicant_service_fuzzer.cpp b/wpa_supplicant/aidl/mainline/fuzzers/mainline_supplicant_service_fuzzer.cpp
new file mode 100644
index 0000000..23b16ad
--- /dev/null
+++ b/wpa_supplicant/aidl/mainline/fuzzers/mainline_supplicant_service_fuzzer.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#include <android/binder_interface_utils.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+
+#include "aidl/mainline/mainline_supplicant.h"
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "utils/wpa_debug.h"
+#include "wpa_supplicant_i.h"
+}
+
+using namespace android;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    struct wpa_params params;
+    os_memset(&params, 0, sizeof(params));
+    params.wpa_debug_level = MSG_INFO;
+
+    struct wpa_global *global = wpa_supplicant_init(&params);
+    if (global == NULL) {
+        return 1;
+    }
+
+    std::shared_ptr<MainlineSupplicant> service = SharedRefBase::make<MainlineSupplicant>(global);
+    fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+    return 0;
+}
diff --git a/wpa_supplicant/aidl/vendor/p2p_iface.cpp b/wpa_supplicant/aidl/vendor/p2p_iface.cpp
index 81bf3f1..b1cd1cd 100644
--- a/wpa_supplicant/aidl/vendor/p2p_iface.cpp
+++ b/wpa_supplicant/aidl/vendor/p2p_iface.cpp
@@ -858,7 +858,7 @@
 ::ndk::ScopedAStatus P2pIface::getFeatureSet(int64_t* _aidl_return)
 {
 	return validateAndCall(
-		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
 		&P2pIface::getFeatureSetInternal, _aidl_return);
 }
 
@@ -867,7 +867,7 @@
 		int32_t* _aidl_return)
 {
 	return validateAndCall(
-		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
 		&P2pIface::startUsdBasedServiceDiscoveryInternal, _aidl_return,
 		in_serviceDiscoveryConfig);
 }
@@ -884,7 +884,7 @@
 		int32_t* _aidl_return)
 {
 	return validateAndCall(
-		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
 		&P2pIface::startUsdBasedServiceAdvertisementInternal, _aidl_return,
 		in_serviceAdvertisementConfig);
 }
@@ -904,6 +904,29 @@
 		&P2pIface::provisionDiscoveryWithParamsInternal, in_params);
 }
 
+::ndk::ScopedAStatus P2pIface::getDirInfo(P2pDirInfo* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getDirInfoInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::validateDirInfo(const P2pDirInfo& in_dirInfo,
+		int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::validateDirInfoInternal, _aidl_return, in_dirInfo);
+}
+
+::ndk::ScopedAStatus P2pIface::reinvokePersistentGroup(
+		const P2pReinvokePersistentGroupParams& in_reinvokeGroupParams)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::reinvokePersistentGroupInternal, in_reinvokeGroupParams);
+}
+
 std::pair<std::string, ndk::ScopedAStatus> P2pIface::getNameInternal()
 {
 	return {ifname_, ndk::ScopedAStatus::ok()};
@@ -2045,6 +2068,27 @@
 	return ndk::ScopedAStatus::ok();
 }
 
+std::pair<P2pDirInfo, ndk::ScopedAStatus> P2pIface::getDirInfoInternal()
+{
+	// TODO Fill the field when supplicant implementation is ready
+	P2pDirInfo dirInfo = {};
+	return {dirInfo, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> P2pIface::validateDirInfoInternal(
+	const P2pDirInfo& dirInfo)
+{
+	// TODO Fill the field when supplicant implementation is ready
+	return {0, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::reinvokePersistentGroupInternal(
+	const P2pReinvokePersistentGroupParams& reinvokeGroupParams)
+{
+	// TODO Fill the field when supplicant implementation is ready
+	return ndk::ScopedAStatus::ok();
+}
+
 /**
  * Retrieve the underlying |wpa_supplicant| struct
  * pointer for this iface.
diff --git a/wpa_supplicant/aidl/vendor/p2p_iface.h b/wpa_supplicant/aidl/vendor/p2p_iface.h
index 840878e..545a6c9 100644
--- a/wpa_supplicant/aidl/vendor/p2p_iface.h
+++ b/wpa_supplicant/aidl/vendor/p2p_iface.h
@@ -195,6 +195,11 @@
 	::ndk::ScopedAStatus stopUsdBasedServiceAdvertisement(int32_t in_sessionId) override;
 	::ndk::ScopedAStatus provisionDiscoveryWithParams(
 		const P2pProvisionDiscoveryParams& in_params) override;
+	::ndk::ScopedAStatus getDirInfo(P2pDirInfo* _aidl_return) override;
+	::ndk::ScopedAStatus validateDirInfo(const P2pDirInfo &in_dirInfo,
+		int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus reinvokePersistentGroup(
+		const P2pReinvokePersistentGroupParams& in_reinvokeGroupParams) override;
 
 
 private:
@@ -336,6 +341,11 @@
 	::ndk::ScopedAStatus stopUsdBasedServiceAdvertisementInternal(uint32_t sessionId);
 	::ndk::ScopedAStatus provisionDiscoveryWithParamsInternal(
 		const P2pProvisionDiscoveryParams& params);
+	std::pair<P2pDirInfo, ndk::ScopedAStatus> getDirInfoInternal();
+	std::pair<int32_t, ndk::ScopedAStatus> validateDirInfoInternal(
+		const P2pDirInfo& dirInfo);
+	::ndk::ScopedAStatus reinvokePersistentGroupInternal(
+		const P2pReinvokePersistentGroupParams& reinvokeGroupParams);
 
 	struct wpa_supplicant* retrieveIfacePtr();
 	struct wpa_supplicant* retrieveGroupIfacePtr(
diff --git a/wpa_supplicant/aidl/vendor/sta_iface.cpp b/wpa_supplicant/aidl/vendor/sta_iface.cpp
index 3880a1d..1a6ae08 100644
--- a/wpa_supplicant/aidl/vendor/sta_iface.cpp
+++ b/wpa_supplicant/aidl/vendor/sta_iface.cpp
@@ -38,23 +38,10 @@
 using aidl::android::hardware::wifi::supplicant::LegacyMode;
 using aidl::android::hardware::wifi::supplicant::RxFilterType;
 using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
+using aidl::android::hardware::wifi::supplicant::WifiChannelWidthInMhz;
 using aidl::android::hardware::wifi::supplicant::WifiTechnology;
 using aidl::android::hardware::wifi::supplicant::misc_utils::createStatus;
 
-// Enum definition copied from the Vendor HAL interface.
-// See android.hardware.wifi.WifiChannelWidthInMhz
-enum WifiChannelWidthInMhz {
-  WIDTH_20	= 0,
-  WIDTH_40	= 1,
-  WIDTH_80	= 2,
-  WIDTH_160   = 3,
-  WIDTH_80P80 = 4,
-  WIDTH_5	 = 5,
-  WIDTH_10	= 6,
-  WIDTH_320	= 7,
-  WIDTH_INVALID = -1
-};
-
 constexpr uint32_t kMaxAnqpElems = 100;
 constexpr char kGetMacAddress[] = "MACADDR";
 constexpr char kStartRxFilter[] = "RXFILTER-START";
@@ -856,6 +843,58 @@
 		&StaIface::disableMscsInternal);
 }
 
+::ndk::ScopedAStatus StaIface::getUsdCapabilities(UsdCapabilities* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::getUsdCapabilitiesInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::startUsdPublish(int32_t in_cmdId,
+	const UsdPublishConfig& in_usdPublishConfig)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::startUsdPublishInternal, in_usdPublishConfig);
+}
+
+::ndk::ScopedAStatus StaIface::startUsdSubscribe(int32_t in_cmdId,
+	const UsdSubscribeConfig& in_usdSubscribeConfig)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::startUsdSubscribeInternal, in_usdSubscribeConfig);
+}
+
+::ndk::ScopedAStatus StaIface::updateUsdPublish(int32_t in_publishId,
+	const std::vector<uint8_t>& in_serviceSpecificInfo)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::updateUsdPublishInternal, in_publishId, in_serviceSpecificInfo);
+}
+
+::ndk::ScopedAStatus StaIface::cancelUsdPublish(int32_t in_publishId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::cancelUsdPublishInternal, in_publishId);
+}
+
+::ndk::ScopedAStatus StaIface::cancelUsdSubscribe(int32_t in_subscribeId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::cancelUsdSubscribeInternal, in_subscribeId);
+}
+
+::ndk::ScopedAStatus StaIface::sendUsdMessage(const UsdMessageInfo& in_messageInfo)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::sendUsdMessageInternal, in_messageInfo);
+}
+
 std::pair<std::string, ndk::ScopedAStatus> StaIface::getNameInternal()
 {
 	return {ifname_, ndk::ScopedAStatus::ok()};
@@ -1851,32 +1890,32 @@
 			capa.technology = WifiTechnology::LEGACY;
 			if (wpas_freq_to_band(wpa_s->assoc_freq) == BAND_2_4_GHZ) {
 				capa.legacyMode = (wpa_s->connection_11b_only) ? LegacyMode::B_MODE
-						: LegacyMode::G_MODE; 
+						: LegacyMode::G_MODE;
 			} else {
 				capa.legacyMode = LegacyMode::A_MODE;
 			}
 		}
 		switch (wpa_s->connection_channel_bandwidth) {
 		case CHAN_WIDTH_20:
-			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+			capa.channelBandwidth = static_cast<int32_t>(WifiChannelWidthInMhz::WIDTH_20);
 			break;
 		case CHAN_WIDTH_40:
-			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_40;
+			capa.channelBandwidth = static_cast<int32_t>(WifiChannelWidthInMhz::WIDTH_40);
 			break;
 		case CHAN_WIDTH_80:
-			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80;
+			capa.channelBandwidth = static_cast<int32_t>(WifiChannelWidthInMhz::WIDTH_80);
 			break;
 		case CHAN_WIDTH_160:
-			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_160;
+			capa.channelBandwidth = static_cast<int32_t>(WifiChannelWidthInMhz::WIDTH_160);
 			break;
 		case CHAN_WIDTH_80P80:
-			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80P80;
+			capa.channelBandwidth = static_cast<int32_t>(WifiChannelWidthInMhz::WIDTH_80P80);
 			break;
 		case CHAN_WIDTH_320:
-			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_320;
+			capa.channelBandwidth = static_cast<int32_t>(WifiChannelWidthInMhz::WIDTH_320);
 			break;
 		default:
-			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+			capa.channelBandwidth = static_cast<int32_t>(WifiChannelWidthInMhz::WIDTH_20);
 			break;
 		}
 		capa.maxNumberRxSpatialStreams = wpa_s->connection_max_nss_rx;
@@ -1884,7 +1923,7 @@
 		capa.apTidToLinkMapNegotiationSupported = wpa_s->ap_t2lm_negotiation_support;
 	} else {
 		capa.technology = WifiTechnology::UNKNOWN;
-		capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+		capa.channelBandwidth = static_cast<int32_t>(WifiChannelWidthInMhz::WIDTH_20);
 		capa.maxNumberTxSpatialStreams = 1;
 		capa.maxNumberRxSpatialStreams = 1;
 		capa.legacyMode = LegacyMode::UNKNOWN;
@@ -2568,6 +2607,38 @@
 	return ndk::ScopedAStatus::ok();
 }
 
+std::pair<UsdCapabilities, ndk::ScopedAStatus> StaIface::getUsdCapabilitiesInternal() {
+	UsdCapabilities capabilities;
+	return {capabilities, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::startUsdPublishInternal(
+		const UsdPublishConfig& usdPublishConfig) {
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+}
+
+ndk::ScopedAStatus StaIface::startUsdSubscribeInternal(
+		const UsdSubscribeConfig& usdSubscribeConfig) {
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+}
+
+::ndk::ScopedAStatus StaIface::updateUsdPublishInternal(int32_t publishId,
+		const std::vector<uint8_t>& serviceSpecificInfo) {
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+}
+
+::ndk::ScopedAStatus StaIface::cancelUsdPublishInternal(int32_t publishId) {
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+}
+
+::ndk::ScopedAStatus StaIface::cancelUsdSubscribeInternal(int32_t subscribeId) {
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+}
+
+::ndk::ScopedAStatus StaIface::sendUsdMessageInternal(const UsdMessageInfo& messageInfo) {
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+}
+
 /**
  * Retrieve the underlying |wpa_supplicant| struct
  * pointer for this iface.
diff --git a/wpa_supplicant/aidl/vendor/sta_iface.h b/wpa_supplicant/aidl/vendor/sta_iface.h
index b52c6b0..6c6cfb9 100644
--- a/wpa_supplicant/aidl/vendor/sta_iface.h
+++ b/wpa_supplicant/aidl/vendor/sta_iface.h
@@ -167,6 +167,16 @@
 		std::vector<QosPolicyScsRequestStatus>* _aidl_return) override;
 	::ndk::ScopedAStatus configureMscs(const MscsParams& in_params) override;
 	::ndk::ScopedAStatus disableMscs() override;
+	::ndk::ScopedAStatus getUsdCapabilities(UsdCapabilities* _aidl_return);
+	::ndk::ScopedAStatus startUsdPublish(int32_t in_cmdId,
+		const UsdPublishConfig& in_usdPublishConfig);
+	::ndk::ScopedAStatus startUsdSubscribe(int32_t in_cmdId,
+		const UsdSubscribeConfig& in_usdSubscribeConfig);
+	::ndk::ScopedAStatus updateUsdPublish(int32_t in_publishId,
+		const std::vector<uint8_t>& in_serviceSpecificInfo);
+	::ndk::ScopedAStatus cancelUsdPublish(int32_t in_publishId);
+	::ndk::ScopedAStatus cancelUsdSubscribe(int32_t in_subscribeId);
+	::ndk::ScopedAStatus sendUsdMessage(const UsdMessageInfo& in_messageInfo);
 
 private:
 	// Corresponding worker functions for the AIDL methods.
@@ -281,6 +291,14 @@
 		const std::vector<uint8_t>& scsPolicyIds);
 	::ndk::ScopedAStatus configureMscsInternal(const MscsParams& params);
 	::ndk::ScopedAStatus disableMscsInternal();
+	std::pair<UsdCapabilities, ndk::ScopedAStatus> getUsdCapabilitiesInternal();
+	::ndk::ScopedAStatus startUsdPublishInternal(const UsdPublishConfig& usdPublishConfig);
+	::ndk::ScopedAStatus startUsdSubscribeInternal(const UsdSubscribeConfig& usdSubscribeConfig);
+	::ndk::ScopedAStatus updateUsdPublishInternal(int32_t publishId,
+		const std::vector<uint8_t>& serviceSpecificInfo);
+	::ndk::ScopedAStatus cancelUsdPublishInternal(int32_t publishId);
+	::ndk::ScopedAStatus cancelUsdSubscribeInternal(int32_t subscribeId);
+	::ndk::ScopedAStatus sendUsdMessageInternal(const UsdMessageInfo& messageInfo);
 
 	struct wpa_supplicant* retrieveIfacePtr();
 
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index 9229eb5..517c6bc 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -178,7 +178,9 @@
 }
 #endif /* CONFIG_MATCH_IFACE */
 
-
+// Temporarily allow the fuzzer library to redefine main()
+// TODO: Remove this flag once mainline supplicant does not include this file
+#ifndef SUPPLICANT_SERVICE_FUZZER
 int main(int argc, char *argv[])
 {
 	int c, i;
@@ -409,3 +411,4 @@
 
 	return exitcode;
 }
+#endif /* SUPPLICANT_SERVICE_FUZZER */