Bug 893307 (CVE-2013-0164)

Summary: CVE-2013-0164 openshift-origin-port-proxy: openshift-port-proxy-cfg lockwrap() tmp file creation
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: bleanhar, calfonso, jialiu, jlieskov, jrusnack, lmeyer, rmillner, security-response-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard: impact=low,public=20130131,reported=20130104,source=redhat,cvss2=2.1/AV:L/AC:L/Au:N/C:N/I:N/A:P,openshift-enterprise-1/openshift-origin-port-proxy=affected,cwe=CWE-377
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-04-23 08:57:57 EDT Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Bug Depends On: 892050, 901379    
Bug Blocks: 767033, 893315    
Attachments:
Description Flags
Move the request files to /var/run/openshift-port-proxy none

Description Kurt Seifried 2013-01-09 00:35:29 EST
Michael Scherer (misc@zarb.org) of Red Hat reports:

Looking at a recent git checkout of openshift, I found that some script use a 
hardcoded or easy to guess filename in /tmp, in this case :
https://github.com/openshift/origin-server/blob/master/port-proxy/bin/openshift-port-proxy-cfg#L13

I am not sure this can be exploited, but after searching a while, here is a 
credible attack.

This filename is used on https://github.com/openshift/origin-server/blob/master/port-proxy/bin/openshift-port-proxy-cfg#L144

While it took me a while to figure what the code of lockwrap does exactly, I 
found out there is a small windows of time between "we check the file exist 
and is empty" and "we write 0 or a return code to the file". 

Let's imagine the following scenario, some attacker has shell access to the 
server that run this ( ie, a openshift node if I am not wrong ). People have 
access to the node, at least on openshift-online and this is required to push 
with git the code ( unless setup otherwise ).

This attacker create 5000 empty files who match the pattern 
/tmp/openshift-port-proxy-reload.req.????? ( and this could be something else 
than numbers, like .aaaaa ). Then he wait, and 1 second after, erase it and 
replace it by a link to another arbitrary file. Doing it with the 5000 files 
and a proper timing ( like waiting 1/5000 second between each file operation )
would make sure that if a operation check a file and then 1 second later, 
write to the file, this would not be the same for at least 1 of them. ( at
least, that's my understanding, timing may be harder to get right on a real 
computer with enough ram, cpu and fast disk than the one I imagined ). 
Another variant would be to use something that is triggered when stat is run, 
but inotify cannot be used, and audit subsystem requires root.

Then, if someone else run the script and enter the function lockwrap that 
reload the proxy, it would first do a stat to check the file is empty 
(https://github.com/openshift/origin-server/blob/master/port-proxy/bin/openshift-port-proxy-cfg#L152) 
then reload the proxy ( and check all others file with stat before ), and 
there is a non negligeable chance that the script would write the return code 
in a different file ( ie, if that's a link, write it somewhere else ), since 
it write on all files matching the pattern, and not only the one created by 
mkstemp. 


Depending on the kernel configuration and installation, this can be mitigated 
( openshift online use polyinstanciation of /tmp, for example, newer kernel 
ship the yama module, for another example ). But in the most favourable case 
for the attacker ( ie no protection ), this mean he can create a file in a 
arbitray location with a content of 0 or 1.

The script is executed as root , as part as the user creation :
https://github.com/openshift/origin-server/blob/master/node/lib/openshift-origin-node/model/unix_user.rb#L87 , function create, just after running useradd 
command ( hence the assumption this is run as root ) 

that function call initialize_openshift_port_proxy 
https://github.com/openshift/origin-server/blob/master/node/lib/openshift-origin-node/model/unix_user.rb#L139

that run the command "openshift-port-proxy-cfg setproxy"
 
https://github.com/openshift/origin-server/blob/master/node/lib/openshift-origin-node/model/unix_user.rb#L583

that then that script run the function lockwrap :
https://github.com/openshift/origin-server/blob/master/port-proxy/bin/openshift-port-proxy-cfg#L263

and then lockwrap trigger the problem described before.


So a attacker could just create and remove several application until the 
attack succeed, ie, bruteforce it and make a 0 or 1 be written in a arbitrary 
location as root ( if selinux, polyinstanciation etc are disabled ).

openshift-origin-port-proxy is part of the entreprise release version 1, IIRC,
of F18 and rawhide. 

So I think this will requires a errata and a CVE if I am not wrong on my 
analysis of the problem. The issue was not discussed with anyone explicitely 
(I just discussed about the code on #fedora-devel on irc.freenode.net with 2 
others fedora packagers but the exact issue was not disclosed ).
Comment 1 Rob Millner 2013-01-09 16:48:27 EST
This should never be a problem for the online service; gear logins get their own polyinstantiated /tmp.  But we should move the reqfiles to a special, locked down directory anyway since this code only ever runs as root.
Comment 2 Rob Millner 2013-01-09 17:31:33 EST
Pull request...

https://github.com/openshift/origin-server/pull/1136
Comment 3 Rob Millner 2013-01-09 17:49:36 EST
Created attachment 675901 [details]
Move the request files to /var/run/openshift-port-proxy
Comment 4 Rob Millner 2013-01-09 17:51:17 EST
Pull request cancelled due to the embargo and the patch was added as an attachment to this BZ.
Comment 11 Murray McAllister 2013-01-30 04:07:25 EST
Acknowledgements:

This issue was discovered by Michael Scherer of the Red Hat Regional IT team.
Comment 12 errata-xmlrpc 2013-01-31 15:34:37 EST
This issue has been addressed in following products:

  RHEL 6 Version of OpenShift Enterprise

Via RHSA-2013:0220 https://rhn.redhat.com/errata/RHSA-2013-0220.html