Bug 222918

Summary: server crash after deleting supposedly deleted attribute
Product: [Retired] 389 Reporter: Michal Vocu <tucnacek>
Component: Database - Indexes/SearchesAssignee: Noriko Hosoi <nhosoi>
Status: CLOSED CURRENTRELEASE QA Contact: Viktor Ashirov <vashirov>
Severity: high Docs Contact:
Priority: high    
Version: 1.0.2   
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-12-07 16:41:31 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 152373, 240316, 427409    
Attachments:
Description Flags
cvs diffs
none
revised diff for string.c
none
cvs commit message
none
schema definition
none
server DSE none

Description Michal Vocu 2007-01-16 21:13:03 UTC
Description of problem:
After modify operation which replaces indexed attribute with empty value (ie.
deletes it) the attribute does not seem to be actually removed; subsequent
delete operation of that attribute crashes the server.

Version-Release number of selected component (if applicable):
FDS 1.0.2

How reproducible:
On my configuration always, however another server with different configuration
(and database) survives.

Steps to Reproduce:
1. Use the following LDIF:

dn: cuniPersonalId=99853826,ou=people,dc=cuni,dc=cz
changetype: modify
replace: eduPersonPrimaryOrgUnitDN
eduPersonPrimaryOrgUnitDN: dc=fsv,dc=cuni,dc=cz
-
replace: eduPersonPrimaryAffiliation
eduPersonPrimaryAffiliation: staff
-
replace: eduPersonAffiliation
eduPersonAffiliation: staff
-
replace: eduPersonScopedAffiliation
eduPersonScopedAffiliation: staff.cz
-
replace: eduPersonOrgUnitDN
eduPersonOrgUnitDN: dc=fsv,dc=cuni,dc=cz
-
replace: cuniPrincipalName
-

dn: cuniPersonalId=99853826,ou=people,dc=cuni,dc=cz
changetype: modify
delete: cuniPrincipalName

  
Actual results:
Server crashes.

Expected results:
Server denies the second operation (delete), because given attribute is not present.

Additional info:
This is the backtrace info from debugger:
#0  0xb774c141 in string_values2keys (pb=0xbc5f92d4, bvals=0x0,
    ivals=0xbc5f9594, syntax=1, ftype=163) at string.c:315
#1  0xb774d38b in cis_values2keys (pb=0xbc5f92d4, vals=0x0, ivals=0xbc5f9594,
    ftype=163) at cis.c:297
#2  0xb7ed4d1d in slapi_call_syntax_values2keys_sv (vpi=0x80eaf30, vals=0x0,
    ivals=0xbc5f9594, ftype=163) at plugin_syntax.c:290
#3  0xb6baefc0 in index_addordel_values_ext_sv (be=0x831e940,
    type=0x84d9118 "cuniPrincipalName", vals=0x0, evals=0x0, id=90558,
    flags=38, txn=0xbc5f9814, idl_disposition=0x0, buffer_handle=0x0)
    at index.c:1736
#4  0xb6baecf6 in index_addordel_values_sv (be=0x831e940,
    type=0x84d9118 "cuniPrincipalName", vals=0x0, evals=0x0, id=90558,
    flags=38, txn=0xbc5f9814) at index.c:1660
#5  0xb6bac777 in index_add_mods (be=0x831e940, mods=0x856aae8,
    olde=0x851ac10, newe=0x856ac40, txn=0xbc5f9814) at index.c:621
#6  0xb6bea0c2 in ldbm_back_modify (pb=0x81b7ab0) at ldbm_modify.c:389
#7  0xb7efaaee in op_shared_modify (pb=0x81b7ab0, pw_change=0, old_pw=0x0)
    at modify.c:780
#8  0xb7ef9b1b in do_modify (pb=0x81b7ab0) at modify.c:334
#9  0x080568e2 in connection_dispatch_operation (conn=0xb4a60708,
    op=0x8569440, pb=0x81b7ab0) at connection.c:487
#10 0x08058063 in connection_threadmain () at connection.c:2117
#11 0xb7d3f3b1 in _pt_root () from ../lib/libnspr4.so
#12 0xb7c7fe51 in pthread_start_thread () from /lib/libpthread.so.0
#13 0xb7a7e8aa in clone () from /lib/libc.so.6

