[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: slapd-mtread crash on ppc64{,el} in stretch/sid



Ryan,

> Nice. I was able to reproduce it and debug it further. The problem seems
> to be related to a invalid branch/jump, the the next address is not
> memory mapped, thus the segfault. The new address is completely random,
> and definitely is wrong. 

I think I found the real case of the problem here. There is an array
being allocated, and initialized until 'i'.

Later, we use a random number 'r' to access this array, and it will fail
if 'r' is bigger than 'i', since any value bigger than 'i' will not be
initialized. It might fail harder if 'r' is being allocated than 'nvalues', but
I didn't get this scenario during my debugs.

That is how I see the array and how we are trying to access it:

0                         i                        nvalues          RAND_MAX
|-------------------------|---------------------------|--------------|
|     initialized         |       mapped              | unmapped     |
|-------------------------|---------------------------|--------------|

I understand that forcing the values to be smaller than 'i' is what we want.

This is a patch I've created to fix this problem. The problem seems to happen
upstream also. If this patch is OK for you , I will create a pull request
to send this fix upstream.

---

diff --git a/tests/progs/slapd-mtread.c b/tests/progs/slapd-mtread.c
index c9c872918..15316b360 100644
--- a/tests/progs/slapd-mtread.c
+++ b/tests/progs/slapd-mtread.c
@@ -635,7 +635,7 @@ do_random( LDAP *ld,
        int     i = 0, do_retry = maxretries;
        char    *attrs[ 2 ];
        int     rc = LDAP_SUCCESS;
-       int     nvalues = 0;
+       int     maxnvalue, nvalues = 0;
        char    **values = NULL;
        LDAPMessage *res = NULL, *e = NULL;
        char    thrstr[BUFSIZ];
@@ -668,6 +668,7 @@ do_random( LDAP *ld,
                        values[ i ] = ldap_get_dn( ld, e );
                }
                values[ i ] = NULL;
+               maxnvalue = i;

                ldap_msgfree( res );

@@ -680,6 +681,7 @@ do_random( LDAP *ld,

                for ( i = 0; i < innerloop; i++ ) {
                        int     r = ((double)nvalues)*rand()/(RAND_MAX + 1.0);
+                       r %= maxnvalue;

                        do_read( ld, values[ r ],
                                srchattrs, noattrs, nobind, 1, maxretries,


Reply to: