Snap for 12667701 from 9fbe9c7750346d1412930ee70fb5361a6930dd7d to 25Q2-release

Change-Id: Iaf6e74a1768d58a1e1be56e1168decc7b88da0e8
diff --git a/hostapd/aidl/hostapd.cpp b/hostapd/aidl/hostapd.cpp
index d58b1ed..b5118b3 100644
--- a/hostapd/aidl/hostapd.cpp
+++ b/hostapd/aidl/hostapd.cpp
@@ -781,6 +781,10 @@
 			"owe_transition_ifname=%s", owe_transition_ifname.c_str());
 	}
 
+	std::string ap_isolation_as_string = StringPrintf("ap_isolate=%s",
+			isAidlServiceVersionAtLeast(3) && nw_params.isClientIsolationEnabled ?
+			"1" : "0");
+
 	return StringPrintf(
 		"interface=%s\n"
 		"driver=nl80211\n"
@@ -806,6 +810,7 @@
 		"%s\n"
 		"%s\n"
 		"%s\n"
+		"%s\n"
 		"%s\n",
 		iface_params.usesMlo ? br_name.c_str() : iface_params.name.c_str(),
 		iface_params.name.c_str(),
@@ -825,7 +830,8 @@
 		owe_transition_ifname_as_string.c_str(),
 		enable_edmg_as_string.c_str(),
 		edmg_channel_as_string.c_str(),
-		vendor_elements_as_string.c_str());
+		vendor_elements_as_string.c_str(),
+		ap_isolation_as_string.c_str());
 }
 
 Generation getGeneration(hostapd_hw_modes *current_mode)
diff --git a/wpa_supplicant/Android.bp b/wpa_supplicant/Android.bp
index 210325b..8160071 100644
--- a/wpa_supplicant/Android.bp
+++ b/wpa_supplicant/Android.bp
@@ -1422,6 +1422,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/mainline/mainline_supplicant.cpp b/wpa_supplicant/aidl/mainline/mainline_supplicant.cpp
index 97ad056..dd2babe 100644
--- a/wpa_supplicant/aidl/mainline/mainline_supplicant.cpp
+++ b/wpa_supplicant/aidl/mainline/mainline_supplicant.cpp
@@ -6,14 +6,78 @@
  * See README for more details.
  */
 
+#include "aidl/shared/shared_utils.h"
 #include "mainline_supplicant.h"
+#include "utils.h"
 
 using ::ndk::ScopedAStatus;
 
+const std::string kConfigFilePath = "/apex/com.android.wifi/etc/mainline_supplicant.conf";
+
 MainlineSupplicant::MainlineSupplicant(struct wpa_global* global) {
     wpa_global_ = global;
 }
 
