We have found a bug in libraries/libldap/result.c which may cause an infinite loop in some situations.
The error is this, in the function wait4msg():
if ( rc == LDAP_MSG_X_KEEP_LOOKING && tvp != NULL ) { tmp_time = time( NULL ); tv0.tv_sec -= ( tmp_time - start_time ); if ( tv0.tv_sec <= 0 ) { rc = 0; /* timed out */ ld->ld_errno = LDAP_TIMEOUT; break; } tv.tv_sec = tv0.tv_sec; ... }
The problem is this: The check ( tv0.tv_sec <= 0 ) is always true, since tv_sec (on our system, at least) is an unsigned int.
The problem is fixed by casting it to int:
if ( (int) tv0.tv_sec <= 0 ) { ... }
however this might not be the most suitable way to fix it.
best regards,
Carsten Agger Software Consultant, TietoEnator A/S, Denmark http://www.tietoenator.dk
Carsten.Agger@tietoenator.com wrote:
We have found a bug in libraries/libldap/result.c which may cause an infinite loop in some situations.
The error is this, in the function wait4msg():
if ( rc == LDAP_MSG_X_KEEP_LOOKING && tvp != NULL ) { tmp_time = time( NULL ); tv0.tv_sec -= ( tmp_time - start_time ); if ( tv0.tv_sec <= 0 ) { rc = 0; /* timed out */ ld->ld_errno = LDAP_TIMEOUT; break; } tv.tv_sec = tv0.tv_sec; ... }
The problem is this: The check ( tv0.tv_sec <= 0 ) is always true, since tv_sec (on our system, at least) is an unsigned int.
The problem is fixed by casting it to int:
if ( (int) tv0.tv_sec <= 0 ) { ... }
however this might not be the most suitable way to fix it.
On 32 bit Linux, it is defined as long. In any case, ((unsigned) <= 0) is not always true; it's only true when ( == 0), because an unsigned cannot be negative. The solution rather consists in testing if the value of tv_sec would be negative after subtracting ( tmp_time - start_time ).
Please file a bug, and state what's your system.
p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.n.c. Via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ------------------------------------------ Office: +39.02.23998309 Mobile: +39.333.4963172 Email: pierangelo.masarati@sys-net.it ------------------------------------------
-----Original Message----- From: Pierangelo Masarati [mailto:ando@sys-net.it] Sent: Mon 3/12/2007 8:43 PM To: Agger Carsten Cc: openldap-bugs@openldap.org Subject: Re: Bug causing infinite loop in result.c
The problem is this: The check ( tv0.tv_sec <= 0 ) is always true, since tv_sec (on our system, at least) is an unsigned int.
The problem is fixed by casting it to int:
if ( (int) tv0.tv_sec <= 0 ) { ... break; }
however this might not be the most suitable way to fix it.
On 32 bit Linux, it is defined as long. In any case, ((unsigned) <= 0) is not always true; it's only true when ( == 0), because an unsigned cannot be negative. The solution rather consists in testing if the value of tv_sec would be negative after subtracting ( tmp_time - start_time ).
Please file a bug, and state what's your system.
----
OK, thanks - there was an error in my mail, of course:
What I wanted to say is is that ( tv0.tv_sec <= 0 ) is *never* true - of course, it *might* be true, but if the first subtraction to fulfil the condition makes it negative rather than zero, the condition is never reached, the "break" is never executed and we have an infinite loop.
Our system is OSE for AXE-GARP - but I'll file a bug on this.
thanks Carsten