Azure / azure-iot-sdk-c

A C99 SDK for connecting devices to Microsoft Azure IoT services
https://azure.github.io/azure-iot-sdk-c
Other
580 stars 738 forks source link

Add guard against crash in amqp messenger/mq #2608

Closed ewertons closed 3 months ago

ewertons commented 3 months ago

Checklist

Reference/Link to the issue solved with this PR (if any)

Description of the problem

messagesender may fire the send complete callback for a message already destroyed at the calling layer (iothubtransport_amqp_messenger), causing a memory access/read error.

Description of the solution

There are instances where a message will be destroyed at the iothubtransport amqp messeger layer, but be still in flight at the messagesender (uamqp) layer, running at the risk of messagesender invoking the send complete callback and resulting in a memory read error over an address previously freed. Using the async operation feature of uamqp adds an extra layer of safety to cancel the existing send operation, preventing the callback to be fired improperly. It intends to address the crash in the following stack:

Error: Time:Sat Mar 16 04:04:26 2024 Fil==256952== Invalid read of size 8
==256952==    at 0x136B85: on_send_complete_callback (iothubtransport_amqp_messenger.c:862)
==256952==    by 0x1798DD: indicate_all_messages_as_error (message_sender.c:703)
==256952==    by 0x179D5C: messagesender_close (message_sender.c:848)
==256952==    by 0x179BBB: messagesender_destroy (message_sender.c:797)
==256952==    by 0x136196: destroy_message_sender (iothubtransport_amqp_messenger.c:596)
==256952==    by 0x137987: amqp_messenger_stop (iothubtransport_amqp_messenger.c:1232)
==256952==    by 0x1343F7: twin_messenger_stop (iothubtransport_amqp_twin_messenger.c:2000)
==256952==    by 0x124B72: internal_device_stop (iothubtransport_amqp_device.c:832)
==256952==    by 0x12512C: amqp_device_do_work (iothubtransport_amqp_device.c:956)
==256952==    by 0x11F475: IoTHubTransport_AMQP_Common_Device_DoWork (iothubtransport_amqp_common.c:1109)
==256952==    by 0x120274: IoTHubTransport_AMQP_Common_DoWork (iothubtransport_amqp_common.c:1470)
==256952==    by 0x11CFF7: IoTHubTransportAMQP_DoWork (iothubtransportamqp.c:56)
==256952==    by 0x1ABA7A: IoTHubClientCore_LL_DoWork (iothub_client_core_ll.c:2115)
==256952==    by 0x1AF1D0: IoTHubDeviceClient_LL_DoWork (iothub_device_client_ll.c:91)
==256952==    by 0x11CD3F: main (iothub_ll_client_shared_sample.c:1299)
==256952==  Address 0x7b92820 is 48 bytes inside a block of size 64 in arena "client"