aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-02-13 20:47:54 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-02-13 20:47:54 +0000
commitd7558dbbd588f953aeb58ab57ac0822bc0f6e991 (patch)
tree2b8aac84c4cd10e7cc625a937d81fe702146ed6a
parent05454fedd81a41af3c925996af3ab9f5ecafe3a3 (diff)
parent7a116b63a9486c4d2cad24e562d47c9a7494e2fa (diff)
downloadbt-d7558dbbd588f953aeb58ab57ac0822bc0f6e991.tar.gz
Merge cherrypicks of ['googleplex-android-review.googlesource.com/20672923', 'googleplex-android-review.googlesource.com/20614756', 'googleplex-android-review.googlesource.com/20614757', 'googleplex-android-review.googlesource.com/20614758', 'googleplex-android-review.googlesource.com/21060030'] into sc-platform-release.android-platform-12.0.0_r19android-platform-12.0.0_r18
Change-Id: I25555f3e312870a88b187eeaa4795334dea72bfb
-rw-r--r--btif/src/btif_rc.cc5
-rw-r--r--gd/Android.bp1
-rw-r--r--gd/btaa/Android.bp7
-rw-r--r--gd/btaa/attribution_processor.h13
-rw-r--r--gd/btaa/linux_generic/attribution_processor.cc13
-rw-r--r--gd/btaa/linux_generic/attribution_processor_tests.cc84
-rw-r--r--stack/avdt/avdt_scb_act.cc13
7 files changed, 127 insertions, 9 deletions
diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc
index c77ba6f55..31a0cb98e 100644
--- a/btif/src/btif_rc.cc
+++ b/btif/src/btif_rc.cc
@@ -1955,6 +1955,11 @@ static bt_status_t register_notification_rsp(
dump_rc_notification_event_id(event_id));
std::unique_lock<std::mutex> lock(btif_rc_cb.lock);
+ if (event_id > MAX_RC_NOTIFICATIONS) {
+ BTIF_TRACE_ERROR("Invalid event id");
+ return BT_STATUS_PARM_INVALID;
+ }
+
memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
avrc_rsp.reg_notif.event_id = event_id;
diff --git a/gd/Android.bp b/gd/Android.bp
index c9985a845..d214a9620 100644
--- a/gd/Android.bp
+++ b/gd/Android.bp
@@ -335,6 +335,7 @@ cc_test {
":BluetoothShimTestSources",
":BluetoothSecurityUnitTestSources",
":BluetoothStorageUnitTestSources",
+ ":BluetoothBtaaSources_linux_generic_tests",
],
generated_headers: [
"BluetoothGeneratedBundlerSchema_h_bfbs",
diff --git a/gd/btaa/Android.bp b/gd/btaa/Android.bp
index 2aea7eefb..6b4c269ba 100644
--- a/gd/btaa/Android.bp
+++ b/gd/btaa/Android.bp
@@ -30,3 +30,10 @@ filegroup {
"linux_generic/wakelock_processor.cc",
],
}
+
+filegroup {
+ name: "BluetoothBtaaSources_linux_generic_tests",
+ srcs: [
+ "linux_generic/attribution_processor_tests.cc",
+ ],
+}
diff --git a/gd/btaa/attribution_processor.h b/gd/btaa/attribution_processor.h
index 11bbc9cc4..37c7e72c2 100644
--- a/gd/btaa/attribution_processor.h
+++ b/gd/btaa/attribution_processor.h
@@ -58,7 +58,20 @@ class AttributionProcessor {
void Dump(
std::promise<flatbuffers::Offset<ActivityAttributionData>> promise, flatbuffers::FlatBufferBuilder* fb_builder);
+ using ClockType = std::chrono::time_point<std::chrono::system_clock>;
+ using NowFunc = ClockType (*)();
+
+ // by default, we use the std::chrono::system_clock::now implementation to
+ // get the current timestamp
+ AttributionProcessor() : now_func_(std::chrono::system_clock::now) {}
+ // in other cases, we may need to use different implementation
+ // e.g., for testing purposes
+ AttributionProcessor(NowFunc func) : now_func_(func) {}
+
private:
+ // this function is added for testing support in
+ // OnWakelockReleased
+ NowFunc now_func_ = std::chrono::system_clock::now;
bool wakeup_ = false;
std::unordered_map<AddressActivityKey, BtaaAggregationEntry, AddressActivityKeyHasher> btaa_aggregator_;
std::unordered_map<AddressActivityKey, BtaaAggregationEntry, AddressActivityKeyHasher> wakelock_duration_aggregator_;
diff --git a/gd/btaa/linux_generic/attribution_processor.cc b/gd/btaa/linux_generic/attribution_processor.cc
index a55243a06..4c0eac780 100644
--- a/gd/btaa/linux_generic/attribution_processor.cc
+++ b/gd/btaa/linux_generic/attribution_processor.cc
@@ -64,7 +64,7 @@ void AttributionProcessor::OnWakelockReleased(uint32_t duration_ms) {
}
ms_per_byte = duration_ms / total_byte_count;
- auto cur_time = std::chrono::system_clock::now();
+ auto cur_time = now_func_();
for (auto& it : wakelock_duration_aggregator_) {
it.second.wakelock_duration_ms = ms_per_byte * it.second.byte_count;
if (btaa_aggregator_.find(it.first) == btaa_aggregator_.end()) {
@@ -91,12 +91,15 @@ void AttributionProcessor::OnWakelockReleased(uint32_t duration_ms) {
return;
}
// Trim down the transient entries in the aggregator to avoid that it overgrows
- for (auto& it : btaa_aggregator_) {
+ auto it = btaa_aggregator_.begin();
+ while (it != btaa_aggregator_.end()) {
auto elapsed_time_sec =
- std::chrono::duration_cast<std::chrono::seconds>(cur_time - it.second.creation_time).count();
+ std::chrono::duration_cast<std::chrono::seconds>(cur_time - it->second.creation_time).count();
if (elapsed_time_sec > kDurationTransientDeviceActivityEntrySecs &&
- it.second.byte_count < kByteCountTransientDeviceActivityEntry) {
- btaa_aggregator_.erase(it.first);
+ it->second.byte_count < kByteCountTransientDeviceActivityEntry) {
+ it = btaa_aggregator_.erase(it);
+ } else {
+ it++;
}
}
}
diff --git a/gd/btaa/linux_generic/attribution_processor_tests.cc b/gd/btaa/linux_generic/attribution_processor_tests.cc
new file mode 100644
index 000000000..e54e7fbe2
--- /dev/null
+++ b/gd/btaa/linux_generic/attribution_processor_tests.cc
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#include <base/strings/stringprintf.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include "btaa/activity_attribution.h"
+#include "btaa/attribution_processor.h"
+
+using bluetooth::hci::Address;
+using namespace bluetooth::activity_attribution;
+using namespace std::chrono;
+
+// mock for std::chrono::system_clock::now
+static AttributionProcessor::ClockType now_ret_val;
+static AttributionProcessor::ClockType fake_now() {
+ return now_ret_val;
+}
+
+class AttributionProcessorTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ pAttProc = std::make_unique<AttributionProcessor>(fake_now);
+ }
+ void TearDown() override {
+ pAttProc.reset();
+ }
+
+ std::unique_ptr<AttributionProcessor> pAttProc;
+};
+
+static void fake_now_set_current() {
+ now_ret_val = system_clock::now();
+}
+
+static void fake_now_advance_1000sec() {
+ now_ret_val += seconds(1000s);
+}
+
+TEST_F(AttributionProcessorTest, UAFInOnWakelockReleasedRegressionTest) {
+ std::vector<BtaaHciPacket> btaaPackets;
+ Address addr;
+
+ fake_now_set_current();
+
+ // setup the condition 1 for triggering erase operation
+ // add 220 entries in app_activity_aggregator_
+ // and btaa_aggregator_
+ for (int i = 0; i < 220; i++) {
+ std::string addrStr = base::StringPrintf("21:43:65:87:a9:%02x", i + 10);
+ ASSERT_TRUE(Address::FromString(addrStr, addr));
+ BtaaHciPacket packet(Activity::ACL, addr, 30 * i);
+ btaaPackets.push_back(packet);
+ }
+
+ pAttProc->OnBtaaPackets(btaaPackets);
+ pAttProc->OnWakelockReleased(100);
+
+ // setup the condition 2 for triggering erase operation
+ // make elapsed_time_sec > 900s
+ fake_now_advance_1000sec();
+
+ pAttProc->OnBtaaPackets(btaaPackets);
+ pAttProc->OnWakelockReleased(100);
+}
diff --git a/stack/avdt/avdt_scb_act.cc b/stack/avdt/avdt_scb_act.cc
index 84ea54c78..513234d55 100644
--- a/stack/avdt/avdt_scb_act.cc
+++ b/stack/avdt/avdt_scb_act.cc
@@ -257,19 +257,24 @@ void avdt_scb_hdl_pkt_no_frag(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
if (offset > len) goto length_error;
p += 2;
BE_STREAM_TO_UINT16(ex_len, p);
- offset += ex_len * 4;
p += ex_len * 4;
}
+ if ((p - p_start) >= len) {
+ AVDT_TRACE_WARNING("%s: handling malformatted packet: ex_len too large", __func__);
+ osi_free_and_reset((void**)&p_data->p_pkt);
+ return;
+ }
+ offset = p - p_start;
+
/* adjust length for any padding at end of packet */
if (o_p) {
/* padding length in last byte of packet */
- pad_len = *(p_start + p_data->p_pkt->len);
+ pad_len = *(p_start + len - 1);
}
/* do sanity check */
- if ((offset > p_data->p_pkt->len) ||
- ((pad_len + offset) > p_data->p_pkt->len)) {
+ if (pad_len >= (len - offset)) {
AVDT_TRACE_WARNING("Got bad media packet");
osi_free_and_reset((void**)&p_data->p_pkt);
}