From 3304f46f1a6a1cb3d6d07468f8d15583d3d265b2 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 14 May 2019 10:39:27 +0300 Subject: [PATCH] shared/gatt-db: Fix crash when generating hash The following crash can be observed when handles are not contiguous: Invalid write of size 8 at 0x452697: gen_hash_m (gatt-db.c:314) by 0x453FE8: gatt_db_service_foreach (gatt-db.c:1395) by 0x45408C: service_gen_hash_m (gatt-db.c:322) by 0x4548F1: foreach_service_in_range (gatt-db.c:1284) by 0x4548F1: foreach_in_range (gatt-db.c:1307) by 0x457470: queue_foreach (queue.c:220) by 0x453B75: gatt_db_foreach_service_in_range (gatt-db.c:1349) by 0x453BAC: gatt_db_foreach_service (gatt-db.c:1254) by 0x453C46: db_hash_update (gatt-db.c:340) by 0x4567B4: timeout_callback (timeout-glib.c:34) Change-Id: Idc0456441e2b94935e7475e25b62428277180797 Signed-off-by: himanshu --- src/shared/gatt-db.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c index 0c3627e..412fae1 100644 --- a/src/shared/gatt-db.c +++ b/src/shared/gatt-db.c @@ -277,9 +277,14 @@ static void handle_notify(void *data, void *user_data) notify->service_removed(notify_data->attr, notify->user_data); } +struct hash_data { + struct iovec *iov; + uint16_t i; +}; + static void gen_hash_m(struct gatt_db_attribute *attr, void *user_data) { - struct iovec *iov = user_data; + struct hash_data *hash = user_data; uint8_t *data; size_t len; @@ -313,8 +318,10 @@ static void gen_hash_m(struct gatt_db_attribute *attr, void *user_data) return; } - iov[attr->handle].iov_base = data; - iov[attr->handle].iov_len = len; + hash->iov[hash->i].iov_base = data; + hash->iov[hash->i].iov_len = len; + + hash->i++; return; } @@ -327,7 +334,7 @@ static void service_gen_hash_m(struct gatt_db_attribute *attr, void *user_data) static bool db_hash_update(void *user_data) { struct gatt_db *db = user_data; - struct iovec *iov; + struct hash_data hash; uint16_t i; db->hash_id = 0; @@ -335,15 +342,16 @@ static bool db_hash_update(void *user_data) if (!db->next_handle) return false; - iov = new0(struct iovec, db->next_handle); + hash.iov = new0(struct iovec, db->next_handle); + hash.i = 0; - gatt_db_foreach_service(db, NULL, service_gen_hash_m, iov); - bt_crypto_gatt_hash(db->crypto, iov, db->next_handle, db->hash); + gatt_db_foreach_service(db, NULL, service_gen_hash_m, &hash); + bt_crypto_gatt_hash(db->crypto, hash.iov, db->next_handle, db->hash); - for (i = 0; i < db->next_handle; i++) - free(iov[i].iov_base); + for (i = 0; i < hash.i; i++) + free(hash.iov[i].iov_base); - free(iov); + free(hash.iov); return false; } -- 2.7.4