Please do not reply directly to this email. All additional comments should be made in the comments box of this bug report.
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=172336
Summary: getgrnam() crashes with "Out of memory" if /etc/group contains long lines Product: Fedora Core Version: fc4 Platform: i386 URL: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=227621 OS/Version: Linux Status: NEW Severity: security Priority: normal Component: perl AssignedTo: jvdias@redhat.com ReportedBy: jvdias@redhat.com QAContact: dkl@redhat.com CC: fedora-perl-devel-list@redhat.com,prockai@redhat.com
+++ This bug was initially created as a clone of Bug #163958 +++
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050720 Firefox/1.0.6
Description of problem: This bug has been fixed in Debian and in newest Perl. I'm just wondering does this concern RHEL 3 too, because we are rather close having "too much" users in one group and I would rather see this bug fixed before that we are going to have problems.
* Fix test of reenterant function return values which was causing perl to malloc itself to death if ERANGE was encountered before ENOENT (such as a long line in /etc/group; closes: #227621).
Version-Release number of selected component (if applicable):
How reproducible: Didn't try
Additional info:
-- Additional comment from jvdias@redhat.com on 2005-11-02 16:23 EST -- This is PERL bug 37056, fixed with patch 25084 in bleadperl (5.9.x): ( http://rt.perl.org/rt3/Ticket/Display.html?id=37056 ) Subject: getgrent fails if a line in /etc/groups gets too long Date: Fri, 02 Sep 2005 15:53:08 +0200 To: perlbug@perl.org From: Michiel Blotwijk michiel@blotwijk.com
This is a bug report for perl from michiel@altiplano.be, generated with the help of perlbug 1.35 running under perl v5.8.5.
----------------------------------------------------------------- [Please enter your report here]
The function getgrent throws an error if a line in /etc/groups gets too long (> 3000 characters). This error can be reproduced as follows:
1/ Manually add a large number of users to a group in /etc/group. It doesn't really matter if these are real users or not, as long as the line exceeds 3000 characters.
2/ perl -e 'use User::grent; while (my $gr = getgrent() ) { print $gr->name."\n"; }'
This will return an "Out of memory!" message.
This thread seems to be related: http://lists.debian.org/debian-security/2005/06/msg00041.html
Originally reported at Debian:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=227621
As said in the Debian bug report:
From: "Steinar H. Gunderson" sgunderson@bigfoot.com To: Peter PalĂșch peterp@frix.fri.utc.sk Cc: control@bugs.debian.org, 227621@bugs.debian.org, debian-security@lists.debian.org Subject: Re: perl: getgrnam() crashes with "Out of memory" if /etc/group contains long lines Date: Fri, 10 Jun 2005 15:03:02 +0200
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 */
I agree this bug has security implications .
This problem affects all {get,set}* nss perl wrapper functions, not only getgrent .
This problem affects all previous releases of PERL in all current Red Hat releases.
The patch is very straightforward - replace all occurences of ((PL_REENTRANT_RETINT == ERANGE) || (errno == ERANGE)) with (PL_REENTRANT_RETINT == ERANGE) in reentr.inc and reentr.pl.
This bug is now being fixed in these perl versions:
Rawhide / FC-5 : perl-5.8.7-0.7.fc5 FC-4 : perl-5.8.6-16 RHEL-4 : perl-5.8.5-17.RHEL4 RHEL-3 : perl-5.8.0-90.2