Bug#701882: release.debian.org: unblock: chef/10.12.0-3
Package: release.debian.org
Severity: normal
The security fix in ruby-json 1.7.3-3 broke chef, and this is worked
around in the just-uploaded 10.12.0-3 version of chef. Please unblock
this version.
Debdiff attached.
--
Tollef Fog Heen
UNIX is user friendly, it's just picky about who its friends are
diff -Nru chef-10.12.0/debian/changelog chef-10.12.0/debian/changelog
--- chef-10.12.0/debian/changelog 2012-08-05 21:04:52.000000000 +0200
+++ chef-10.12.0/debian/changelog 2013-02-28 14:07:45.000000000 +0100
@@ -1,3 +1,10 @@
+chef (10.12.0-3) unstable; urgency=high
+
+ * Backport fixes from 10.22 to work around API breakage in JSON gem.
+ Closes: #701629
+
+ -- Tollef Fog Heen <tfheen@debian.org> Thu, 28 Feb 2013 13:56:32 +0100
+
chef (10.12.0-2) unstable; urgency=low
* Team upload
diff -Nru chef-10.12.0/debian/patches/json_create_CVE-2013-0269_workaround.diff chef-10.12.0/debian/patches/json_create_CVE-2013-0269_workaround.diff
--- chef-10.12.0/debian/patches/json_create_CVE-2013-0269_workaround.diff 1970-01-01 01:00:00.000000000 +0100
+++ chef-10.12.0/debian/patches/json_create_CVE-2013-0269_workaround.diff 2013-02-28 13:54:47.000000000 +0100
@@ -0,0 +1,165 @@
+diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb
+index 1c2deef..c7c9503 100644
+--- a/lib/chef/cookbook_version.rb
++++ b/lib/chef/cookbook_version.rb
+@@ -807,7 +807,7 @@ class Chef
+ cookbook_version.manifest = o
+
+ # We don't need the following step when we decide to stop supporting deprecated operators in the metadata (e.g. <<, >>)
+- cookbook_version.manifest["metadata"] = JSON.parse(cookbook_version.metadata.to_json)
++ cookbook_version.manifest["metadata"] = Chef::JSONCompat.from_json(cookbook_version.metadata.to_json)
+
+ cookbook_version.freeze_version if o["frozen?"]
+ cookbook_version
+diff --git a/lib/chef/json_compat.rb b/lib/chef/json_compat.rb
+index 9f59a41..4e14a11 100644
+--- a/lib/chef/json_compat.rb
++++ b/lib/chef/json_compat.rb
+@@ -24,6 +24,22 @@ class Chef
+ class JSONCompat
+ JSON_MAX_NESTING = 1000
+
++ JSON_CLASS = "json_class".freeze
++
++ CHEF_APICLIENT = "Chef::ApiClient".freeze
++ CHEF_CHECKSUM = "Chef::Checksum".freeze
++ CHEF_COOKBOOKVERSION = "Chef::CookbookVersion".freeze
++ CHEF_DATABAG = "Chef::DataBag".freeze
++ CHEF_DATABAGITEM = "Chef::DataBagItem".freeze
++ CHEF_ENVIRONMENT = "Chef::Environment".freeze
++ CHEF_NODE = "Chef::Node".freeze
++ CHEF_ROLE = "Chef::Role".freeze
++ CHEF_SANDBOX = "Chef::Sandbox".freeze
++ CHEF_RESOURCE = "Chef::Resource".freeze
++ CHEF_RESOURCECOLLECTION = "Chef::ResourceCollection".freeze
++ CHEF_WEBUIUSER = "Chef::WebUIUser".freeze
++ CHEF_OPENIDREGISTRAION = "Chef::OpenIDRegistration".freeze
++
+ class <<self
+ # See CHEF-1292/PL-538. Increase the max nesting for JSON, which defaults
+ # to 19, and isn't enough for some (for example, a Node within a Node)
+@@ -38,7 +54,49 @@ class Chef
+
+ # Just call the JSON gem's parse method with a modified :max_nesting field
+ def from_json(source, opts = {})
+- ::JSON.parse(source, opts_add_max_nesting(opts))
++ obj = ::Yajl::Parser.parse(source)
++
++ unless obj.kind_of?(Hash) || obj.kind_of?(Array)
++ raise JSON::ParserError, "Top level JSON object must be a Hash or Array (actual: #{obj.class})"
++ end
++
++ # The old default in the json gem (which we are mimicing because we
++ # sadly rely on this misfeature) is to "create additions" i.e., convert
++ # JSON objects into ruby objects. Explicit :create_additions => false
++ # is required to turn it off.
++ if opts[:create_additions].nil? || opts[:create_additions]
++ map_to_rb_obj(obj)
++ else
++ obj
++ end
++ rescue Yajl::ParseError => e
++ raise JSON::ParserError, e.message
++ end
++
++ # Look at an object that's a basic type (from json parse) and convert it
++ # to an instance of Chef classes if desired.
++ def map_to_rb_obj(json_obj)
++ res = case json_obj
++ when Hash
++ mapped_hash = map_hash_to_rb_obj(json_obj)
++ if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS]))
++ class_to_inflate.json_create(mapped_hash)
++ else
++ mapped_hash
++ end
++ when Array
++ json_obj.map {|e| map_to_rb_obj(e) }
++ else
++ json_obj
++ end
++ res
++ end
++
++ def map_hash_to_rb_obj(json_hash)
++ json_hash.each do |key, value|
++ json_hash[key] = map_to_rb_obj(value)
++ end
++ json_hash
+ end
+
+ def to_json(obj, opts = nil)
+@@ -48,6 +106,44 @@ class Chef
+ def to_json_pretty(obj, opts = nil)
+ ::JSON.pretty_generate(obj, opts_add_max_nesting(opts))
+ end
++
++
++ def class_for_json_class(json_class)
++ case json_class
++ when CHEF_APICLIENT
++ Chef::ApiClient
++ when CHEF_CHECKSUM
++ Chef::Checksum
++ when CHEF_COOKBOOKVERSION
++ Chef::CookbookVersion
++ when CHEF_DATABAG
++ Chef::DataBag
++ when CHEF_DATABAGITEM
++ Chef::DataBagItem
++ when CHEF_ENVIRONMENT
++ Chef::Environment
++ when CHEF_NODE
++ Chef::Node
++ when CHEF_ROLE
++ Chef::Role
++ when CHEF_SANDBOX
++ Chef::Sandbox
++ when CHEF_RESOURCE
++ Chef::Resource
++ when CHEF_RESOURCECOLLECTION
++ Chef::ResourceCollection
++ when CHEF_WEBUIUSER
++ Chef::WebUIUser
++ when CHEF_OPENIDREGISTRAION
++ Chef::OpenIDRegistration
++ when /^Chef::Resource/
++ Chef::Resource.find_subclass_by_name(json_class)
++ else
++ raise JSON::ParserError, "Unsupported `json_class` type '#{json_class}'"
++ end
++ end
++
+ end
+ end
+ end
++
+diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
+index 2fd3942..b8f7603 100644
+--- a/lib/chef/resource.rb
++++ b/lib/chef/resource.rb
+@@ -74,6 +74,24 @@ F
+ FORBIDDEN_IVARS = [:@run_context, :@node, :@not_if, :@only_if]
+ HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@node]
+
++ # Track all subclasses of Resource. This is used so names can be looked up
++ # when attempting to deserialize from JSON. (See: json_compat)
++ def self.resource_classes
++ @resource_classes ||= []
++ end
++
++ # Callback when subclass is defined. Adds subclass to list of subclasses.
++ def self.inherited(subclass)
++ resource_classes << subclass
++ end
++
++ # Look up a subclass by +class_name+ which should be a string that matches
++ # `Subclass.name`
++ def self.find_subclass_by_name(class_name)
++ resource_classes.first {|c| c.name == class_name }
++ end
++
++
+ include Chef::Mixin::CheckHelper
+ include Chef::Mixin::ParamsValidate
+ include Chef::Mixin::Language
diff -Nru chef-10.12.0/debian/patches/series chef-10.12.0/debian/patches/series
--- chef-10.12.0/debian/patches/series 2012-08-05 21:04:52.000000000 +0200
+++ chef-10.12.0/debian/patches/series 2013-02-28 13:55:09.000000000 +0100
@@ -1 +1,2 @@
remove_rubygems.diff
+json_create_CVE-2013-0269_workaround.diff
Reply to: