mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-12-14 06:25:08 +08:00
shared/gatt-server: Fix crash on read multiple
When read multiple includes external characteristic, call to gatt_db_attribute_read's complete callback is asynchronous. Fix following crash: Use of uninitialised value of size 8 at 0x49718A: read_multiple_complete_cb (gatt-server.c:994) by 0x498999: pending_read_result (gatt-db.c:136) by 0x49A84B: gatt_db_attribute_read_result (gatt-db.c:1787) by 0x451F4C: read_reply_cb (gatt-database.c:1712) by 0x48B221: method_call_reply (client.c:972) by 0x53AB601: ??? (in /usr/lib64/libdbus-1.so.3.19.3) by 0x53AEF7E: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.19.3) by 0x486FEF: message_dispatch (mainloop.c:72) by 0x50CB576: ??? (in /usr/lib64/libglib-2.0.so.0.5400.3) by 0x50CEB76: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.5400.3) by 0x50CEF1F: ??? (in /usr/lib64/libglib-2.0.so.0.5400.3) by 0x50CF231: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.5400.3) Invalid read of size 8 at 0x49718A: read_multiple_complete_cb (gatt-server.c:994) by 0x498999: pending_read_result (gatt-db.c:136) by 0x49A84B: gatt_db_attribute_read_result (gatt-db.c:1787) by 0x451F4C: read_reply_cb (gatt-database.c:1712) by 0x48B221: method_call_reply (client.c:972) by 0x53AB601: ??? (in /usr/lib64/libdbus-1.so.3.19.3) by 0x53AEF7E: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.19.3) by 0x486FEF: message_dispatch (mainloop.c:72) by 0x50CB576: ??? (in /usr/lib64/libglib-2.0.so.0.5400.3) by 0x50CEB76: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.5400.3) by 0x50CEF1F: ??? (in /usr/lib64/libglib-2.0.so.0.5400.3) by 0x50CF231: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.5400.3) Address 0x8 is not stack'd, malloc'd or (recently) free'd
This commit is contained in:
parent
a097cb0732
commit
9e3fa05343
@ -965,10 +965,8 @@ struct read_multiple_resp_data {
|
|||||||
static void read_multiple_resp_data_free(struct read_multiple_resp_data *data)
|
static void read_multiple_resp_data_free(struct read_multiple_resp_data *data)
|
||||||
{
|
{
|
||||||
free(data->handles);
|
free(data->handles);
|
||||||
data->handles = NULL;
|
|
||||||
|
|
||||||
free(data->rsp_data);
|
free(data->rsp_data);
|
||||||
data->rsp_data = NULL;
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_multiple_complete_cb(struct gatt_db_attribute *attr, int err,
|
static void read_multiple_complete_cb(struct gatt_db_attribute *attr, int err,
|
||||||
@ -1045,38 +1043,38 @@ static void read_multiple_cb(uint8_t opcode, const void *pdu,
|
|||||||
{
|
{
|
||||||
struct bt_gatt_server *server = user_data;
|
struct bt_gatt_server *server = user_data;
|
||||||
struct gatt_db_attribute *attr;
|
struct gatt_db_attribute *attr;
|
||||||
struct read_multiple_resp_data data;
|
struct read_multiple_resp_data *data = NULL;
|
||||||
uint8_t ecode = BT_ATT_ERROR_UNLIKELY;
|
uint8_t ecode = BT_ATT_ERROR_UNLIKELY;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
data.handles = NULL;
|
|
||||||
data.rsp_data = NULL;
|
|
||||||
|
|
||||||
if (length < 4) {
|
if (length < 4) {
|
||||||
ecode = BT_ATT_ERROR_INVALID_PDU;
|
ecode = BT_ATT_ERROR_INVALID_PDU;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.server = server;
|
data = new0(struct read_multiple_resp_data, 1);
|
||||||
data.num_handles = length / 2;
|
data->handles = NULL;
|
||||||
data.cur_handle = 0;
|
data->rsp_data = NULL;
|
||||||
data.mtu = bt_att_get_mtu(server->att);
|
data->server = server;
|
||||||
data.length = 0;
|
data->num_handles = length / 2;
|
||||||
data.rsp_data = malloc(data.mtu - 1);
|
data->cur_handle = 0;
|
||||||
|
data->mtu = bt_att_get_mtu(server->att);
|
||||||
|
data->length = 0;
|
||||||
|
data->rsp_data = malloc(data->mtu - 1);
|
||||||
|
|
||||||
if (!data.rsp_data)
|
if (!data->rsp_data)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
data.handles = new0(uint16_t, data.num_handles);
|
data->handles = new0(uint16_t, data->num_handles);
|
||||||
|
|
||||||
for (i = 0; i < data.num_handles; i++)
|
for (i = 0; i < data->num_handles; i++)
|
||||||
data.handles[i] = get_le16(pdu + i * 2);
|
data->handles[i] = get_le16(pdu + i * 2);
|
||||||
|
|
||||||
util_debug(server->debug_callback, server->debug_data,
|
util_debug(server->debug_callback, server->debug_data,
|
||||||
"Read Multiple Req - %zu handles, 1st: 0x%04x",
|
"Read Multiple Req - %zu handles, 1st: 0x%04x",
|
||||||
data.num_handles, data.handles[0]);
|
data->num_handles, data->handles[0]);
|
||||||
|
|
||||||
attr = gatt_db_get_attribute(server->db, data.handles[0]);
|
attr = gatt_db_get_attribute(server->db, data->handles[0]);
|
||||||
|
|
||||||
if (!attr) {
|
if (!attr) {
|
||||||
ecode = BT_ATT_ERROR_INVALID_HANDLE;
|
ecode = BT_ATT_ERROR_INVALID_HANDLE;
|
||||||
@ -1084,11 +1082,13 @@ static void read_multiple_cb(uint8_t opcode, const void *pdu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gatt_db_attribute_read(attr, 0, opcode, server->att,
|
if (gatt_db_attribute_read(attr, 0, opcode, server->att,
|
||||||
read_multiple_complete_cb, &data))
|
read_multiple_complete_cb, data))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
read_multiple_resp_data_free(&data);
|
if (data)
|
||||||
|
read_multiple_resp_data_free(data);
|
||||||
|
|
||||||
bt_att_send_error_rsp(server->att, opcode, 0, ecode);
|
bt_att_send_error_rsp(server->att, opcode, 0, ecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user