Skip to content

Commit 26c6b75

Browse files
authored
Merge pull request #14625 from paul-szczepanek-arm/fix-read-auth
BLE: Fix overwriting attribute data from read auth callback
2 parents ffd5389 + 2041cc6 commit 26c6b75

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,19 +1672,30 @@ class GattCharacteristic {
16721672
*
16731673
* @attention This function is not meant to be called by user code.
16741674
*
1675-
* @param[in] params Context of the read-auth request; it contains an
1675+
* @param[in,out] params Context of the read-auth request; it contains an
16761676
* out-parameter used as a reply and the handler can fill it with outgoing
1677-
* data.
1677+
* data. The params->data provides a pointer to the data and params->len
1678+
* provides the length of this data. params->len is also used to pass the
1679+
* maximum size of data that the params->data can contain. If you set the
1680+
* params->len to a value larger than the passed in value the read operation
1681+
* will fail.
16781682
*
16791683
* @return A GattAuthCallbackReply_t value indicating whether authorization
16801684
* is granted.
16811685
*
1686+
* @note If the read is approved, the event handler can specify an outgoing
1687+
* value directly with the help of the fields params->data and params->len.
1688+
*
16821689
* @note If the read request is approved and params->data remains nullptr, then
16831690
* the current characteristic value is used in the read response payload.
16841691
*
1685-
* @note If the read is approved, the event handler can specify an outgoing
1686-
* value directly with the help of the fields
1687-
* GattReadAuthCallbackParams::data and GattReadAuthCallbackParams::len.
1692+
* @note The params->len parameter initially contains the maximum length of
1693+
* data that can be returned. Set it to the length of your data but it must
1694+
* not be larger than the original value.
1695+
*
1696+
* @note You must also take into account the offset provided in params->offset.
1697+
* The params->len you provide must be larger then the offset as the read operation
1698+
* will attempt to read at that offset.
16881699
*/
16891700
GattAuthCallbackReply_t authorizeRead(GattReadAuthCallbackParams *params)
16901701
{

connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,13 +1124,15 @@ uint8_t GattServer::atts_read_cb(
11241124
attsAttr_t *pAttr
11251125
)
11261126
{
1127+
uint8_t err = ATT_SUCCESS;
1128+
11271129
char_auth_callback *auth_cb = getInstance().get_auth_callback(handle);
11281130
if (auth_cb && auth_cb->read_cb) {
11291131
GattReadAuthCallbackParams read_auth_params = {
11301132
connId,
11311133
handle,
11321134
offset,
1133-
/* len */ 0,
1135+
/* len */ pAttr->maxLen,
11341136
/* data */ nullptr,
11351137
AUTH_CALLBACK_REPLY_SUCCESS
11361138
};
@@ -1146,8 +1148,23 @@ uint8_t GattServer::atts_read_cb(
11461148
return read_auth_params.authorizationReply & 0xFF;
11471149
}
11481150

1149-
pAttr->pValue = read_auth_params.data;
1150-
*pAttr->pLen = read_auth_params.len;
1151+
/* if new data provided copy into the attribute value buffer */
1152+
if (read_auth_params.data) {
1153+
if (read_auth_params.len > pAttr->maxLen) {
1154+
tr_error("Read authorisation callback set length larger than maximum attribute length, "
1155+
"cannot copy data");
1156+
err = ATT_ERR_UNLIKELY;
1157+
} else {
1158+
memcpy(pAttr->pValue, read_auth_params.data, read_auth_params.len);
1159+
*pAttr->pLen = read_auth_params.len;
1160+
1161+
if (read_auth_params.len < offset) {
1162+
tr_warning("Read authorisation callback shortened data beyond current offset, "
1163+
"current read will fail");
1164+
err = ATT_ERR_OFFSET;
1165+
}
1166+
}
1167+
}
11511168
}
11521169

11531170
tr_debug("Read attribute %d on connection %d - value=%s",
@@ -1161,11 +1178,11 @@ uint8_t GattServer::atts_read_cb(
11611178
offset,
11621179
*pAttr->pLen,
11631180
pAttr->pValue,
1164-
/* status */ BLE_ERROR_NONE,
1181+
/* status */ (err == ATT_SUCCESS) ? BLE_ERROR_NONE : BLE_ERROR_PARAM_OUT_OF_RANGE
11651182
};
11661183
getInstance().handleDataReadEvent(&read_params);
11671184

1168-
return ATT_SUCCESS;
1185+
return err;
11691186
}
11701187

11711188
uint8_t GattServer::atts_write_cb(

0 commit comments

Comments
 (0)