tags 227621 + patch thanks On Mon, Jun 06, 2005 at 01:10:01PM +0200, Peter Palúch wrote: > There was a very similar bug in glibc some time ago. The problem appeared > when a line in /etc/group was longer than 1023 characters - the routines in > glibc allocated more and more memory in an infinite loop until all free > memory was exhausted. It was reported as bug #208428 and I have contributed > some information to it. However, the problem in glibc has been solved since > then. You will find some detailed information in the bug report archive. The > bug was finally solved upstream in an other way that I suggested - but > surely it was a better solution.
It's about the same bug in perl as it was in glibc. reentr.pl line 698 reads: $call = qq[((PL_REENTRANT_RETINT = $call)$test ? $true : (((PL_REENTRANT_RETINT == ERANGE) || (errno == ERANGE)) ? ($seenm{$func}{$seenr{$func}})Perl_reentrant_retry("$func"$rv) : 0))]; The problem here is "errno == ERANGE". If, at any time, there's a line longer than the initial buffer, getgrent() (or any in the same family) will get ERANGE back (and errno will be set to ERANGE). However, this is never reset. Thus, when getgrent_r() hits EOF, it returns ENOENT, _but errno is still ERANGE_. Perl figures the buffer was too small, doubles it and tries again, but still gets ENOENT, of course (and errno is still ERANGE). This goes on forever and ever until you run out of memory (which happens quite fast). The solution is simply to remove "errno == ERANGE" AFAICS; getgrent_r() does not define what happens to errno, and the return message will always be ERANGE if the buffer is too small. I'm a bit tempted to tag this "security"; if a user can (say) change his or her own GECOS field to make it long enough, Perl programs using getpwent() will crash, for instance. I can't find any direct way to exploit it (chfn limits the length of the fields, for instance), but I'm still slightly concerned over the possibilities of a DoS; Cc-ing debian-security. /* Steinar */ -- Homepage: http://www.sesse.net/ -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]