On Fri, Jun 27, 2008 at 03:17:10PM +0000, Andrew Findlay wrote:
> Hmm: I now have a crasher in attr_valadd when adding a member to a
> group that already contains two members. Not sure yet whether I caused it
> with the minus-one-line fix above, or whether I have uncovered a new
> problem.
> for ( j = a->a_numvals; j >= slot; j-- ) {
> a->a_vals[j+1] = a->a_vals[j]; <==================== Crash here
> if ( nvals )
> a->a_nvals[j+1] = a->a_nvals[j];
> }
... so I stepped through that in GDB. j did indeed start at 2 and
decrement to 0, but then it kept going!
407 for ( j = a->a_numvals; j >= slot; j-- ) {
(gdb)
408 a->a_vals[j+1] = a->a_vals[j];
(gdb) print j
$17 = 1
(gdb) print a->a_vals[j]
$18 = {bv_len = 97,
bv_val = 0x847b680 "uniqueIdentifier=a3,ou=accounts,uniqueIdentifier=to-a,dc=orgs,...."}
(gdb) n
409 if ( nvals )
(gdb)
410 a->a_nvals[j+1] = a->a_nvals[j];
(gdb)
407 for ( j = a->a_numvals; j >= slot; j-- ) {
(gdb)
408 a->a_vals[j+1] = a->a_vals[j];
(gdb) print print a->a_vals[j]
A syntax error in expression, near `a->a_vals[j]'.
(gdb) print a->a_vals[j]
$19 = {bv_len = 96,
bv_val = 0x847b618 "uniqueIdentifier=ag1,ou=groups,uniqueIdentifier=to-a,dc=orgs,..."}
(gdb) n
slap_client_connect: URI=ldap://localhost:2389/ DN="cn=replicator,dc=accounts,...." ldap_sasl_bind_s failed (-1)
do_syncrepl: rid=002 retrying (5 retries left)
409 if ( nvals )
(gdb)
410 a->a_nvals[j+1] = a->a_nvals[j];
(gdb)
407 for ( j = a->a_numvals; j >= slot; j-- ) {
(gdb)
408 a->a_vals[j+1] = a->a_vals[j];
(gdb) print j
$20 = -1
(gdb) n
409 if ( nvals )
(gdb) print slot
$21 = 0
(gdb) n
410 a->a_nvals[j+1] = a->a_nvals[j];
(gdb)
slap_client_connect: URI=ldap://localhost:2389/ DN="cn=replicator,dc=accounts,..." ldap_sasl_bind_s failed (-1)
do_syncrepl: rid=002 retrying (4 retries left)
407 for ( j = a->a_numvals; j >= slot; j-- ) {
(gdb)
408 a->a_vals[j+1] = a->a_vals[j];
(gdb) print j
$22 = -2
(gdb) print j >= slot
$23 = 1
(gdb) print slot
$24 = 0
Curiouser and curiouser cried Alice...
(gdb) whatis j
type = int
(gdb) whatis slot
type = unsigned int
Aha! Comparing signed and unsigned integers. Could be risky.
I don't do much C these days, and I don't see many explicit type-casts
in OpenLDAP code. What would be a good-practice solution here?
Casting slot to long int seems to work for me so I have updated the patch:
ftp://ftp.openldap.org/incoming/andrew.findlay-sortvals-20080627.patch
Andrew
--
-----------------------------------------------------------------------
| From Andrew Findlay, Skills 1st Ltd |
| Consultant in large-scale systems, networks, and directory services |
| http://www.skills-1st.co.uk/ +44 1628 782565 |
-----------------------------------------------------------------------
On Thu, Jun 26, 2008 at 10:00:00AM +0000, Andrew Findlay wrote:
> I have uploaded a proposed fix for this:
>
> ftp://ftp.openldap.org/incoming/andrew-findlay-sortvals-20080626.patch
>
> My reasoning is that the break statement terminates the loop before
> the last value in the list has been compared with the assertion value.
> Thus, even if the last value matches, the loop ends with -1 in 'match'.
Hmm: I now have a crasher in attr_valadd when adding a member to a
group that already contains two members. Not sure yet whether I caused it
with the minus-one-line fix above, or whether I have uncovered a new
problem.
I would expect the new value to sort at the front of the list.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1518945392 (LWP 1431)]
0x0806e650 in attr_valadd (a=0xa6c71084, vals=0x847a148, nvals=0x847a190, nn=1) at attr.c:410
410 a->a_nvals[j+1] = a->a_nvals[j];
(gdb) where
#0 0x0806e650 in attr_valadd (a=0xa6c71084, vals=0x847a148, nvals=0x847a190, nn=1) at attr.c:410
#1 0x080b4db3 in modify_add_values (e=0xa5769cb0, mod=0x8479a98, permissive=0, text=0xa576b17c, textbuf=0xa5769bb0 "",
textlen=256) at mods.c:155
#2 0x080d0d4e in bdb_modify_internal (op=0x83964e0, tid=0x847b400, modlist=0x8479a98, e=0xa5769cb0, text=0xa576b17c,
textbuf=0xa5769bb0 "", textlen=256) at modify.c:101
#3 0x080d1926 in bdb_modify (op=0x83964e0, rs=0xa576b168) at modify.c:578
#4 0x080c6b21 in overlay_op_walk (op=0x83964e0, rs=0xa576b168, which=op_modify, oi=0x82f9a18, on=0x82fa0c8) at backover.c:646
#5 0x080c709d in over_op_func (op=0x83964e0, rs=0xa576b168, which=op_modify) at backover.c:698
#6 0x0807dd36 in fe_op_modify (op=0x83964e0, rs=0xa576b168) at modify.c:300
#7 0x0807e6a8 in do_modify (op=0x83964e0, rs=0xa576b168) at modify.c:175
#8 0x08065646 in connection_operation (ctx=0xa576b238, arg_v=0x83964e0) at connection.c:1084
#9 0x08065c42 in connection_read_thread (ctx=0xa576b238, argv=0x1f) at connection.c:1211
#10 0x0817e454 in ldap_int_thread_pool_wrapper (xpool=0x82b4310) at tpool.c:663
#11 0xb7c19112 in start_thread () from /lib/libpthread.so.0
#12 0xb7ba52ee in clone () from /lib/libc.so.6
(gdb) print j
$1 = -305887
(gdb) print a
$2 = (Attribute *) 0xa6c71084
(gdb) print *a
$3 = {a_desc = 0x82e12e8, a_vals = 0x847ba28, a_nvals = 0x847b6e8, a_numvals = 2, a_flags = 16, a_next = 0xa6c7bd34}
(gdb) print slot
$4 = 0
(gdb) print nvals
$5 = (BerVarray) 0x847a190
(gdb)
The relevant code block is this:
/* If sorted and old vals exist, must insert */
if (( a->a_flags & SLAP_ATTR_SORTED_VALS ) && a->a_numvals ) {
unsigned slot;
int j, rc;
v2 = nvals ? nvals : vals;
for ( i = 0; i < nn; i++ ) {
rc = attr_valfind( a, SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX |
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
&v2[i], &slot, NULL );
if ( rc != LDAP_NO_SUCH_ATTRIBUTE ) {
/* should never happen */
if ( rc == LDAP_SUCCESS )
rc = LDAP_TYPE_OR_VALUE_EXISTS;
return rc;
}
for ( j = a->a_numvals; j >= slot; j-- ) {
a->a_vals[j+1] = a->a_vals[j]; <==================== Crash here
if ( nvals )
a->a_nvals[j+1] = a->a_nvals[j];
}
ber_dupbv( &a->a_nvals[slot], &v2[i] );
if ( nvals )
ber_dupbv( &a->a_vals[slot], &vals[i] );
a->a_numvals++;
}
BER_BVZERO( &a->a_vals[a->a_numvals] );
if ( a->a_vals != a->a_nvals )
BER_BVZERO( &a->a_nvals[a->a_numvals] );
} else {
I cannot see how j got that large negative value. It should have started the
loop at 2 (a->a_numvals) and decremented until it reached zero.
Must have been overwritten somewhere.
Andrew
--
-----------------------------------------------------------------------
| From Andrew Findlay, Skills 1st Ltd |
| Consultant in large-scale systems, networks, and directory services |
| http://www.skills-1st.co.uk/ +44 1628 782565 |
-----------------------------------------------------------------------
Howard Chu wrote:
> zdi-disclosures(a)tippingpoint.com wrote:
>> Full_Name: Cameron Hotchkies
>> Version: 2.3.41
>> OS: Gentoo Linux
>> URL: ftp://ftp.openldap.org/incoming/
>> Submission from: (NULL) (66.179.208.36)
>>
>>
>> This vulnerability allows remote attackers to deny services on vulnerable
>> installations of OpenLDAP. Authentication is not required to exploit this
>> vulnerability.
>
> Thanks for the report, a fix is now in HEAD. Please test.
For future reference, it looks like this may have crept in in 2001, rev
1.88/ITS#2465...
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/
zdi-disclosures(a)tippingpoint.com wrote:
> Full_Name: Cameron Hotchkies
> Version: 2.3.41
> OS: Gentoo Linux
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (66.179.208.36)
>
>
> This vulnerability allows remote attackers to deny services on vulnerable
> installations of OpenLDAP. Authentication is not required to exploit this
> vulnerability.
Thanks for the report, a fix is now in HEAD. Please test.
> The specific flaw exists in the decoding of ASN.1 BER network datagrams. When
> the size of a BerElement is specified incorrectly, the application will trigger
> an assert(), leading to abnormal program termination.
> Tech Details:
>
> The code exhibiting the problem is located in the function ber_get_next()
> function in "libraries/liblber/io.c" .
>
> The function fails to handle properly BER encoding of an element (tag + length +
> content) that contains:
>
> * exactly 4 bytes long "multi-byte tag"
> * exactly 4 bytes long "multi-byte size"
>
> The total size of the resulting encoding equals to the size of the BerElement
> structure buffer plus one byte. This causes the function returns indicating that
> more data are needed, but leaves the read-pointer pointing right at the end of
> the buffer, which is not permitted.
>
> Subsequent calls to the function result in an assertion failure:
>
> assert( 0 ); /* ber structure is messed up ?*/
>
> Example Exploitation:
>
> > slapd -h ldap:// -d511&
> ...
> > xxd packet
> 0000000: ffff ff00 8441 4243 44 .....ABCD
> > nc localhost 389< packet
>
>
>
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/
Full_Name: Anderson M. Gomes
Version: 2.4.9 (but 2.4.10 has the bug)
OS: Ubuntu 8.04.1
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (189.58.241.178)
I submitted a bug report in Ubuntu's Launchpad. The address is:
https://bugs.launchpad.net/ubuntu/+source/openldap2.3/+bug/243337
The bug refers to 2.4.9, but it is reproducible in OpenLDAP 2.4.10 (I could
reproduce it, at least).
Full_Name: Cameron Hotchkies
Version: 2.3.41
OS: Gentoo Linux
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (66.179.208.36)
This vulnerability allows remote attackers to deny services on vulnerable
installations of OpenLDAP. Authentication is not required to exploit this
vulnerability.
The specific flaw exists in the decoding of ASN.1 BER network datagrams. When
the size of a BerElement is specified incorrectly, the application will trigger
an assert(), leading to abnormal program termination.
Tech Details:
The code exhibiting the problem is located in the function ber_get_next()
function in "libraries/liblber/io.c" .
The function fails to handle properly BER encoding of an element (tag + length +
content) that contains:
* exactly 4 bytes long "multi-byte tag"
* exactly 4 bytes long "multi-byte size"
The total size of the resulting encoding equals to the size of the BerElement
structure buffer plus one byte. This causes the function returns indicating that
more data are needed, but leaves the read-pointer pointing right at the end of
the buffer, which is not permitted.
Subsequent calls to the function result in an assertion failure:
assert( 0 ); /* ber structure is messed up ?*/
Example Exploitation:
> slapd -h ldap:// -d511 &
...
> xxd packet
0000000: ffff ff00 8441 4243 44 .....ABCD
> nc localhost 389 < packet
Full_Name: Andrew Findlay
Version: 2.4.10
OS: Linux
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (88.97.25.132)
If an account becomes locked due to excessive failed authentications, its entry
will contain the attributes pwdFailureTime and pwdAccountLockedTime. If the
account is subsequently unlocked by setting a new password, all values of those
attributes are automatically removed. However, if the password is left alone and
the account is unlocked by removing pwdAccountLockedTime, values remain in
pwdFailureTime. This means that a single authentication failure will immediately
lock the account again.
pwdFailureTime cannot be modified directly, so I think there is a case for
clearing it when pwdAccountLockedTime is cleared explicitly.
Andrew
I have uploaded a proposed fix for this:
ftp://ftp.openldap.org/incoming/andrew-findlay-sortvals-20080626.patch
My reasoning is that the break statement terminates the loop before
the last value in the list has been compared with the assertion value.
Thus, even if the last value matches, the loop ends with -1 in 'match'.
Andrew
--
-----------------------------------------------------------------------
| From Andrew Findlay, Skills 1st Ltd |
| Consultant in large-scale systems, networks, and directory services |
| http://www.skills-1st.co.uk/ +44 1628 782565 |
-----------------------------------------------------------------------
On Wed, Jun 25, 2008 at 08:10:56PM +0000, Andrew Findlay wrote:
> When 'sortvals members' is in effect, some attribute modify operations produce
> bad results. This seems to occur when an operation adds an attribute that sorts
> to the end of the list.
Having thought about this some more I now think that the problem
is to do with read/search rather than add. The last value in the
list cannot be matched however it got there.
The test data I uploaded with the ITS contains this group entry:
dn: cn=tenK,ou=groups,o=test,dc=example,dc=org
objectclass: groupOfNames
cn: tenK
member: uniqueIdentifier=a_000000,dc=example,dc=org
member: uniqueIdentifier=a_000001,dc=example,dc=org
member: uniqueIdentifier=a_004994,dc=example,dc=org
member: uniqueIdentifier=a_004995,dc=example,dc=org
member: uniqueIdentifier=a_004996,dc=example,dc=org
member: uniqueIdentifier=a_004997,dc=example,dc=org
member: uniqueIdentifier=a_004998,dc=example,dc=org
member: uniqueIdentifier=a_004999,dc=example,dc=org
member: uniqueIdentifier=a_005000,dc=example,dc=org
If I do a search for any value except the last one, it succeeds:
./bound-search member=uniqueIdentifier=a_004999,dc=example,dc=org
# tenK, groups, test, example.org
dn: cn=tenK,ou=groups,o=test,dc=example,dc=org
objectClass: groupOfNames
cn: tenK
member: uniqueIdentifier=a_000000,dc=example,dc=org
member: uniqueIdentifier=a_000001,dc=example,dc=org
member: uniqueIdentifier=a_004994,dc=example,dc=org
member: uniqueIdentifier=a_004995,dc=example,dc=org
member: uniqueIdentifier=a_004996,dc=example,dc=org
member: uniqueIdentifier=a_004997,dc=example,dc=org
member: uniqueIdentifier=a_004998,dc=example,dc=org
member: uniqueIdentifier=a_004999,dc=example,dc=org
member: uniqueIdentifier=a_005000,dc=example,dc=org
# search result
search: 2
result: 0 Success
./bound-search member=uniqueIdentifier=a_005000,dc=example,dc=org
... this does not find anything
This explains why the add and modify operations failed in such
an odd way.
Andrew
--
-----------------------------------------------------------------------
| From Andrew Findlay, Skills 1st Ltd |
| Consultant in large-scale systems, networks, and directory services |
| http://www.skills-1st.co.uk/ +44 1628 782565 |
-----------------------------------------------------------------------
Hi,
On Tue, Jun 24, 2008 at 3:37 PM, <unix.gurus(a)gmail.com> wrote:
> On Tue, Jun 24, 2008 at 12:50 PM, <unix.gurus(a)gmail.com> wrote:
>> Hi,
>>
>> I have uploaded a patch against HEAD that normalizes the attributes
>> used under cn=monitor according to the schema:
>> ftp://ftp.openldap.org/incoming/sean-burford-monitor-normalize-080624.patch
>
> Unified diff of the same thing:
> sean-burford-monitor-normalize-unified-080624.patch
>
> The search (namingContexts:distinguishedNameMatch:=CN=...) returns the
> expected results, I'll check what filterentry.c:test_mra_filter() is
> up to later.
As far as I can tell the arguments passed to
filterentry.c:test_mra_filter() for that search also look sane, so
whilst it passes my tests I'm looking forward to an official opinion
on this patch.
> make test also completes successfully, for what it's worth.
--
Thanks,
Sean Burford