[389-commits] Branch '389-ds-base-1.2.10' - ldap/servers

Richard Allen Megginson rmeggins at fedoraproject.org
Tue Apr 24 21:53:59 UTC 2012


 ldap/servers/slapd/back-ldbm/idl_new.c |   17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

New commits:
commit 5d45dd8de06aaee3e0a52c85fa5b3e18febd7a27
Author: Rich Megginson <rmeggins at redhat.com>
Date:   Fri Apr 20 20:15:21 2012 -0600

    Ticket #347 - IPA dirsvr seg-fault during system longevity test
    
    https://fedorahosted.org/389/ticket/347
    Resolves: Ticket 347
    Bug Description: IPA dirsvr seg-fault during system longevity test
    Reviewed by: nhosoi, mreynolds (Thanks!)
    Branch: master
    Fix Description: Somehow the DB_MULTIPLE_NEXT pointer is being set to
    an invalid value (-5).  This causes the next iteration to return memory
    that points to before the stack buffer, causing a seg fault.  Valid
    values for the pointer are > -1.  The value -1 is used as the list terminator
    value.  The code that constructs the buffer is in the libdb function
    __bam_bulk in bt_cursor.c.  The fix is to check for a value < -1,
    assume the page or value has been deleted out from under us, and do
    a dbc->get to get the next buffer full, if any.  The code also needs to
    check for duplicate IDs being returned.  In the failure case described
    above, it is possible that the last ID returned in the multiple buffer is
    the first ID in the next buffer.  In that case, we want to skip the ID that
    was already added to the IDL.
    Platforms tested: RHEL6 x86_64
    Flag Day: no
    Doc impact: no

diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c
index d62511c..9cd3daf 100644
--- a/ldap/servers/slapd/back-ldbm/idl_new.c
+++ b/ldap/servers/slapd/back-ldbm/idl_new.c
@@ -242,6 +242,7 @@ IDList * idl_new_fetch(
     /* Iterate over the duplicates, amassing them into an IDL */
 #ifdef DB_USE_BULK_FETCH
     for (;;) {
+        ID lastid = 0;
 
         DB_MULTIPLE_INIT(ptr, &data);
 
@@ -250,6 +251,13 @@ IDList * idl_new_fetch(
             if (dataret.data == NULL) break;
             if (ptr == NULL) break;
 
+            if (*(int32_t *)ptr < -1) {
+                LDAPDebug1Arg(LDAP_DEBUG_TRACE, "DB_MULTIPLE buffer is corrupt; "
+                              "next offset [%d] is less than zero\n",
+                              *(int32_t *)ptr);
+                /* retry the read */
+                break;
+            }
             if (dataret.size != sizeof(ID)) {
                 LDAPDebug(LDAP_DEBUG_ANY, "database index is corrupt; "
                           "key %s has a data item with the wrong size (%d)\n", 
@@ -257,7 +265,14 @@ IDList * idl_new_fetch(
                 goto error;
             }
             memcpy(&id, dataret.data, sizeof(ID));
-
+            if (id == lastid) { /* dup */
+                LDAPDebug1Arg(LDAP_DEBUG_TRACE, "Detedted duplicate id "
+                              "%d due to DB_MULTIPLE error - skipping\n",
+                              id);
+                continue; /* get next one */
+            }
+            /* note the last id read to check for dups */
+            lastid = id;
             /* we got another ID, add it to our IDL */
             idl_rc = idl_append_extend(&idl, id);
             if (idl_rc) {




More information about the 389-commits mailing list