mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-25 13:14:14 +08:00
shared/gatt-client: Fix invalid read
This fixes the following trace caused by last changes which included prepare write support but broke cancel_request code: Invalid read of size 1 at 0x43E726: cancel_request (gatt-client.c:1854) by 0x447E4F: queue_remove_all (queue.c:387) by 0x43F19A: bt_gatt_client_cancel_all (gatt-client.c:1866) by 0x43F250: bt_gatt_client_free (gatt-client.c:1569) by 0x43F3D0: bt_gatt_client_unref (gatt-client.c:1692) by 0x43380C: destroy_context (test-gatt.c:284) by 0x43380C: context_quit (test-gatt.c:312) by 0x433E77: test_read_cb (test-gatt.c:677) by 0x43C260: read_cb (gatt-client.c:1924) by 0x43948B: handle_rsp (att.c:640) by 0x43948B: can_read_data (att.c:813) by 0x446DAA: watch_callback (io-glib.c:170) by 0x4E7E7FA: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.4200.2) by 0x4E7EB97: ??? (in /usr/lib64/libglib-2.0.so.0.4200.2) Address 0x57f0908 is 8 bytes inside a block of size 40 free'd at 0x4C2ACE9: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x43E06F: request_unref (gatt-client.c:160) by 0x4389C6: cancel_att_send_op (att.c:222) by 0x4389C6: bt_att_cancel (att.c:1194) by 0x43E71D: cancel_request (gatt-client.c:1852) by 0x447E4F: queue_remove_all (queue.c:387) by 0x43F19A: bt_gatt_client_cancel_all (gatt-client.c:1866) by 0x43F250: bt_gatt_client_free (gatt-client.c:1569) by 0x43F3D0: bt_gatt_client_unref (gatt-client.c:1692) by 0x43380C: destroy_context (test-gatt.c:284) by 0x43380C: context_quit (test-gatt.c:312) by 0x433E77: test_read_cb (test-gatt.c:677) by 0x43C260: read_cb (gatt-client.c:1924) by 0x43948B: handle_rsp (att.c:640) by 0x43948B: can_read_data (att.c:813)
This commit is contained in:
parent
247aa7074a
commit
a65ea4e54f
@ -1815,6 +1815,19 @@ static bool cancel_prep_write_session(struct bt_gatt_client *client,
|
||||
req, request_unref);
|
||||
}
|
||||
|
||||
static bool cancel_request(struct request *req)
|
||||
{
|
||||
req->removed = true;
|
||||
|
||||
if (req->long_write)
|
||||
return cancel_long_write_req(req->client, req);
|
||||
|
||||
if (req->prep_write)
|
||||
return cancel_prep_write_session(req->client, req);
|
||||
|
||||
return bt_att_cancel(req->client->att, req->att_id);
|
||||
}
|
||||
|
||||
bool bt_gatt_client_cancel(struct bt_gatt_client *client, unsigned int id)
|
||||
{
|
||||
struct request *req;
|
||||
@ -1827,35 +1840,7 @@ bool bt_gatt_client_cancel(struct bt_gatt_client *client, unsigned int id)
|
||||
if (!req)
|
||||
return false;
|
||||
|
||||
req->removed = true;
|
||||
|
||||
if (!bt_att_cancel(client->att, req->att_id) && !req->long_write &&
|
||||
!req->prep_write)
|
||||
return false;
|
||||
|
||||
/* If this was a long-write, we need to abort all prepared writes */
|
||||
if (req->long_write)
|
||||
return cancel_long_write_req(client, req);
|
||||
|
||||
if (req->prep_write)
|
||||
return cancel_prep_write_session(client, req);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cancel_request(void *data)
|
||||
{
|
||||
struct request *req = data;
|
||||
|
||||
req->removed = true;
|
||||
|
||||
bt_att_cancel(req->client->att, req->att_id);
|
||||
|
||||
if (req->long_write)
|
||||
cancel_long_write_req(req->client, req);
|
||||
|
||||
if (req->prep_write)
|
||||
cancel_prep_write_session(req->client, req);
|
||||
return cancel_request(req);
|
||||
}
|
||||
|
||||
bool bt_gatt_client_cancel_all(struct bt_gatt_client *client)
|
||||
@ -1863,7 +1848,8 @@ bool bt_gatt_client_cancel_all(struct bt_gatt_client *client)
|
||||
if (!client || !client->att)
|
||||
return false;
|
||||
|
||||
queue_remove_all(client->pending_requests, NULL, NULL, cancel_request);
|
||||
queue_remove_all(client->pending_requests, NULL, NULL,
|
||||
(queue_destroy_func_t) cancel_request);
|
||||
|
||||
if (client->discovery_req) {
|
||||
bt_gatt_request_cancel(client->discovery_req);
|
||||
|
Loading…
Reference in New Issue
Block a user