Bug 172327

Summary: getgrnam() crashes with "Out of memory" if /etc/group contains long lines
Product: Red Hat Enterprise Linux 4 Reporter: Jason Vas Dias <jvdias>
Component: perlAssignee: Jason Vas Dias <jvdias>
Status: CLOSED ERRATA QA Contact: David Lawrence <dkl>
Severity: medium Docs Contact:
Priority: medium    
Version: 4.0CC: poelstra, prockai, security-response-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: i386   
OS: Linux   
URL: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=227621
Whiteboard:
Fixed In Version: RHSA-2005-880 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-12-20 14:31:24 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 163958    
Bug Blocks: 168429    

Description Jason Vas Dias 2005-11-02 21:27:53 UTC
+++ 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 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
From: Michiel Blotwijk <michiel>

This is a bug report for perl from michiel,
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>
To: Peter Palúch <peterp.utc.sk>
Cc: control.org, 227621.org,
	debian-security.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

Comment 1 Jason Vas Dias 2005-11-02 22:41:24 UTC
This problem is fixed in perl-5.8.5-17.RHEL4+ .


Comment 3 Fedora Update System 2005-12-01 23:57:30 UTC
From User-Agent: XML-RPC

perl-5.8.5-18.FC3 has been pushed for FC3, which should resolve this issue.  If these problems are still present in this version, then please make note of it in this bug report.

Comment 7 Red Hat Bugzilla 2005-12-20 14:31:25 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2005-880.html