The relevant line in string.c reads:
		for ( numbvals = 0; bvals[numbvals] != NULL; numbvals++ ) {

Segmentation fault occurs because bvals is NULL and this is not checked for;
however this is only a manifestation of different issue - apparently the
attribute remains in the entry (possibly with NULL value) after the first
operation even if it should be gone.

The server that crashes is the replication master; the server that I could not
crash in this way does not use replication; maybe that has something to do with it.

Comment 1 Noriko Hosoi 2007-09-26 01:58:27 UTC
First of all, sorry about this late response.

> How reproducible:
> On my configuration always, however another server with different configuration
> (and database) survives.

Fixing the code not to access the contents of NULL is easy, but I'd like to
reproduce the problem in house.  Could you help me by sharing your env info? 
E.g., is it your custom schema?  Could you give us the definition of
cuniPrincipalName?  Also, have you indexed on the attribute?  If yes, what type
of indexes?  E.g., equality and presence?

Thank you for your support.

Comment 2 Noriko Hosoi 2007-09-28 19:52:21 UTC
Created attachment 210881 [details]
cvs diffs

Files: servers/plugins/syntaxes/string.c servers/slapd/back-ldbm/index.c

Description: I tried to reproduce the problem, but it failed.
I tried the test with the stress with nsslapd-serial-lock: off, but the
condition was not the key.  My test always issues:
  ldap_modify: No such attribute
at the second deletion.
I tried index attribute as well as unindex, but no luck.

Anyway, although I could not reproduce the crash, but the stacktrace indicates
even if there is no attribute to delete, it calls index_addordel_values_sv with
NULL vals, which is not supposed to, I think.

Also, string_values2keys in string.c is not ready to accept NULL bvals.

I changed these two files so that even if the condition is realized, the server
won't crash.

Comment 3 Rich Megginson 2007-09-28 20:31:24 UTC
In this code -
https://bugzilla.redhat.com/attachment.cgi?id=210881&action=diff#servers/plugins/syntaxes/string.c_sec1

if ( n == 0 ) {
    slapi_ch_free((void**)nbvals );
    return( 0 );
}

I think we need to set ivals (or *ivals) = NULL before we return.  It depends on
if the caller can handle ivals == NULL or expects ivals to be an array with the
first element NULL.

Also, I think you need to pass &nbvals to slapi_ch_free().

Otherwise, ok.

Comment 4 Noriko Hosoi 2007-09-28 20:48:09 UTC
(In reply to comment #3)
> In this code -
>
https://bugzilla.redhat.com/attachment.cgi?id=210881&action=diff#servers/plugins/syntaxes/string.c_sec1
> 
> if ( n == 0 ) {
>     slapi_ch_free((void**)nbvals );
>     return( 0 );
> }
> 
> I think we need to set ivals (or *ivals) = NULL before we return.  It depends on
> if the caller can handle ivals == NULL or expects ivals to be an array with the
> first element NULL.
> 
> Also, I think you need to pass &nbvals to slapi_ch_free().
> 
> Otherwise, ok.

Thank you, Rich!  That was an important point...  The third arg is ivals.  If we
return NULL, then it'd make the server crash.  I'm making sure
string_values2keys not to return NULL ivals...
        if ( slapi_call_syntax_values2keys_sv( pi, (Slapi_Value**)va, &keyvals,
LDAP_FILTER_EQUALITY ) != 0 ) /* jcm cast */
        {
            [...]
            for ( i = 0; rc==LDAP_SUCCESS && va[i] != NULL; ++i )
            { 
                if ( keyvals[i] == NULL )  <== if keyvals is NULL, it crashes here!
                {


Comment 5 Noriko Hosoi 2007-09-28 23:13:13 UTC
Created attachment 211091 [details]
revised diff for string.c

Based upon the comment from Rich, revised plugin/syntax/string.c:

-		 if ( n == 0 ) {
-			 slapi_ch_free((void**)ivals );
-			 return( 0 );
-		 }
+		 /* even if (n == 0), we should return the array nbvals w/ NULL

items */
		 *ivals = nbvals;
		 break;

Comment 6 Noriko Hosoi 2007-09-28 23:47:42 UTC
Created attachment 211111 [details]
cvs commit message

Reivewed by Rich and Nathan (Thank you!!)

Checked in into CVS HEAD.

Comment 7 Michal Vocu 2007-10-02 13:59:06 UTC
Created attachment 213441 [details]
schema definition

I attach the schema definition used by the server.

Comment 8 Michal Vocu 2007-10-02 14:00:11 UTC
Created attachment 213451 [details]
server DSE

I attach the server configuration from DSE entry (keys and passwords are not
included :-)

Comment 9 Noriko Hosoi 2007-10-02 16:21:04 UTC
Thanks a lot, Michal!  I'm using your data to verify the change.