From bfe316cf9f026d5b48bcfb2f457685b537baa9a3 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Thu, 16 May 2024 20:47:44 +0000
Subject: [PATCH] Fix OOB write in build_read_multi_rsp of gatt_sr.cc

build_read_multi_rsp is missing a bounds check, which can lead to an
OOB write when the mtu parameter is set to zero.

Add that bounds check.

Bug: 323850943
Test: atest GattSrTest
Test: researcher POC
Tag: #security
Flag: EXEMPT trivial validity checks
Ignore-AOSP-First: Security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:cad927034a371b82a4a07a16ec442eb261f6153f)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e5ab6c617683a00c4e2996f1bc15c4c6e7f70f48)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8d5c170681e728ec3b72f6f0799207b2f7e5ea1d)
Merged-In: I18e4325dbc9d6814220332288c85b114d0415c2f
Change-Id: I18e4325dbc9d6814220332288c85b114d0415c2f
---
 system/stack/eatt/eatt.h     | 1 +
 system/stack/gatt/gatt_sr.cc | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/system/stack/eatt/eatt.h b/system/stack/eatt/eatt.h
index a029395a6f8..ba1d47a627a 100644
--- a/system/stack/eatt/eatt.h
+++ b/system/stack/eatt/eatt.h
@@ -99,6 +99,7 @@ class EattChannel {
 
   void EattChannelSetTxMTU(uint16_t tx_mtu) {
     this->tx_mtu_ = std::min<uint16_t>(tx_mtu, EATT_MAX_TX_MTU);
+    this->tx_mtu_ = std::max<uint16_t>(this->tx_mtu_, EATT_MIN_MTU_MPS);
   }
 };
 
diff --git a/system/stack/gatt/gatt_sr.cc b/system/stack/gatt/gatt_sr.cc
index ad8f2540540..8fc378703c9 100644
--- a/system/stack/gatt/gatt_sr.cc
+++ b/system/stack/gatt/gatt_sr.cc
@@ -149,6 +149,13 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
   uint8_t* p;
   bool is_overflow = false;
 
+  // We need at least one extra byte for the opcode
+  if (mtu == 0) {
+    LOG(ERROR) << "Invalid MTU";
+    p_cmd->status = GATT_ILLEGAL_PARAMETER;
+    return;
+  }
+
   len = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu;
   BT_HDR* p_buf = (BT_HDR*)osi_calloc(len);
   p_buf->offset = L2CAP_MIN_OFFSET;
-- 
GitLab