+ndk::ScopedAStatus MainlineSupplicant::addUsdInterface(const std::string& ifaceName) {
+    if (ifaceName.empty()) {
+        wpa_printf(MSG_ERROR, "Empty iface name provided");
+        return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+    }
+
+    if (active_usd_ifaces_.find(ifaceName) != active_usd_ifaces_.end()) {
+        wpa_printf(MSG_INFO, "Interface %s already exists", ifaceName.c_str());
+        return ndk::ScopedAStatus::ok();
+    }
+
+    if (ensureConfigFileExistsAtPath(kConfigFilePath) != 0) {
+        wpa_printf(MSG_ERROR, "Unable to find config file at %s", kConfigFilePath.c_str());
+        return createStatusWithMsg(
+            SupplicantStatusCode::FAILURE_UNKNOWN, "Config file does not exist");
+    }
+
+    struct wpa_interface iface_params = {};
+    iface_params.driver = kIfaceDriverName;
+    iface_params.ifname = ifaceName.c_str();
+    iface_params.confname = kConfigFilePath.c_str();
+
+    struct wpa_supplicant* wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
+    if (!wpa_s) {
+        wpa_printf(MSG_ERROR, "Unable to add interface %s", ifaceName.c_str());
+        return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+    }
+
+    wpa_printf(MSG_INFO, "Interface %s was added successfully", ifaceName.c_str());
+    active_usd_ifaces_.insert(ifaceName);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus MainlineSupplicant::removeUsdInterface(const std::string& ifaceName) {
+    if (ifaceName.empty()) {
+        wpa_printf(MSG_ERROR, "Empty iface name provided");
+        return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+    }
+
+    if (active_usd_ifaces_.find(ifaceName) == active_usd_ifaces_.end()) {
+        wpa_printf(MSG_ERROR, "Interface %s does not exist", ifaceName.c_str());
+        return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+    }
+
+    struct wpa_supplicant* wpa_s =
+        wpa_supplicant_get_iface(wpa_global_, ifaceName.c_str());
+    if (!wpa_s) {
+        wpa_printf(MSG_ERROR, "Interface %s does not exist", ifaceName.c_str());
+        return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+    }
+    if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) {
+        wpa_printf(MSG_ERROR, "Unable to remove interface %s", ifaceName.c_str());
+        return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+    }
+
+    wpa_printf(MSG_INFO, "Interface %s was removed successfully", ifaceName.c_str());
+    active_usd_ifaces_.erase(ifaceName);
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus MainlineSupplicant::terminate() {
     wpa_printf(MSG_INFO, "Terminating...");
     wpa_supplicant_terminate_proc(wpa_global_);
diff --git a/wpa_supplicant/aidl/mainline/mainline_supplicant.h b/wpa_supplicant/aidl/mainline/mainline_supplicant.h
index 4cdc9c8..38a355f 100644
--- a/wpa_supplicant/aidl/mainline/mainline_supplicant.h
+++ b/wpa_supplicant/aidl/mainline/mainline_supplicant.h
@@ -9,7 +9,10 @@
 #ifndef MAINLINE_SUPPLICANT_IMPL_H
 #define MAINLINE_SUPPLICANT_IMPL_H
 
+#include <set>
+
 #include <aidl/android/system/wifi/mainline_supplicant/BnMainlineSupplicant.h>
+#include <aidl/android/system/wifi/mainline_supplicant/SupplicantStatusCode.h>
 
 extern "C"
 {
@@ -17,18 +20,24 @@
 #include "utils/includes.h"
 #include "utils/wpa_debug.h"
 #include "wpa_supplicant_i.h"
+#include "scan.h"
 }
 
 using ::aidl::android::system::wifi::mainline_supplicant::BnMainlineSupplicant;
+using ::aidl::android::system::wifi::mainline_supplicant::SupplicantStatusCode;
 
 class MainlineSupplicant : public BnMainlineSupplicant {
     public:
         MainlineSupplicant(struct wpa_global* global);
+        ndk::ScopedAStatus addUsdInterface(const std::string& ifaceName);
+        ndk::ScopedAStatus removeUsdInterface(const std::string& ifaceName);
         ndk::ScopedAStatus terminate();
 
     private:
         // Raw pointer to the global structure maintained by the core
         struct wpa_global* wpa_global_;
+        // Names of all active USD interfaces
+        std::set<std::string> active_usd_ifaces_;
 };
 
 #endif  // MAINLINE_SUPPLICANT_IMPL_H
diff --git a/wpa_supplicant/aidl/mainline/utils.h b/wpa_supplicant/aidl/mainline/utils.h
new file mode 100644
index 0000000..703b9ee
--- /dev/null
+++ b/wpa_supplicant/aidl/mainline/utils.h
@@ -0,0 +1,25 @@
+/*
+ * WPA Supplicant - Utilities for the mainline supplicant
+ * Copyright (c) 2024, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef MAINLINE_SUPPLICANT_UTILS_H
+#define MAINLINE_SUPPLICANT_UTILS_H
+
+#include <aidl/android/system/wifi/mainline_supplicant/SupplicantStatusCode.h>
+
+inline ndk::ScopedAStatus createStatus(SupplicantStatusCode statusCode) {
+	return ndk::ScopedAStatus::fromServiceSpecificError(
+		static_cast<int32_t>(statusCode));
+}
+
+inline ndk::ScopedAStatus createStatusWithMsg(
+	    SupplicantStatusCode statusCode, std::string msg) {
+	return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+		static_cast<int32_t>(statusCode), msg.c_str());
+}
+
+#endif // MAINLINE_SUPPLICANT_UTILS_H
diff --git a/wpa_supplicant/aidl/shared/shared_utils.h b/wpa_supplicant/aidl/shared/shared_utils.h
new file mode 100644
index 0000000..97676f4
--- /dev/null
+++ b/wpa_supplicant/aidl/shared/shared_utils.h
@@ -0,0 +1,49 @@
+/*
+ * WPA Supplicant - Shared utility functions and constants
+ * Copyright (c) 2024, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef SHARED_UTILS_H
+#define SHARED_UTILS_H
+
+#include <android-base/file.h>
+#include <fcntl.h>
+
+extern "C"
+{
+#include "utils/common.h"
+}
+
+constexpr char kIfaceDriverName[] = "nl80211";
+constexpr mode_t kConfigFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+
+/**
+ * Ensure that the config file at |config_file_path| exists.
+ * Returns 0 on success, or errno otherwise.
+ */
+int ensureConfigFileExistsAtPath(const std::string& config_file_path) {
+    int ret = access(config_file_path.c_str(), R_OK);
+    if (ret == 0) {
+        return 0;
+    }
+    if (errno == EACCES) {
+        ret = chmod(config_file_path.c_str(), kConfigFileMode);
+        if (ret == 0) {
+            return 0;
+        } else {
+            wpa_printf(
+                MSG_ERROR, "Cannot set RW to %s. Errno: %s",
+                config_file_path.c_str(), strerror(errno));
+        }
+    } else if (errno != ENOENT) {
+        wpa_printf(
+            MSG_ERROR, "Cannot access %s. Errno: %s",
+            config_file_path.c_str(), strerror(errno));
+    }
+    return errno;
+}
+
+#endif // SHARED_UTILS_H
diff --git a/wpa_supplicant/aidl/vendor/supplicant.cpp b/wpa_supplicant/aidl/vendor/supplicant.cpp
index ae1943f..0cb2342 100644
--- a/wpa_supplicant/aidl/vendor/supplicant.cpp
+++ b/wpa_supplicant/aidl/vendor/supplicant.cpp
@@ -12,6 +12,8 @@
 #include "supplicant.h"
 #include "p2p_iface.h"
 
+#include "aidl/shared/shared_utils.h"
+
 #include <android-base/file.h>
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -22,8 +24,6 @@
 // Note: This may differ for other OEM's. So, modify this accordingly.
 // When wpa_supplicant is in its APEX, overlay/template configurations should be
 // loaded from the same APEX.
-constexpr char kIfaceDriverName[] = "nl80211";
-
 constexpr char kStaIfaceConfPath[] =
 	"/data/vendor/wifi/wpa/wpa_supplicant.conf";
 constexpr char kStaIfaceConfOverlayPath[] =
@@ -42,7 +42,6 @@
 
 constexpr char kOldStaIfaceConfPath[] = "/data/misc/wifi/wpa_supplicant.conf";
 constexpr char kOldP2pIfaceConfPath[] = "/data/misc/wifi/p2p_supplicant.conf";
-constexpr mode_t kConfigFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
 
 std::string resolveVendorConfPath(const std::string& conf_path)
 {
@@ -114,26 +113,15 @@
 	const std::string& config_file_path,
 	const std::string& old_config_file_path)
 {
-	int ret = access(config_file_path.c_str(), R_OK | W_OK);
+	// Check if config file already exists at |config_file_path|
+	int ret = ensureConfigFileExistsAtPath(config_file_path);
 	if (ret == 0) {
+		wpa_printf(MSG_INFO, "Config file already exists at %s", config_file_path.c_str());
 		return 0;
-	}
-	if (errno == EACCES) {
-		ret = chmod(config_file_path.c_str(), kConfigFileMode);
-		if (ret == 0) {
-			return 0;
-		} else {
-			wpa_printf(
-				MSG_ERROR, "Cannot set RW to %s. Errno: %s",
-				config_file_path.c_str(), strerror(errno));
-			return -1;
-		}
-	} else if (errno != ENOENT) {
-		wpa_printf(
-			MSG_ERROR, "Cannot acces %s. Errno: %s",
-			config_file_path.c_str(), strerror(errno));
+	} else if (ret != ENOENT) {
 		return -1;
 	}
+
 	ret = copyFileIfItExists(old_config_file_path, config_file_path);
 	if (ret == 0) {
 		wpa_printf(
@@ -145,6 +133,7 @@
 		unlink(config_file_path.c_str());
 		return -1;
 	}
+
 	std::string vendor_template_conf_path = resolveVendorConfPath(kVendorTemplateConfPath);
 	ret = copyFileIfItExists(vendor_template_conf_path, config_file_path);
 	if (ret == 0) {
@@ -156,6 +145,7 @@
 		unlink(config_file_path.c_str());
 		return -1;
 	}
+
 	ret = copyFileIfItExists(kSystemTemplateConfPath, config_file_path);
 	if (ret == 0) {
 		wpa_printf(
@@ -166,6 +156,7 @@
 		unlink(config_file_path.c_str());
 		return -1;
 	}
+
 	// Did not create the conf file.
 	return -1;
 }
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 */