浏览代码

Ticket #47707 - 389 DS Server crashes and dies while handles paged searches from clients

Bug Description: If a simple paged search request was sent to the server
and the request was abandoned, the paged result slot in the connection
table was not properly released by setting NULL to pr_current_be.  Since
the slot did not look available for the next request even though it was,
the next request failed to get the valid slot number, and the initial slot
number -1 failed to be replaced with the real slot number.  Until the fix
for "Ticket #47623 fix memleak caused by 47347" was made, it overrode the
allocated array's [-1] location, which usually stores the meta data of the
allocated memory.  That crashed the server in the next realloc since the
corrupted memory was passed to the function.

Fix Description: This patch cleans up the abandoned/cleaned up slot for
reuse.  Also, more check not to break the meta data is added.

Special thanks to German Parente ([email protected]) for providing the
reproducer and analysing the crash.

https://fedorahosted.org/389/ticket/47707

Reviewed by [email protected] (Thanks, Rich!)
Noriko Hosoi 11 年之前
父节点
当前提交
087356f7ea
共有 1 个文件被更改,包括 6 次插入1 次删除
  1. 6 1
      ldap/servers/slapd/pagedresults.c

+ 6 - 1
ldap/servers/slapd/pagedresults.c

@@ -130,7 +130,8 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
                 }
                 }
             }
             }
         }
         }
-        if (!conn->c_pagedresults.prl_list[*index].pr_mutex) {
+        if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen) &&
+            !conn->c_pagedresults.prl_list[*index].pr_mutex) {
             conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
             conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
         }
         }
         conn->c_pagedresults.prl_count++;
         conn->c_pagedresults.prl_count++;
@@ -270,6 +271,7 @@ pagedresults_free_one( Connection *conn, Operation *op, int index )
                 prp->pr_current_be->be_search_results_release &&
                 prp->pr_current_be->be_search_results_release &&
                 prp->pr_search_result_set) {
                 prp->pr_search_result_set) {
                 prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
                 prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
+                prp->pr_current_be = NULL;
             }
             }
             if (prp->pr_mutex) {
             if (prp->pr_mutex) {
                 /* pr_mutex is reused; back it up and reset it. */
                 /* pr_mutex is reused; back it up and reset it. */
@@ -307,6 +309,7 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid )
                         prp->pr_current_be->be_search_results_release &&
                         prp->pr_current_be->be_search_results_release &&
                         prp->pr_search_result_set) {
                         prp->pr_search_result_set) {
                         prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
                         prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
+                        prp->pr_current_be = NULL;
                     }
                     }
                     prp->pr_flags |= CONN_FLAG_PAGEDRESULTS_ABANDONED;
                     prp->pr_flags |= CONN_FLAG_PAGEDRESULTS_ABANDONED;
                     prp->pr_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING;
                     prp->pr_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING;
@@ -724,6 +727,7 @@ pagedresults_cleanup(Connection *conn, int needlock)
         if (prp->pr_current_be && prp->pr_search_result_set &&
         if (prp->pr_current_be && prp->pr_search_result_set &&
             prp->pr_current_be->be_search_results_release) {
             prp->pr_current_be->be_search_results_release) {
             prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
             prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
+            prp->pr_current_be = NULL;
             rc = 1;
             rc = 1;
         }
         }
         if (prp->pr_mutex) {
         if (prp->pr_mutex) {
@@ -771,6 +775,7 @@ pagedresults_cleanup_all(Connection *conn, int needlock)
         if (prp->pr_current_be && prp->pr_search_result_set &&
         if (prp->pr_current_be && prp->pr_search_result_set &&
             prp->pr_current_be->be_search_results_release) {
             prp->pr_current_be->be_search_results_release) {
             prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
             prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
+            prp->pr_current_be = NULL;
             rc = 1;
             rc = 1;
         }
         }
     }
     }