GATT: Handle too short Error Response PDU

Since the spec is not clear what to do in this case, use one of
reserved error codes as a failure reason, and pass it to upper layers.

Bug: 79591688
Change-Id: Ie6a53e9c8e4ceb8f1e5a75aee44baa5f4a798c4f
Merged-In: Ie6a53e9c8e4ceb8f1e5a75aee44baa5f4a798c4f
(cherry picked from commit f63c4b652b3231c2b4907bffd13410c6eb2aa760)
diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc
index 2843ac9..9e77e15 100644
--- a/stack/gatt/gatt_cl.cc
+++ b/stack/gatt/gatt_cl.cc
@@ -29,6 +29,7 @@
 #include "bt_utils.h"
 #include "gatt_int.h"
 #include "l2c_int.h"
+#include "log/log.h"
 #include "osi/include/osi.h"
 
 #define GATT_WRITE_LONG_HDR_SIZE 5 /* 1 opcode + 2 handle + 2 offset */
@@ -507,9 +508,24 @@
   tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
 
   VLOG(1) << __func__;
-  STREAM_TO_UINT8(opcode, p);
-  STREAM_TO_UINT16(handle, p);
-  STREAM_TO_UINT8(reason, p);
+
+  if (len < 4) {
+    android_errorWriteLog(0x534e4554, "79591688");
+    LOG(ERROR) << "Error response too short";
+    // Specification does not clearly define what should happen if error
+    // response is too short. General rule in BT Spec 5.0 Vol 3, Part F 3.4.1.1
+    // is: "If an error code is received in the Error Response that is not
+    // understood by the client, for example an error code that was reserved for
+    // future use that is now being used in a future version of this
+    // specification, then the Error Response shall still be considered to state
+    // that the given request cannot be performed for an unknown reason."
+    opcode = handle = 0;
+    reason = 0x7F;
+  } else {
+    STREAM_TO_UINT8(opcode, p);
+    STREAM_TO_UINT16(handle, p);
+    STREAM_TO_UINT8(reason, p);
+  }
 
   if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) {
     gatt_proc_disc_error_rsp(tcb, p_clcb, opcode, handle, reason);