AMQP library for C
Перейти к файлу
Ewerton Scaboro da Silva 96d7179f60
Avoid double-free if session_send_transfer fails and internally destroys the async operation (in link_transfer_async) (#468)
* Avoid double-free if session_send_transfer fails and internally destroys the async operation (in link_transfer_async)

If `session_send_transfer` fails internally, depending on the point where it fails `remove_all_pending_deliveries` might be called,
causing the ASYNC_OPERATION_HANDLE/DELIVERY_INSTANCE variable `result` to be removed from `link->pending_deliveries` and destroyed.
Then when `session_send_transfer` returns, in such cases `singlylinkedlist_remove` will fail and `async_operation_destroy` should not be called (to avoid a double-free).

Callstack of the current double-free in such scenario (without this fix):

==4910== Invalid free() / delete / delete[] / realloc()
==4910==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4910==    by 0x15E0FD: async_operation_destroy (async_operation.c:63)
==4910==    by 0x169B32: link_transfer_async (link.c:1509)
==4910==    by 0x16FAE0: send_one_message (message_sender.c:566)
==4910==    by 0x170810: messagesender_send_async (message_sender.c:962)
==4910==    by 0x122E0C: send_batched_message_and_reset_state (iothubtransport_amqp_telemetry_messenger.c:1120)
==4910==    by 0x1234B9: send_pending_events (iothubtransport_amqp_telemetry_messenger.c:1258)
==4910==    by 0x124A05: telemetry_messenger_do_work (iothubtransport_amqp_telemetry_messenger.c:1809)
==4910==    by 0x11BF83: amqp_device_do_work (iothubtransport_amqp_device.c:1137)
==4910==    by 0x115666: IoTHubTransport_AMQP_Common_Device_DoWork (iothubtransport_amqp_common.c:1121)
==4910==    by 0x1164A9: IoTHubTransport_AMQP_Common_DoWork (iothubtransport_amqp_common.c:1485)
==4910==    by 0x112FD3: IoTHubTransportAMQP_DoWork (iothubtransportamqp.c:56)
==4910==  Address 0x852ae30 is 0 bytes inside a block of size 56 free'd
==4910==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4910==    by 0x15E0FD: async_operation_destroy (async_operation.c:63)
==4910==    by 0x1661D3: remove_all_pending_deliveries (link.c:105)
==4910==    by 0x167B5B: on_session_state_changed (link.c:674)
==4910==    by 0x1746D4: session_set_state (session.c:143)
==4910==    by 0x174C73: on_connection_state_changed (session.c:386)
==4910==    by 0x15FB7B: connection_set_state (connection.c:114)
==4910==    by 0x160222: on_bytes_encoded (connection.c:276)
==4910==    by 0x166093: frame_codec_encode_frame (frame_codec.c:706)
==4910==    by 0x1777BF: amqp_frame_codec_encode_frame (amqp_frame_codec.c:314)
==4910==    by 0x1648D8: connection_encode_frame (connection.c:2084)
==4910==    by 0x176CD4: session_send_transfer (session.c:1655)

* Fixes for windows build
2024-08-09 13:44:28 -07:00
build
build_all Fix VS2017 build break (#457) 2024-02-08 16:46:21 -08:00
configs
deps Submodule update (#464) 2024-05-28 13:49:48 -07:00
design
devdoc Check for minimum size of amqpvalue_get_encoded_size in sasl_frame_codec_encode_frame (#450) 2024-01-31 14:39:43 -08:00
inc/azure_uamqp_c
jenkins
samples
src Avoid double-free if session_send_transfer fails and internally destroys the async operation (in link_transfer_async) (#468) 2024-08-09 13:44:28 -07:00
tests Avoid double-free if session_send_transfer fails and internally destroys the async operation (in link_transfer_async) (#468) 2024-08-09 13:44:28 -07:00
tools Delete tools/kick_jenkins.cmd (#448) 2024-01-25 11:09:07 -08:00
uamqp_generator
.gitattributes
.gitignore
.gitmodules
CMakeLists.txt
LICENSE
SECURITY.MD
contribute.md
dependencies-test.cmake
readme.md Update readme.md (#454) 2024-02-05 14:15:20 -08:00
version.txt

readme.md

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

uAMQP

uAMQP is a C library for AMQP 1.0 communication to Azure Cloud Services.

The goals are:

  • Compliance with the standard
  • Optimizing for low RAM footprint
  • Be as portable as possible

It is currently a client side implementation only.

Dependencies

uAMQP uses azure-c-shared-utility, which is a C library providing common functionality for basic tasks (string manipulation, list manipulation, IO, etc.). azure-c-shared-utility is available here: https://github.com/Azure/azure-c-shared-utility and it is used as a submodule.

Please note that azure-c-shared-utility in turn depends on several libraries (libssl-dev, libuuid-dev, libcurl-dev).

On an Ubuntu distro it is recommended to install all needed packages by running:

  sudo apt-get update
  sudo apt-get install -y git cmake build-essential curl libcurl4-openssl-dev libssl-dev uuid-dev

azure-c-shared-utility provides several tlsio implementations, some being:

  • tlsio_schannel - runs only on Windows
  • tlsio_openssl - depends on OpenSSL being installed
  • tlsio_wolfssl - depends on WolfSSL being installed
  • tlsio_mbedtls
  • ...

For more information about configuring azure-c-shared-utility see https://github.com/Azure/azure-c-shared-utility.

uAMQP uses cmake for configuring build files.

For WebSockets support uAMQP depends on the support provided by azure-c-shared-utility.

Setup

Build

  • Clone azure-uamqp-c by:
git clone --recursive https://github.com/Azure/azure-uamqp-c.git
  • Create a folder named cmake under azure-uamqp-c

  • Switch to the cmake folder and run

cmake ..
  • Build
cmake --build .

Installation and Use

Optionally, you may choose to install azure-uamqp-c on your machine:

  1. Switch to the cmake folder and run

    cmake -Duse_installed=ON ../
    
    cmake --build . --target install
    

    or install using the follow commands for each platform:

    On Linux:

    sudo make install
    

    On Windows:

    msbuild /m INSTALL.vcxproj
    
  2. Use it in your project (if installed)

    find_package(uamqp REQUIRED CONFIG)
    target_link_library(yourlib uamqp)
    

This requires that azure-c-shared-utility is installed (through CMake) on your machine.

If running tests, this requires that umock-c, azure-ctest, and azure-c-testrunnerswitcher are installed (through CMake) on your machine.

Building the tests

In order to build the unit tests use:

cmake .. -Drun_unittests:bool=ON

In order to build the end to end tests use:

cmake .. -Drun_e2e_tests:bool=ON

Please note that some end to end tests (talking to Event Hubs or IoT Hubs) require setup of environment variables so that the tests have the information about the endpoints that they need to connect to.

Switching branches

After any switch of branches (git checkout for example), one should also update the submodule references by:

git submodule update --init --recursive

Samples

Samples are available in the azure-uamqp-c/samples folder:

  • Send messages to an Event Hub
  • Receive messages from an Event Hub
  • Send messages to an IoT Hub using CBS
  • Send messages to an IoT Hub using AMQP over WebSockets
  • Simple client/server sample using raw TCP