Bug 709393 (CVE-2011-2491)

Summary: CVE-2011-2491 kernel: rpc task leak after flock()ing NFS share
Product: [Other] Security Response Reporter: Vasily Averin <vvs>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact: Norm Murray <nmurray>
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: arozansk, bhu, dhoward, fhrbata, jkacur, kmcmartin, lgoncalv, lwang, nmurray, nobody, plougher, pmatouse, rwheeler, security-response-team, sforsber, steved, tcallawa, williams
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-07-29 12:48:36 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: 709546, 709547, 709548, 709549, 709550, 752999    
Bug Blocks:    
Attachments:
Description Flags
dmesg output with NFS/NLM/RPC debug
none
patch for 2.6.39 kernel
none
Proposed patch from Trond none

Description Vasily Averin 2011-05-31 15:31:26 UTC
Created attachment 502027 [details]
dmesg output with NFS/NLM/RPC debug

btw. I'm reporting this issue to akpm@ and to Trond Myklebust because other vendors and upstream linux kernel is affected too.

Description of problem:
unprivileged user can use flock syscall for NFS share to trigger unlimited resource leak and this could cause node DoS.

Details:
flock on NFS calls nlmclnt_lock() function, where nlmclnt_call() executes synchronous RPC task NLMPROC_LOCK. Via several subcalls (call_bind) it successfully connects to NFS server and decodes its reply, however because server did not set up r_port rpcb_getport_done() returns -EACCES, and following rpc subcall call_bind_status() in this case repeats call_bind() after 3 sec timeout.

It isn't a big problem, and this cycle could be broken by signal, however error path of nlmclnt_lock() executes identical asynchronous RPC call to unlock taken lock. Waiting of result of this call is also canceled by signal, however in this case RPC call is asynchronous, it cycles too and never finished.

I would like to ask Trond to recheck my analyze and review my patch with fix of this issue or propose some better and more correct solution.

My idea is to break cycle described above, return -EOPNOTSUPP to nlmclnt_lock(), check it on error path and do not execute NLMPROC_UNLOCK call because we already know that server does not support locking operations.

PS. one more separate issue: NLMPROC_UNLOCK can be cycled in another place: nlmclnt_unlock_callback() restarts RPC task in case of any errors. Therefore we cannot execute NLMPROC_UNLOCK on error path in case of server errors. I did not reproduce this issue, however I believe it's possible.

PPS. Also I've found similar cycles in other nlm callbacks, however I have no ideas is it possible to exploit it. However I would like to ask Trond to review this code too.

Version-Release number of selected component (if applicable):
2.6.32-131.0.15.el6.x86_64
I've reproduced this issue on RHEL5, RHEL6, ubuntu 11.04 and upstream linux kernel 2.6.39. 

How reproducible:
100%

Actual results:
flock hangs, can be canceled by signal, as result one more rpc task leaks
(FYI: sysctl -w sunrpc.rpc_debug=0 dumps status of active RPC taks) 

Expected results:
no hangs, no leaks

Additional info:
dmesg output with NFS/NLM/RPC debug and concept of patch are attached.
Because  vendor-sec is no longer in use I'm preparing private report to akpm@ and to Trond Myklebust, probably they can propose some better solution

Comment 1 Vasily Averin 2011-05-31 15:36:57 UTC
Created attachment 502030 [details]
patch for 2.6.39 kernel

Comment 3 Eugene Teo (Security Response) 2011-06-01 01:00:30 UTC
Created attachment 502142 [details]
Proposed patch from Trond

How about something like the appended fix? It should deal with errors
such as the rebind issue, but only after retrying a few times.

Cheers
 Trond

Comment 7 Eugene Teo (Security Response) 2011-06-01 01:12:53 UTC
Acknowledgements:

Red Hat would like to thank Vasily Averin for reporting this issue.

Comment 8 Eugene Teo (Security Response) 2011-06-23 07:09:42 UTC
Upstream commit:
http://git.kernel.org/linus/0b760113a3a155269a3fba93a409c640031dd68f

Comment 15 errata-xmlrpc 2011-08-23 14:41:53 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 6

Via RHSA-2011:1189 https://rhn.redhat.com/errata/RHSA-2011-1189.html

Comment 16 errata-xmlrpc 2011-09-12 19:44:31 UTC
This issue has been addressed in following products:

  MRG for RHEL-6 v.2

Via RHSA-2011:1253 https://rhn.redhat.com/errata/RHSA-2011-1253.html

Comment 17 errata-xmlrpc 2011-09-13 15:44:05 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5

Via RHSA-2011:1212 https://rhn.redhat.com/errata/RHSA-2011-1212.html

Comment 19 errata-xmlrpc 2011-12-13 21:28:57 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5.6.Z - Server Only

Via RHSA-2011:1813 https://rhn.redhat.com/errata/RHSA-2011-1813.html