Blob Blame History Raw
From 22c173192bb0dc189d8db84bbe8f0555b071f731 Mon Sep 17 00:00:00 2001
From: Tomas Jelinek <tojeline@redhat.com>
Date: Thu, 3 Sep 2015 17:14:05 +0200
Subject: [PATCH] fixed command injection vulnerability

---
 pcsd/fenceagent.rb | 18 ++++++++++++------
 pcsd/remote.rb     |  1 +
 pcsd/resource.rb   | 11 ++++++-----
 3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/pcsd/fenceagent.rb b/pcsd/fenceagent.rb
index 8b37147..c348597 100644
--- a/pcsd/fenceagent.rb
+++ b/pcsd/fenceagent.rb
@@ -18,12 +18,6 @@ def getFenceAgents(fence_agent = nil)
 end
 
 def getFenceAgentMetadata(fenceagentname)
-  # There are bugs in stonith_admin & the new fence_agents interaction
-  # eventually we'll want to switch back to this, but for now we directly
-  # call the agent to get metadata
-  #metadata = `stonith_admin --metadata -a #{fenceagentname}`
-  metadata = `/usr/sbin/#{fenceagentname} -o metadata`
-  doc = REXML::Document.new(metadata)
   options_required = {}
   options_optional = {}
   options_advanced = {
@@ -39,6 +33,18 @@ def getFenceAgentMetadata(fenceagentname)
     options_advanced["pcmk_" + a + "_timeout"] = ""
     options_advanced["pcmk_" + a + "_retries"] = ""
   end
+  # There are bugs in stonith_admin & the new fence_agents interaction
+  # eventually we'll want to switch back to this, but for now we directly
+  # call the agent to get metadata
+  #metadata = `stonith_admin --metadata -a #{fenceagentname}`
+  if not fenceagentname.start_with?('fence_') or fenceagentname.include?('/')
+    return [options_required, options_optional, options_advanced]
+  end
+  stdout, stderr, retval = run_cmd(
+    "/usr/sbin/#{fenceagentname}", '-o', 'metadata'
+  )
+  doc = REXML::Document.new(stdout.join)
+
   doc.elements.each('resource-agent/parameters/parameter') { |param|
     temp_array = []
     if param.elements["shortdesc"]
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
index fe4a5d9..b3eca7e 100644
--- a/pcsd/remote.rb
+++ b/pcsd/remote.rb
@@ -840,6 +840,7 @@ def resource_metadata (params)
   return 200 if not params[:resourcename] or params[:resourcename] == ""
   resource_name = params[:resourcename][params[:resourcename].rindex(':')+1..-1]
   class_provider = params[:resourcename][0,params[:resourcename].rindex(':')]
+  return [400, 'Invalid resource agent name'] if resource_name.include?('/')
 
   @resource = ResourceAgent.new(params[:resourcename])
   if class_provider == "ocf:heartbeat"
diff --git a/pcsd/resource.rb b/pcsd/resource.rb
index 387e791..4e159f8 100644
--- a/pcsd/resource.rb
+++ b/pcsd/resource.rb
@@ -103,11 +103,12 @@ def getResourceOptions(resource_id,stonith=false)
 
   ret = {}
   if stonith
-    resource_options = `#{PCS} stonith show #{resource_id}`
+    command = [PCS, 'stonith', 'show', resource_id]
   else
-    resource_options = `#{PCS} resource show #{resource_id}`
+    command = [PCS, 'resource', 'show', resource_id]
   end
-  resource_options.each_line { |line|
+  stdout, stderr, retval = run_cmd(*command)
+  stdout.each { |line|
     keyval = line.strip.split(/: /,2)
     if keyval[0] == "Attributes" then
       options = keyval[1].split(/ /)
@@ -281,8 +282,8 @@ end
 
 def getResourceMetadata(resourcepath)
   ENV['OCF_ROOT'] = OCF_ROOT
-  metadata = `#{resourcepath} meta-data`
-  doc = REXML::Document.new(metadata)
+  stdout, stderr, retval = run_cmd(resourcepath, 'meta-data')
+  doc = REXML::Document.new(stdout.join)
   options_required = {}
   options_optional = {}
   long_desc = ""
-- 
1.9.1