-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 OpenAFS Security Advisory 2019-001 Topic: information leakage from uninitialized RPC output variables on error Issued: 22 October, 2019 Affected: OpenAFS versions 1.0 through 1.6.23, and 1.8.0 through 1.8.4 Generated RPC handler routines ran output variables through XDR encoding even when the call had failed and would shortly be aborted (and for which uninitialized output variables is common); any complete packets assembled in the process would be sent to the peer, leaking the contents of the uninitialized memory in question. SUMMARY ======= AFS-3 RPCs use the XDR data encoding to represent input/output arguments, and OpenAFS uses an XDR en/decoder that is tightly integrated to the Rx protocol implementation. The generated RPC handler code takes care of allocating storage/variables for the input/output variables and reading the input parameters from the network into local storage before calling the function that implements the RPC logic. Similarly, after that function call, the generated code takes care of encoding the output parameters into Rx packets and sending them to the peer as necessary, then deallocating the storage it allocated and returning control flow to the caller. However, in the case of an error return from the handler, the Rx layer will abort the current Rx call to direct the peer that the operation failed, and well-behaved peers will discard any information obtained as part of the aborted call. Unfortunately, the generated code was going through the "encode output parameters" step even when the resulting data would not be of use to well-behaved peers, and in some cases the output parameters remained uninitialized in the case of error returns (on the assumption that since it was an error, the call would be aborted). So for non-well-behaved peers, a large partially constructed response could include information from uninitialized memory in the RPC handler. IMPACT ====== RPCs that produce large responses are most at risk, and configurations that use small MTU values, since those increate the likelihood of one or more complete Rx packets being filled. Leaving output variables uninitialized on error returns is a fairly common phenomenon, so many RPCs are expected to be at risk. The amount and rate of data exposure is highly context-dependent, since the memory allocator behavior and other load on the system affect exactly what information is leaked from uninitialized memory. At present, no code paths in the cache manager are known to trigger this issue, but the risk has not been conclusively shown to be absent, so clients are listed as potentially affected as well. AFFECTED SOFTWARE ================= All releases of OpenAFS prior to 1.6.24 are affected, as are OpenAFS 1.8.0 through 1.8.4. FIXES ===== The OpenAFS project recommends that administrators upgrade all machines to the 1.8.5 or 1.6.24 releases. It is necessary to restart the server processes and cache manager in order for the fixes to take effect. DETAILS ======= The AFS-3 protocol suite and OpenAFS extensions are run over the Rx RPC protocol. A variant of Sun rpcgen, rxgen, is used to generate data en/decoding routines and client- and server-side stub functions from an interface description file. In the RPC server, these stubs interface between the Rx network protocol layer and the implementation of the RPC server-side logic. The server logic is written as a normal C function, taking input variables either as pointer-to-struct or scalar-by-value, and returning output variables via pointer arguments (allocating storage as appropriate). The generated stub allocates storage on the stack for local variables to hold the input and ouput arguments of the RPC that are passed as arguments to the function implementing the server logic, and as discussed in OPENAFS-SA-2019-002, these local variables are only sometimes given an initial value; at other times they remain uninitialized and potentially refer to other content in the memory address space of the running process. Once the function implementing the server logic returns to the generated stub, the stub function uses the XDR encoder to pack the output variables from the local variables into an XDR bytestream. The way in which the OpenAFS encoder works results in Rx packets being generated by the XDR encoder, and when a complete packet is assembled, it is sent to the peer according to the Rx congestion-control logic. After all the output parameters have been encoded to the XDR bytestream, the generated stub frees any storage allocated, and then returns the result from the server logic. On success, this translates to completing any partially constructed Rx packet and sending the response code, but for error returns, any pending data is discarded and instead an Rx abort packet is sent for the Rx call over which the RPC is running. The abort indicates to the client that the RPC has failed and the XDR stream is to be discarded. Unfortunately, the XDR-encode-and-send-packets step is not skipped in the case of error returns, even though the call will ultimately be aborted and well-behaved clients will discard the XDR bytestream, there is still an opportunity for Rx packets to be generated and sent. When combined with the potential for uninitialized local variables to be included in the encoded stream, this results in a channel for the contents of uninitialized memory to be sent on the wire to a (potentially unauthenticated) peer. Vulnerabilities of this nature can be difficult to exploit, as there is not always context for *which* content from uninitialized memory is leaked to the caller, and that is in turn dependent on the allocation/deallocation patterns in the surrounding application and the other load patterns on the server. However, there are worked examples in other software of attackers being able to massage allocator state and stack contents in order to exfiltrate specific information, so it should be assumed that such attacks are also possible here given a sufficiently dedicated attacker. ACKNOWLEDGMENTS =============== Thanks to Andrew Deason for the detailed report and contributed patch. -----BEGIN PGP SIGNATURE----- iQG3BAEBCgAdFiEE2WGV4E2ARf9BYP0XKNmm82TrdRIFAl2vh/QACgkQKNmm82Tr dRJGMwwghX7qcmKA50FBq+Smhvqp1KggNnGXnt6t78opKm3uR3LfTrsDc4g4YZLG 4H24JdbYoGfyoziTJtBMLW8KubFojrZfoqgDRXgcpx2TQE36X0kzgpH2grAxE5kA wBL6aic6FxEgkF9Xw+iwo34hGv79WPHEgB0lWlGqjRj94geVh7dWjYWeL0K7JnlS WdOpmIWMUr5aMIG5G34t/XrZvoVDOrBjBKXUXFHLpYCZS7XPrxWTCOzNwyS5WehQ uBtEIgPeYVL1c+8XLA94Lyyegc8lnvdNvEU3nP9nIQTJ4x79j3bQ/PhmKQCQPMeS 3G/LKtzYTA5d2SmEQ5pfTUYCmG4ULjAdk2IT2nW20cwbWmuArzWlcCPkAH3itonO ToRpRcywjqa1Z9p0EWrwZyXKVwRt1t8areIraHiFQiuTpjecl4or4ioXggnNoeqa Ek+W/sV5sTVFZhLUlpx2VrpvahqUckc4deo/BjUzqMpPWSLZ9tgH/Qv4pCkxtD29 lvMgEDkke90EOQ== =KqJn -----END PGP SIGNATURE-----