Fix a memory leak in GTM proxy
authorPavan Deolasee <[email protected]>
Fri, 6 May 2016 12:36:37 +0000 (18:06 +0530)
committerPavan Deolasee <[email protected]>
Tue, 18 Oct 2016 10:05:07 +0000 (15:35 +0530)
When two lists are concatnated, we might leak header of the second list since
only the list cells are concatnated. We must be careful not to free the list if
list_concat returned the to-be-concatnated list as-is.

src/gtm/proxy/proxy_main.c

index 871280fa89be2654c3f3c335b0bf0fd3addeeda0..e03e3e8b34bf3d3810ad8a85a7a98ceb0b2a4b17 100644 (file)
@@ -2441,6 +2441,14 @@ GTMProxy_ProcessPendingCommands(GTMProxy_ThreadInfo *thrinfo)
                                 */
                                thrinfo->thr_processed_commands = gtm_list_concat(thrinfo->thr_processed_commands,
                                                thrinfo->thr_pending_commands[ii]);
+                               /*
+                                * Free the list header of the second list, unless
+                                * gtm_list_concat actually returned the second list as-is
+                                * because the first list was empty
+                                */
+                               if ((thrinfo->thr_processed_commands != thrinfo->thr_pending_commands[ii]) &&
+                                       (thrinfo->thr_pending_commands[ii] != gtm_NIL))
+                                       pfree(thrinfo->thr_pending_commands[ii]);
                                thrinfo->thr_pending_commands[ii] = gtm_NIL;
                                break;
 
@@ -2472,6 +2480,14 @@ GTMProxy_ProcessPendingCommands(GTMProxy_ThreadInfo *thrinfo)
                                 */
                                thrinfo->thr_processed_commands = gtm_list_concat(thrinfo->thr_processed_commands,
                                                thrinfo->thr_pending_commands[ii]);
+                               /*
+                                * Free the list header of the second list, unless
+                                * gtm_list_concat actually returned the second list as-is
+                                * because the first list was empty
+                                */
+                               if ((thrinfo->thr_processed_commands != thrinfo->thr_pending_commands[ii]) &&
+                                       (thrinfo->thr_pending_commands[ii] != gtm_NIL))
+                                       pfree(thrinfo->thr_pending_commands[ii]);
                                thrinfo->thr_pending_commands[ii] = gtm_NIL;
                                break;
 
@@ -2506,6 +2522,14 @@ GTMProxy_ProcessPendingCommands(GTMProxy_ThreadInfo *thrinfo)
                                 */
                                thrinfo->thr_processed_commands = gtm_list_concat(thrinfo->thr_processed_commands,
                                                thrinfo->thr_pending_commands[ii]);
+                               /*
+                                * Free the list header of the second list, unless
+                                * gtm_list_concat actually returned the second list as-is
+                                * because the first list was empty
+                                */
+                               if ((thrinfo->thr_processed_commands != thrinfo->thr_pending_commands[ii]) &&
+                                       (thrinfo->thr_pending_commands[ii] != gtm_NIL))
+                                       pfree(thrinfo->thr_pending_commands[ii]);
                                thrinfo->thr_pending_commands[ii] = gtm_NIL;
                                break;
 
@@ -2537,6 +2561,14 @@ GTMProxy_ProcessPendingCommands(GTMProxy_ThreadInfo *thrinfo)
                                 */
                                thrinfo->thr_processed_commands = gtm_list_concat(thrinfo->thr_processed_commands,
                                                thrinfo->thr_pending_commands[ii]);
+                               /*
+                                * Free the list header of the second list, unless
+                                * gtm_list_concat actually returned the second list as-is
+                                * because the first list was empty
+                                */
+                               if ((thrinfo->thr_processed_commands != thrinfo->thr_pending_commands[ii]) &&
+                                       (thrinfo->thr_pending_commands[ii] != gtm_NIL))
+                                       pfree(thrinfo->thr_pending_commands[ii]);
                                thrinfo->thr_pending_commands[ii] = gtm_NIL;
                                break;