]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Stasis: Fix potential memory leak of control data. 71/2071/1
authorMark Michelson <mmichelson@digium.com>
Fri, 22 Jan 2016 21:08:58 +0000 (15:08 -0600)
committerMark Michelson <mmichelson@digium.com>
Fri, 22 Jan 2016 21:16:21 +0000 (15:16 -0600)
When queuing tasks onto the Stasis control queue, you can pass an
arbitrary data pointer and a function to free that data. All ARI
commands that use the Stasis control queue made the assumption that the
destructor function would be called in all paths, whether the task was
queued successfully or not. However, this was not correct. If a task was
queued onto a control structure that was already completed, the
allocated data would not be freed properly.

This patch corrects this by making sure that all return paths call the
data destructor.

Change-Id: Ibf06522094f8e5c4cce652537dc5d7222b1c4fcb

res/stasis/control.c

index 99407dfab33876a6d4c8562d4a4558d63ea6da36..bae64ecc241b891df59f143e31dc747e13cfbbc0 100644 (file)
@@ -746,6 +746,14 @@ static int app_send_command_on_condition(struct stasis_app_control *control,
        RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
 
        if (control == NULL || control->is_done) {
+               /* If exec_command_on_condition fails, it calls the data_destructor.
+                * In order to provide consistent behavior, we'll also call the data_destructor
+                * on this error path. This way, callers never have to call the
+                * data_destructor themselves.
+                */
+               if (data_destructor) {
+                       data_destructor(data);
+               }
                return -1;
        }
 
@@ -771,6 +779,14 @@ int stasis_app_send_command_async(struct stasis_app_control *control,
        RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
 
        if (control == NULL || control->is_done) {
+               /* If exec_command fails, it calls the data_destructor. In order to
+                * provide consistent behavior, we'll also call the data_destructor
+                * on this error path. This way, callers never have to call the
+                * data_destructor themselves.
+                */
+               if (data_destructor) {
+                       data_destructor(data);
+               }
                return -1;
        }