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

Re: perl: getgrnam() crashes with "Out of memory" if /etc/group contains long lines

tags 227621 + patch

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/

Reply to: