Vulnerability: In the web ui of the openbuildservice before 2.3.0 a code injection of the project rebuildtimes statistics could be used by authorized attackers to execute shellcode.
Vulnerability ID: CVE-2011-3178
CWE: CWE-94
Severity score: 6.4
Project: https://github.com/openSUSE/open-build-service
Published: 2018-03-20
File: src/webui/app/controllers/project_controller.rb
Commit message: [webui] check the value of the scheduler parameter
Commit author: Stephan Kulow

Vulnerable version (before fix):
 def rebuild_time     @arch = params[:arch]     @hosts = begin Integer(params[:hosts] || '40') rescue 40 end     @scheduler = params[:scheduler] || 'needed'     bdep = find_cached(BuilddepInfo, :project => @project.name, :repository => @repository, :arch => @arch)     jobs = find_cached(Jobhislist , :project => @project.name, :repository => @repository, :arch => @arch,              :limit => @packages.each.size * 3, :code => ['succeeded', 'unchanged']) def rebuild_time     f.write(jobs.dump_xml)     f.close     outdir = Dir.mktmpdir     cmd="perl ./mkdiststats '--srcdir=#{indir}' '--destdir=#{outdir}' --outfmt=xml #{@project.name}/#{@repository}/#{@arch} --width=910 --buildhosts=#{@hosts} --scheduler=#{@scheduler}"     logger.debug "cd #{RAILS_ROOT}/vendor/diststats && #{cmd}"     system("cd #{RAILS_ROOT}/vendor/diststats && #{cmd}")     f=File.open(outdir + "/rebuild.png")     png=f.read     f.close 

Fixed version (after fix):
 def rebuild_time     @arch = params[:arch]     @hosts = begin Integer(params[:hosts] || '40') rescue 40 end     @scheduler = params[:scheduler] || 'needed'     unless ["fifo", "lifo", "random", "btime", "needed", "neededb", "longest_data", "longested_triedread", "longest"].include? @scheduler       flash[:error] = "Invalid scheduler type, check mkdiststats docu - aehm, source"       redirect_to :action => :show, :project => @project       return     end     bdep = find_cached(BuilddepInfo, :project => @project.name, :repository => @repository, :arch => @arch)     jobs = find_cached(Jobhislist , :project => @project.name, :repository => @repository, :arch => @arch,              :limit => @packages.each.size * 3, :code => ['succeeded', 'unchanged']) def rebuild_time     f.write(jobs.dump_xml)     f.close     outdir = Dir.mktmpdir     logger.debug "cd #{RAILS_ROOT}/vendor/diststats && perl ./mkdiststats --srcdir=#{indir} --destdir=#{outdir}               --outfmt=xml #{@project.name}/#{@repository}/#{@arch} --width=910              --buildhosts=#{@hosts} --scheduler=#{@scheduler}"     fork do       Dir.chdir("#{RAILS_ROOT}/vendor/diststats")       system("perl", "./mkdiststats", "--srcdir=#{indir}", "--destdir=#{outdir}",               "--outfmt=xml", "#{@project.name}/#{@repository}/#{@arch}", "--width=910",              "--buildhosts=#{@hosts}", "--scheduler=#{@scheduler}")     end     Process.wait     f=File.open(outdir + "/rebuild.png")     png=f.read     f.close 

Patch:
patch: @@ -457,6 +457,11 @@ def rebuild_time
     @arch = params[:arch]
     @hosts = begin Integer(params[:hosts] || '40') rescue 40 end
     @scheduler = params[:scheduler] || 'needed'
+    unless ["fifo", "lifo", "random", "btime", "needed", "neededb", "longest_data", "longested_triedread", "longest"].include? @scheduler
+      flash[:error] = "Invalid scheduler type, check mkdiststats docu - aehm, source"
+      redirect_to :action => :show, :project => @project
+      return
+    end
     bdep = find_cached(BuilddepInfo, :project => @project.name, :repository => @repository, :arch => @arch)
     jobs = find_cached(Jobhislist , :project => @project.name, :repository => @repository, :arch => @arch, 
             :limit => @packages.each.size * 3, :code => ['succeeded', 'unchanged'])
@@ -473,9 +478,16 @@ def rebuild_time
     f.write(jobs.dump_xml)
     f.close
     outdir = Dir.mktmpdir
-    cmd="perl ./mkdiststats '--srcdir=#{indir}' '--destdir=#{outdir}' --outfmt=xml #{@project.name}/#{@repository}/#{@arch} --width=910 --buildhosts=#{@hosts} --scheduler=#{@scheduler}"
-    logger.debug "cd #{RAILS_ROOT}/vendor/diststats && #{cmd}"
-    system("cd #{RAILS_ROOT}/vendor/diststats && #{cmd}")
+    logger.debug "cd #{RAILS_ROOT}/vendor/diststats && perl ./mkdiststats --srcdir=#{indir} --destdir=#{outdir} 
+             --outfmt=xml #{@project.name}/#{@repository}/#{@arch} --width=910
+             --buildhosts=#{@hosts} --scheduler=#{@scheduler}"
+    fork do
+      Dir.chdir("#{RAILS_ROOT}/vendor/diststats")
+      system("perl", "./mkdiststats", "--srcdir=#{indir}", "--destdir=#{outdir}", 
+             "--outfmt=xml", "#{@project.name}/#{@repository}/#{@arch}", "--width=910",
+             "--buildhosts=#{@hosts}", "--scheduler=#{@scheduler}")
+    end
+    Process.wait
     f=File.open(outdir + "/rebuild.png")
     png=f.read
     f.close
path: src/webui/app/controllers/project_controller.rb