adapter: Fix storing IRK causing invalid read
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 22 Oct 2021 20:10:09 +0000 (13:10 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:37 +0000 (19:08 +0530)
When storing an IRK the storage file may not have been created yet
since that uses the device address which is likely changed to the
identity address causing the following trace:

Invalid read of size 8
   at 0x196452: store_irk.constprop.0 (adapter.c:8679)
   by 0x198C92: new_irk_callback (adapter.c:8737)
   by 0x1CF6DC: queue_foreach (queue.c:207)
   by 0x1D1394: process_notify (mgmt.c:308)
   by 0x1D1394: can_read_data (mgmt.c:374)
   by 0x1E0634: watch_callback (io-glib.c:157)
   by 0x4954A9E: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.6600.8)
   by 0x49A6A97: ??? (in /usr/lib64/libglib-2.0.so.0.6600.8)
   by 0x4954162: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.6600.8)
   by 0x1E0CD4: mainloop_run (mainloop-glib.c:66)
   by 0x1E10B1: mainloop_run_with_signal (mainloop-notify.c:188)
   by 0x12E3FC: main (main.c:1210)
 Address 0x6534418 is 8 bytes inside a block of size 16 free'd

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/adapter.c
src/device.c

index e5d4f174e1709fc7c9b1a78308a1030b7d07ab13..87799fa06dd37ebf0b2bb886454b5b3fd3aa935a 100644 (file)
@@ -14117,11 +14117,15 @@ static void store_link_key(struct btd_adapter *adapter,
 
        snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
                        btd_adapter_get_storage_dir(adapter), device_addr);
+       create_file(filename, 0600);
+
        key_file = g_key_file_new();
        if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
                error("Unable to load key file from %s: (%s)", filename,
                                                                gerr->message);
                g_error_free(gerr);
+               g_key_file_free(key_file);
+               return;
        }
 
        for (i = 0; i < 16; i++)
@@ -14476,8 +14480,6 @@ static void store_irk(struct btd_adapter *adapter, const bdaddr_t *peer,
 
        g_key_file_set_string(key_file, "IdentityResolvingKey", "Key", str);
 
-       create_file(filename, 0600);
-
        store_data = g_key_file_to_data(key_file, &length, NULL);
        if (!g_file_set_contents(filename, store_data, length, &gerr)) {
                error("Unable set contents for %s: (%s)", filename,
index 1d1533f18a656fc644f08e1aa2f9698f77e11b0a..7b31e1616870ba8f2ba96ac5b330fa7296dc0249 100644 (file)
@@ -591,12 +591,15 @@ static gboolean store_device_info_cb(gpointer user_data)
        snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
                                btd_adapter_get_storage_dir(device->adapter),
                                device_addr);
+       create_file(filename, 0600);
 
        key_file = g_key_file_new();
        if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
                error("Unable to load key file from %s: (%s)", filename,
                                                                gerr->message);
                g_error_free(gerr);
+               g_key_file_free(key_file);
+               return FALSE;
        }
 
        g_key_file_set_string(key_file, "General", "Name", device->name);
@@ -729,8 +732,6 @@ static gboolean store_device_info_cb(gpointer user_data)
        if (device->remote_csrk)
                store_csrk(device->remote_csrk, key_file, "RemoteSignatureKey");
 
-       create_file(filename, 0600);
-
        str = g_key_file_to_data(key_file, &length, NULL);
        if (!g_file_set_contents(filename, str, length, &gerr)) {
                error("Unable set contents for %s: (%s)", filename,
@@ -7226,9 +7227,9 @@ static void device_remove_stored(struct btd_device *device)
 
        key_file = g_key_file_new();
        if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
-               error("Unable to load key file from %s: (%s)", filename,
-                                                               gerr->message);
                g_error_free(gerr);
+               g_key_file_free(key_file);
+               return;
        }
        g_key_file_remove_group(key_file, "ServiceRecords", NULL);
        g_key_file_remove_group(key_file, "Attributes", NULL);