From: Jakub Pawlowski Date: Wed, 23 May 2018 17:19:53 +0000 (-0700) Subject: GATT: Handle too short Error Response PDU X-Git-Tag: android-x86-9.0-r1~71^2~2^2^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=f63c4b652b3231c2b4907bffd13410c6eb2aa760;p=android-x86%2Fsystem-bt.git 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 --- diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc index 2843ac938..9e77e1587 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 @@ void gatt_process_error_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, 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);