Bug 435631 - ruby recurses indefinitely when cwd is broken and path empty
ruby recurses indefinitely when cwd is broken and path empty
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: ruby (Show other bugs)
5.1
All Linux
urgent Severity medium
: rc
: ---
Assigned To: Vít Ondruch
QE Internationalization Bugs
: Patch
Depends On:
Blocks: 668957 719046
  Show dependency treegraph
 
Reported: 2008-03-02 14:01 EST by Andrew Hecox
Modified: 2012-02-21 01:00 EST (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2012-02-21 01:00:29 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
check maxpathlen patch (795 bytes, patch)
2008-03-02 14:12 EST, Andrew Hecox
no flags Details | Diff
ruby getcwd path based on upstream code. (307 bytes, patch)
2008-04-08 09:35 EDT, ritz
no flags Details | Diff

  None (edit)
Description Andrew Hecox 2008-03-02 14:01:16 EST
In 1.8.5's version of path_check_0(), the ruby vm recurses until it determines
it's absolute path:

path_check_0(fpath, loadpath)
{
  ... 
  if (!is_absolute_path(p0)) {
    ...
    return path_check_0(newpath, loadpath);
  }
  ...
}

However, if the environment's path is broken and getcwd unable to determine the
 full path of the current working directory, ruby will recurse indefinitely (or
until consuming all available memory).

The reproducer is fairly obtuse but replicates a problem a customer is seeing
on-site.

To reproduce:

sudo mount <nfs>:<export> /mnt/
cd /mnt/foo
sudo umount -l /mnt/
PATH=

Then run any ruby program. I used:

#!/usr/bin/ruby -w
kernel = %x{/bin/uname -s}.chomp

A better behavior would be to error out after any reasonable chance of
determining an absolute path has failed.
Comment 1 Andrew Hecox 2008-03-02 14:12:19 EST
The following patch presents one way of fixing the recursion problem by raising
a rb_eRuntimeError if the relative path built in path_check_0 grows beyond
MAXPATHLEN (eg, 4096). While not specifically targeting the case of a broken
cwd, it seems a reasonable check to perform under all conditions.

Another option would be to backport 1.8.6's non-recursive implementation of
path_check_0; I did not do this because it relied on a series of macros defined
in 1.8.6 not present in our version. However, that seems another reasonable and
simple solution.

I also fixed some white-space in the effected conditional block. 
Comment 2 Andrew Hecox 2008-03-02 14:12:51 EST
Created attachment 296521 [details]
check maxpathlen patch
Comment 3 ritz 2008-04-08 09:35:07 EDT
Created attachment 301632 [details]
ruby getcwd path based on upstream code.
Comment 4 RHEL Product and Program Management 2008-07-21 19:05:52 EDT
This request was evaluated by Red Hat Product Management for
inclusion, but this component is not scheduled to be updated in
the current Red Hat Enterprise Linux release. If you would like
this request to be reviewed for the next minor release, ask your
support representative to set the next rhel-x.y flag to "?".
Comment 9 RHEL Product and Program Management 2009-03-26 13:11:49 EDT
This request was evaluated by Red Hat Product Management for
inclusion, but this component is not scheduled to be updated in
the current Red Hat Enterprise Linux release. If you would like
this request to be reviewed for the next minor release, ask your
support representative to set the next rhel-x.y flag to "?".
Comment 15 RHEL Product and Program Management 2010-08-09 15:35:01 EDT
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated in the
current release, Red Hat is unfortunately unable to address this
request at this time. Red Hat invites you to ask your support
representative to propose this request, if appropriate and relevant,
in the next release of Red Hat Enterprise Linux.
Comment 20 RHEL Product and Program Management 2011-05-31 11:47:44 EDT
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated in the
current release, Red Hat is unfortunately unable to address this
request at this time. Red Hat invites you to ask your support
representative to propose this request, if appropriate and relevant,
in the next release of Red Hat Enterprise Linux.
Comment 24 Bohuslav "Slavek" Kabrda 2011-09-22 02:25:28 EDT
I have been investigating this problem and it seems, that the patch in comment 3 by ritz is ok.
I have reproduced the bug and the problem is, that if you do the steps from comment 1:

sudo mount <nfs>:<export> /mnt/
cd /mnt/foo
sudo umount -l /mnt/
PATH=

then my_getcwd() function used to get the current working directory returns only 'foo/' (if you 'cd /mnt/foo/bar' instead of just 'cd /mnt/foo', my_getcwd returns 'foo/bar').
So when you call the function for the first time, it finds out that the path is not absolute (because its empty, thats why the 'PATH=' has to be present), so it calls my_getcwd and before recursing, it has "newpath = 'foo/'". This is not absolute path, so in the next call, the function prepends another 'foo/' to newpath. Therefore the recursion never ends, constructing the newpath in form of 'foo/foo/foo/foo/...', which is never absolute.

The patch works because my_getcwd uses getcwd (which returns an absolute path in a normal case), so in a normal case, the recursion is not needed anyway. In the special case mentioned in comment 1, getcwd returns just foo/ and path_check_0 continues (and works) normally.
Comment 27 errata-xmlrpc 2012-02-21 01:00:29 EST
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHBA-2012-0218.html

Note You need to log in before you can comment on or make changes to this bug.