Merge tag 'android-security-11.0.0_r49' into int/11/fp3
Android security 11.0.0 release 49
* tag 'android-security-11.0.0_r49':
Fix UAF problem in wificond
Change-Id: Ib493dc0b09925986e4e16f31a6b756a4d0f9aa14
diff --git a/Android.bp b/Android.bp
index 0578933..c320326 100644
--- a/Android.bp
+++ b/Android.bp
@@ -50,6 +50,8 @@
"libutils",
"libwifi-system-iface",
"android.system.wifi.keystore@1.0",
+ "libvndksupport",
+ "libprocessgroup",
],
static_libs: [
"libwificond", // Wificond daemon
@@ -93,6 +95,16 @@
"libwificond_nl",
"libwificond_event_loop",
],
+ arch: {
+ arm: {
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-DARCH_ARM_32",
+ ],
+ },
+ }
}
//
diff --git a/client_interface_impl.cpp b/client_interface_impl.cpp
index 38a59ff..d715a40 100644
--- a/client_interface_impl.cpp
+++ b/client_interface_impl.cpp
@@ -91,6 +91,10 @@
client_interface_->bssid_.fill(0);
}
+void MlmeEventHandlerImpl::OnChSwitchNotify() {
+ client_interface_->RefreshAssociateFreq();
+}
+
void MlmeEventHandlerImpl::OnDisassociate(unique_ptr<MlmeDisassociateEvent> event) {
client_interface_->is_associated_ = false;
client_interface_->bssid_.fill(0);
@@ -132,6 +136,8 @@
on_frame_tx_status_event_handler_ = [](bool was_acked) {};
}
});
+ netlink_utils_->SubscribeChannelSwitchEvent(interface_index_,
+ std::bind(&ClientInterfaceImpl::OnChannelSwitchEvent, this, _1));
netlink_utils_->SubscribeChannelSwitchEvent(interface_index_,
std::bind(&ClientInterfaceImpl::OnChannelSwitchEvent, this, _1));
diff --git a/client_interface_impl.h b/client_interface_impl.h
index 4ecbf1d..8cf2c7c 100644
--- a/client_interface_impl.h
+++ b/client_interface_impl.h
@@ -48,6 +48,7 @@
void OnAssociate(std::unique_ptr<MlmeAssociateEvent> event) override;
void OnDisconnect(std::unique_ptr<MlmeDisconnectEvent> event) override;
void OnDisassociate(std::unique_ptr<MlmeDisassociateEvent> event) override;
+ void OnChSwitchNotify() override;
private:
ClientInterfaceImpl* client_interface_;
diff --git a/main.cpp b/main.cpp
index 0c17edf..965aa03 100644
--- a/main.cpp
+++ b/main.cpp
@@ -103,6 +103,7 @@
android::IPCThreadState::self()->handlePolledCommands();
}
+
int main(int argc, char** argv) {
android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
LOG(INFO) << "wificond is starting up...";
diff --git a/net/mlme_event_handler.h b/net/mlme_event_handler.h
index 3587604..cf1e793 100644
--- a/net/mlme_event_handler.h
+++ b/net/mlme_event_handler.h
@@ -35,6 +35,7 @@
virtual void OnAssociate(std::unique_ptr<MlmeAssociateEvent> event) = 0;
virtual void OnDisconnect(std::unique_ptr<MlmeDisconnectEvent> event) = 0;
virtual void OnDisassociate(std::unique_ptr<MlmeDisassociateEvent> event) = 0;
+ virtual void OnChSwitchNotify();
};
diff --git a/net/netlink_manager.cpp b/net/netlink_manager.cpp
index 0238f0b..1fa66c4 100644
--- a/net/netlink_manager.cpp
+++ b/net/netlink_manager.cpp
@@ -47,7 +47,7 @@
// netlink.h suggests NLMSG_GOODSIZE to be at most 8192 bytes.
constexpr int kReceiveBufferSize = 8 * 1024;
constexpr uint32_t kBroadcastSequenceNumber = 0;
-constexpr int kMaximumNetlinkMessageWaitMilliSeconds = 300;
+constexpr int kMaximumNetlinkMessageWaitMilliSeconds = 1000;
uint8_t ReceiveBuffer[kReceiveBufferSize];
void AppendPacket(vector<unique_ptr<const NL80211Packet>>* vec,
@@ -642,6 +642,10 @@
}
return;
}
+ if (command == NL80211_CMD_CH_SWITCH_NOTIFY) {
+ handler->second->OnChSwitchNotify();
+ return;
+ }
}
diff --git a/net/netlink_utils.cpp b/net/netlink_utils.cpp
index c31249d..47b56dc 100644
--- a/net/netlink_utils.cpp
+++ b/net/netlink_utils.cpp
@@ -53,7 +53,7 @@
uint32_t k5GHzFrequencyLowerBound = 5000;
// This upper bound will exclude any 5.9Ghz channels which belong to 802.11p
// for "vehicular communication systems".
-uint32_t k5GHzFrequencyUpperBound = 5865;
+uint32_t k5GHzFrequencyUpperBound = 5885;
uint32_t k6GHzFrequencyLowerBound = 5925;
uint32_t k6GHzFrequencyUpperBound = 7125;
@@ -104,6 +104,7 @@
supports_high_accuracy_oneshot_scan =
IsExtFeatureFlagSet(ext_feature_flags_bytes,
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN);
+
// TODO (b/112029045) check if sending frame at specified MCS is supported
supports_tx_mgmt_frame_mcs = false;
supports_ext_sched_scan_relative_rssi =
@@ -123,8 +124,8 @@
NetlinkUtils::~NetlinkUtils() {}
-bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index,
- const std::string& iface_name) {
+bool NetlinkUtils::GetWiphyIndices(std::vector<uint32_t>* wiphy_index_list,
+ const std::string& iface_name) {
NL80211Packet get_wiphy(
netlink_manager_->GetFamilyId(),
NL80211_CMD_GET_WIPHY,
@@ -161,14 +162,29 @@
<< static_cast<int>(packet->GetCommand());
return false;
}
- if (!packet->GetAttributeValue(NL80211_ATTR_WIPHY, out_wiphy_index)) {
+ uint32_t wiphy_index;
+ if (!packet->GetAttributeValue(NL80211_ATTR_WIPHY, &wiphy_index)) {
LOG(ERROR) << "Failed to get wiphy index from reply message";
return false;
}
+ wiphy_index_list->push_back(wiphy_index);
}
return true;
}
+bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index,
+ const std::string& iface_name) {
+ std::vector<uint32_t> wiphy_index_list;
+
+ if (!GetWiphyIndices(&wiphy_index_list, iface_name)) {
+ LOG(ERROR) << "Failed to get wiphy indices";
+ return false;
+ }
+
+ *out_wiphy_index = wiphy_index_list.back();
+ return true;
+}
+
bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index) {
return GetWiphyIndex(out_wiphy_index, "");
}
@@ -723,6 +739,9 @@
// Return invalid tx rate to avoid breaking the get station cmd
tx_bitrate = 0;
}
+ } else {
+ LOG(ERROR) << "Failed to get NL80211_STA_INFO_TX_BITRATE";
+ return false;
}
NL80211NestedAttr rx_bitrate_attr(0);
uint32_t rx_bitrate = 0;
diff --git a/net/netlink_utils.h b/net/netlink_utils.h
index df92e7d..53d9a48 100644
--- a/net/netlink_utils.h
+++ b/net/netlink_utils.h
@@ -172,6 +172,7 @@
class MlmeEventHandler;
class NetlinkManager;
class NL80211Packet;
+class NL80211NestedAttr;
// Provides NL80211 helper functions.
class NetlinkUtils {
@@ -192,6 +193,12 @@
virtual bool GetWiphyIndex(uint32_t* out_wiphy_index,
const std::string& iface_name);
+ // Get a list of wiphy indices for all registered wiphys from kernel.
+ // |*wiphy_index_list| returns the list of indices
+ // Returns true on success
+ virtual bool GetWiphyIndices(std::vector<uint32_t>* wiphy_index_list,
+ const std::string& iface_name);
+
// Get wifi interfaces info from kernel.
// |wiphy_index| is the wiphy index we get using GetWiphyIndex().
// |interface_info| returns a vector of InterfaceInfo structs with
diff --git a/scanning/scanner_impl.cpp b/scanning/scanner_impl.cpp
index 83eceb2..1266a98 100644
--- a/scanning/scanner_impl.cpp
+++ b/scanning/scanner_impl.cpp
@@ -74,6 +74,7 @@
scan_started_(false),
pno_scan_started_(false),
nodev_counter_(0),
+ enetdown_counter_(0),
interface_index_(interface_index),
scan_capabilities_(scan_capabilities),
wiphy_features_(wiphy_features),
@@ -179,12 +180,19 @@
nodev_counter_ ++;
LOG(WARNING) << "Scan failed with error=nodev. counter=" << nodev_counter_;
}
- CHECK(error_code != ENODEV || nodev_counter_ <= 3)
- << "Driver is in a bad state, restarting wificond";
+
+ if (error_code == ENETDOWN) {
+ enetdown_counter_++;
+ LOG(WARNING) << "Scan failed with error=iface down. counter=" << enetdown_counter_;
+ }
+ CHECK((error_code != ENODEV || nodev_counter_ <= 3) &&
+ (error_code != ENETDOWN || enetdown_counter_ <= 10))
+ << "Driver is in a bad state, restarting wificond";
*out_success = false;
return Status::ok();
}
nodev_counter_ = 0;
+ enetdown_counter_ = 0;
scan_started_ = true;
*out_success = true;
return Status::ok();
@@ -291,9 +299,15 @@
nodev_counter_ ++;
LOG(WARNING) << "Pno Scan failed with error=nodev. counter=" << nodev_counter_;
}
+ if (error_code == ENETDOWN) {
+ enetdown_counter_++;
+ LOG(WARNING) << "Pno Scan failed with error=iface down. counter= "
+ << enetdown_counter_;
+ }
LOG(ERROR) << "Failed to start pno scan";
- CHECK(error_code != ENODEV || nodev_counter_ <= 3)
- << "Driver is in a bad state, restarting wificond";
+ CHECK((error_code != ENODEV || nodev_counter_ <= 3) &&
+ (error_code != ENETDOWN || enetdown_counter_ <= 10))
+ << "Driver is in a bad state, restarting wificond";
return false;
}
string freq_string;
@@ -307,6 +321,7 @@
}
LOG(INFO) << "Pno scan started " << freq_string;
nodev_counter_ = 0;
+ enetdown_counter_ = 0;
pno_scan_started_ = true;
return true;
}
diff --git a/scanning/scanner_impl.h b/scanning/scanner_impl.h
index 6e23ea7..e8ab17b 100644
--- a/scanning/scanner_impl.h
+++ b/scanning/scanner_impl.h
@@ -94,6 +94,7 @@
android::net::wifi::nl80211::PnoSettings pno_settings_;
uint32_t nodev_counter_;
+ uint32_t enetdown_counter_;
const uint32_t interface_index_;
// Scanning relevant capability information for this wiphy/interface.
diff --git a/server.cpp b/server.cpp
index 97fbd1e..5f0de94 100644
--- a/server.cpp
+++ b/server.cpp
@@ -23,6 +23,7 @@
#include <android-base/strings.h>
#include <binder/IPCThreadState.h>
#include <binder/PermissionCache.h>
+#include <net/if.h>
#include "wificond/logging_utils.h"
#include "wificond/net/netlink_utils.h"
@@ -51,13 +52,16 @@
namespace {
constexpr const char* kPermissionDump = "android.permission.DUMP";
+constexpr const char* kBaseIfName = "wlan0";
} // namespace
Server::Server(unique_ptr<InterfaceTool> if_tool,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils)
- : if_tool_(std::move(if_tool)),
+ : base_ifname_(kBaseIfName),
+ base_wiphy_index_(0),
+ if_tool_(std::move(if_tool)),
netlink_utils_(netlink_utils),
scan_utils_(scan_utils) {
}
@@ -92,10 +96,14 @@
Status Server::createApInterface(const std::string& iface_name,
sp<IApInterface>* created_interface) {
InterfaceInfo interface;
- if (!SetupInterface(iface_name, &interface)) {
+ uint32_t wiphy_index;
+
+ if (!SetupInterface(iface_name, &interface, &wiphy_index)) {
return Status::ok(); // Logging was done internally
}
+ LOG(DEBUG) << "createApInterface: wiphy_index " << wiphy_index << " iface_name " << iface_name;
+
unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
interface.name,
interface.index,
@@ -104,6 +112,7 @@
*created_interface = ap_interface->GetBinder();
BroadcastApInterfaceReady(ap_interface->GetBinder());
ap_interfaces_[iface_name] = std::move(ap_interface);
+ wiphy_indexes_[iface_name] = wiphy_index;
return Status::ok();
}
@@ -117,18 +126,29 @@
ap_interfaces_.erase(iter);
*out_success = true;
}
+
+ const auto iter_wi = wiphy_indexes_.find(iface_name);
+ if (iter_wi != wiphy_indexes_.end()) {
+ LOG(DEBUG) << "tearDownApInterface: erasing wiphy_index for iface_name " << iface_name;
+ wiphy_indexes_.erase(iter_wi);
+ }
+
return Status::ok();
}
Status Server::createClientInterface(const std::string& iface_name,
sp<IClientInterface>* created_interface) {
InterfaceInfo interface;
- if (!SetupInterface(iface_name, &interface)) {
+ uint32_t wiphy_index;
+
+ if (!SetupInterface(iface_name, &interface, &wiphy_index)) {
return Status::ok(); // Logging was done internally
}
+ LOG(DEBUG) << "createClientInterface: wiphy_index " << wiphy_index << " iface_name " << iface_name;
+
unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl(
- wiphy_index_,
+ wiphy_index,
interface.name,
interface.index,
interface.mac_address,
@@ -138,6 +158,7 @@
*created_interface = client_interface->GetBinder();
BroadcastClientInterfaceReady(client_interface->GetBinder());
client_interfaces_[iface_name] = std::move(client_interface);
+ wiphy_indexes_[iface_name] = wiphy_index;
return Status::ok();
}
@@ -151,6 +172,13 @@
client_interfaces_.erase(iter);
*out_success = true;
}
+
+ const auto iter_wi = wiphy_indexes_.find(iface_name);
+ if (iter_wi != wiphy_indexes_.end()) {
+ LOG(DEBUG) << "tearDownClientInterface: erasing wiphy_index for iface_name " << iface_name;
+ wiphy_indexes_.erase(iter_wi);
+ }
+
return Status::ok();
}
@@ -167,7 +195,10 @@
MarkDownAllInterfaces();
- netlink_utils_->UnsubscribeRegDomainChange(wiphy_index_);
+ for (auto& it : wiphy_indexes_) {
+ netlink_utils_->UnsubscribeRegDomainChange(it.second);
+ }
+ wiphy_indexes_.clear();
return Status::ok();
}
@@ -197,11 +228,11 @@
}
stringstream ss;
- ss << "Current wiphy index: " << wiphy_index_ << endl;
ss << "Cached interfaces list from kernel message: " << endl;
for (const auto& iface : interfaces_) {
ss << "Interface index: " << iface.index
<< ", name: " << iface.name
+ << ", wiphy index: " << wiphy_indexes_[iface.name]
<< ", mac address: "
<< LoggingUtils::GetMacString(iface.mac_address) << endl;
}
@@ -230,13 +261,11 @@
}
void Server::MarkDownAllInterfaces() {
- uint32_t wiphy_index;
- vector<InterfaceInfo> interfaces;
- if (netlink_utils_->GetWiphyIndex(&wiphy_index) &&
- netlink_utils_->GetInterfaces(wiphy_index, &interfaces)) {
- for (InterfaceInfo& interface : interfaces) {
- if_tool_->SetUpState(interface.name.c_str(), false);
- }
+ std::string iface_name;
+
+ for (auto& it : wiphy_indexes_) {
+ iface_name = it.first;
+ if_tool_->SetUpState(iface_name.c_str(), false);
}
}
@@ -246,7 +275,7 @@
ScanCapabilities scan_capabilities_ignored;
WiphyFeatures wiphy_features_ignored;
- if (!netlink_utils_->GetWiphyInfo(wiphy_index_, &band_info,
+ if (!netlink_utils_->GetWiphyInfo(base_wiphy_index_, &band_info,
&scan_capabilities_ignored,
&wiphy_features_ignored)) {
LOG(ERROR) << "Failed to get wiphy info from kernel";
@@ -265,7 +294,7 @@
ScanCapabilities scan_capabilities_ignored;
WiphyFeatures wiphy_features_ignored;
- if (!netlink_utils_->GetWiphyInfo(wiphy_index_, &band_info,
+ if (!netlink_utils_->GetWiphyInfo(base_wiphy_index_, &band_info,
&scan_capabilities_ignored,
&wiphy_features_ignored)) {
LOG(ERROR) << "Failed to get wiphy info from kernel";
@@ -284,7 +313,7 @@
ScanCapabilities scan_capabilities_ignored;
WiphyFeatures wiphy_features_ignored;
- if (!netlink_utils_->GetWiphyInfo(wiphy_index_, &band_info,
+ if (!netlink_utils_->GetWiphyInfo(base_wiphy_index_, &band_info,
&scan_capabilities_ignored,
&wiphy_features_ignored)) {
LOG(ERROR) << "Failed to get wiphy info from kernel";
@@ -303,7 +332,7 @@
ScanCapabilities scan_capabilities_ignored;
WiphyFeatures wiphy_features_ignored;
- if (!netlink_utils_->GetWiphyInfo(wiphy_index_, &band_info,
+ if (!netlink_utils_->GetWiphyInfo(base_wiphy_index_, &band_info,
&scan_capabilities_ignored,
&wiphy_features_ignored)) {
LOG(ERROR) << "Failed to get wiphy info from kernel";
@@ -319,7 +348,9 @@
Status Server::getDeviceWiphyCapabilities(
const std::string& iface_name,
std::unique_ptr<DeviceWiphyCapabilities>* capabilities) {
- if (!RefreshWiphyIndex(iface_name)) {
+ uint32_t wiphy_index;
+ if (!netlink_utils_->GetWiphyIndex(&wiphy_index, iface_name)) {
+ LOG(ERROR) << "Failed to get wiphy index";
capabilities = nullptr;
return Status::ok();
}
@@ -328,7 +359,7 @@
ScanCapabilities scan_capabilities_ignored;
WiphyFeatures wiphy_features_ignored;
- if (!netlink_utils_->GetWiphyInfo(wiphy_index_, &band_info,
+ if (!netlink_utils_->GetWiphyInfo(wiphy_index, &band_info,
&scan_capabilities_ignored,
&wiphy_features_ignored)) {
LOG(ERROR) << "Failed to get wiphy info from kernel";
@@ -350,23 +381,30 @@
}
bool Server::SetupInterface(const std::string& iface_name,
- InterfaceInfo* interface) {
- if (!RefreshWiphyIndex(iface_name)) {
+ InterfaceInfo* interface,
+ uint32_t *wiphy_index) {
+ if (!netlink_utils_->GetWiphyIndex(wiphy_index, iface_name)) {
+ LOG(ERROR) << "Failed to get wiphy index";
return false;
}
netlink_utils_->SubscribeRegDomainChange(
- wiphy_index_,
+ *wiphy_index,
std::bind(&Server::OnRegDomainChanged,
this,
_1));
interfaces_.clear();
- if (!netlink_utils_->GetInterfaces(wiphy_index_, &interfaces_)) {
- LOG(ERROR) << "Failed to get interfaces info from kernel";
+ if (!netlink_utils_->GetInterfaces(*wiphy_index, &interfaces_)) {
+ LOG(ERROR) << "Failed to get interfaces info from kernel for iface_name " << iface_name << " wiphy_index " << *wiphy_index;
return false;
}
+ if (iface_name == base_ifname_) {
+ base_wiphy_index_ = *wiphy_index;
+ LOG(INFO) << "setting base_wiphy_index_ to " << base_wiphy_index_;
+ }
+
for (const auto& iface : interfaces_) {
if (iface.name == iface_name) {
*interface = iface;
@@ -378,14 +416,6 @@
return false;
}
-bool Server::RefreshWiphyIndex(const std::string& iface_name) {
- if (!netlink_utils_->GetWiphyIndex(&wiphy_index_, iface_name)) {
- LOG(ERROR) << "Failed to get wiphy index";
- return false;
- }
- return true;
-}
-
void Server::OnRegDomainChanged(std::string& country_code) {
if (country_code.empty()) {
LOG(INFO) << "Regulatory domain changed";
@@ -399,7 +429,7 @@
BandInfo band_info;
ScanCapabilities scan_capabilities;
WiphyFeatures wiphy_features;
- netlink_utils_->GetWiphyInfo(wiphy_index_,
+ netlink_utils_->GetWiphyInfo(base_wiphy_index_,
&band_info,
&scan_capabilities,
&wiphy_features);
diff --git a/server.h b/server.h
index 982bf12..ecebe37 100644
--- a/server.h
+++ b/server.h
@@ -104,8 +104,8 @@
// interface on behalf of createApInterace(), it is Hostapd that configure
// the interface to Ap mode later.
// Returns true on success, false otherwise.
- bool SetupInterface(const std::string& iface_name, InterfaceInfo* interface);
- bool RefreshWiphyIndex(const std::string& iface_num);
+ bool SetupInterface(const std::string& iface_name, InterfaceInfo* interface,
+ uint32_t *wiphy_index);
void LogSupportedBands();
void OnRegDomainChanged(std::string& country_code);
void BroadcastClientInterfaceReady(
@@ -118,11 +118,13 @@
android::sp<android::net::wifi::nl80211::IApInterface> network_interface);
void MarkDownAllInterfaces();
+ const std::string base_ifname_;
+ uint32_t base_wiphy_index_;
const std::unique_ptr<wifi_system::InterfaceTool> if_tool_;
NetlinkUtils* const netlink_utils_;
ScanUtils* const scan_utils_;
- uint32_t wiphy_index_;
+ std::map<std::string, uint32_t> wiphy_indexes_;
std::map<std::string, std::unique_ptr<ApInterfaceImpl>> ap_interfaces_;
std::map<std::string, std::unique_ptr<ClientInterfaceImpl>> client_interfaces_;
std::vector<android::sp<android::net::wifi::nl80211::IInterfaceEventCallback>>