Bug 962035 (CVE-2013-2065)

Summary: CVE-2013-2065 Ruby: Object taint bypassing in DL and Fiddle
Product: [Other] Security Response Reporter: Kurt Seifried <kseifried>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: bkabrda, bleanhar, ccoleman, dmcphers, drieden, jdetiber, jialiu, jkurik, jstribny, kseifried, lmeyer, mmaslano, mmcgrath, mmorsi, mtasaka, nobody+bgollahe, ohadlevy, security-response-team, tagoh, tdawson, vanmeeuwen+fedora, vondruch
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-06-25 07:50:03 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: 962862, 963988, 963989, 963990    
Bug Blocks: 948853    
Attachments:
Description Flags
1-9-fiddle-tainting-CVE-2013-2065.patch
none
2-0-fiddle-tainting-CVE-2013-2065.patch none

Description Kurt Seifried 2013-05-11 05:03:41 UTC
Aaron Patterson (tenderlove) reports:

Object taint bypassing in DL and Fiddle in Ruby

There is a vulnerability in DL and Fiddle in Ruby where tainted strings can be
used by system calls regardless of the $SAFE level set in Ruby. This
vulnerability has been assigned the CVE identifier CVE-2013-2065.

Versions Affected:  1.9.3-pX, 2.0.0-p0
Not affected:       1.8.X
Fixed Versions:     1.9.3-pX, 2.0.0-pX

Impact 
------
Native functions exposed to Ruby with DL or Fiddle do not check the taint
values set on the objects passed in.  This can result in tainted objects being
accepted as input when a SecurityError exception should be raised.

Impacted DL code will look something like this:

    def my_function(user_input)
      handle    = DL.dlopen(nil)
      sys_cfunc = DL::CFunc.new(handle['system'], DL::TYPE_INT, 'system')
      sys       = DL::Function.new(sys_cfunc, [DL::TYPE_VOIDP])
      sys.call user_input
    end
    
    $SAFE = 1
    my_function "uname -rs".taint

Impacted Fiddle code will look something like this:

    def my_function(user_input)
      handle    = DL.dlopen(nil)
      sys = Fiddle::Function.new(handle['system'],
                              [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
      sys.call user_input
    end
    
    $SAFE = 1
    my_function "uname -rs".taint

All users running an affected release should either upgrade or use one of the
work arounds immediately. 

Note that this *does not* prevent numeric memory offsets from being used as
pointer values.  Numbers cannot be tainted, so code passing a numeric memory
offset cannot be checked.  For example:

    def my_function(input)
      handle    = DL.dlopen(nil)
      sys = Fiddle::Function.new(handle['system'],
                              [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
      sys.call input
    end
    
    $SAFE = 1
    user_input = "uname -rs".taint
    my_function DL::CPtr[user_input].to_i

In this case, the memory location is passed, and taintedness of the object
cannot be determined by DL / Fiddle.  In this case, please check the tainting
of the user input before passing the memory location:

    user_input = "uname -rs".taint
    raise if $SAFE >= 1 && user_input.tainted?
    my_function DL::CPtr[user_input].to_i


Releases 
-------- 
The FIXED releases are available at the normal locations. 

Workarounds 
----------- 
This monkey patch can be used as a workaround:

    class Fiddle::Function
      alias :old_call :call
      def call(*args)
        if $SAFE >= 1 && args.any? { |x| x.tainted? }
          raise SecurityError, "tainted parameter not allowed"
        end
        old_call(*args)
      end
    end

Patches 
------- 
To aid users who aren't able to upgrade immediately we have provided patches
for the two supported release series.  They are in git-am format and consist
of a single changeset.

* 1-9-fiddle-tainting.patch - Patch for 1.9 series 
* 2-0-fiddle-tainting.patch - Patch for 2.0 series

Comment 2 Kurt Seifried 2013-05-11 05:10:28 UTC
Created attachment 746494 [details]
1-9-fiddle-tainting-CVE-2013-2065.patch

Comment 3 Kurt Seifried 2013-05-11 05:10:47 UTC
Created attachment 746495 [details]
2-0-fiddle-tainting-CVE-2013-2065.patch

Comment 4 Vincent Danen 2013-05-14 15:33:12 UTC
External References:

http://www.ruby-lang.org/en/news/2013/05/14/taint-bypass-dl-fiddle-cve-2013-2065/

Comment 5 Vincent Danen 2013-05-14 15:36:58 UTC
Created ruby tracking bugs for this issue

Affects: fedora-all [bug 962862]

Comment 6 Kurt Seifried 2013-05-15 03:03:20 UTC
Vulnerable versions are:

* All ruby 1.9 versions prior to ruby 1.9.3 patchlevel 426
* All ruby 2.0 versions prior to ruby 2.0.0 patchlevel 195
* prior to trunk revision 40728

Non vulnerable versions are:

* ruby 1.8 versions are not affected.

Comment 10 Fedora Update System 2013-05-30 03:37:36 UTC
ruby-2.0.0.195-8.fc19 has been pushed to the Fedora 19 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 11 Kurt Seifried 2013-10-02 20:37:39 UTC
Acknowledgements:

This issue was discovered by Vit Ondruch of Red Hat.

Comment 12 Kurt Seifried 2014-06-25 07:50:03 UTC
Statement:

(none)

Comment 13 Adam Mariš 2015-07-30 12:53:51 UTC
Upstream patch:

https://github.com/ruby/ruby/commit/c7d7ff45f1e0d6fad28e53c02108d4b067e843c3