-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 OpenAFS Security Advisory 2019-003 Topic: database server crash from unserialized data access Issued: 22 October, 2019 Affected: OpenAFS versions 1.0 through 1.6.23, and 1.8.0 through 1.8.4 Database servers in the SVOTE_Debug() RPC handler can encounter a segmentation fault and crash during certain circumstances, when running in parallel with the end of a write transaction on the database. SUMMARY ======= The SVOTE_Debug() RPC handler used to implement the main udebug(1) functionality performs unlocked accesses to a global pointer variable, dereferencing it if the first access returns a non-NULL value. Since the accesses are not serialized against writes, the value can change between accesses (e.g., to become NULL), with the attempted dereference generating a segmentation fault. IMPACT ====== The impact of this issue can be limited by the compiler and options used to compile the server code in question. For example, gcc on some popular linux distributions is able to optimize the two memory accesses into a single load, so the value being dereferenced to check the type of the transaction will never be NULL. (It might point into freed memory, but for the memory allocators in use on these linux systems, that memory is highly unlikely to have been unmapped in the intervening period, so the access would merely return bad data rather than crashing.) Other compilers/architectures do not make this optimization, such as the Solaris cc, and the resulting binaries are impacted. Since the VOTE_Debug() RPC does not require authentication, a remote attacker can attempt to call the RPC repeatedly and overlap with the end of a write transaction; crashes have been observed simply by running udebug(1) in a tight loop. AFFECTED SOFTWARE ================= All releases of OpenAFS prior to 1.6.24 are affected, as are OpenAFS 1.8.0 through 1.8.4. Database server processes built against LWP (instead of pthreads) are not affected by this issue. Database server processes are built against LWP by default in 1.6 releases, but are built against pthreads by default in 1.8 releases. FIXES ===== The OpenAFS project recommends that administrators upgrade all database servers to the 1.8.5 or 1.6.24 releases. It is necessary to restart the database server processes in order for the fixes to take effect. Using a firewall to block or rate-limit VOTE_Debug() RPCs from untrusted sources may be an adequate workaround. DETAILS ======= The udebug(1) utility is a debugging tool, and as such does not require authenticated access for the RPC calls it performs. Most of its functionality comes from the VOTE_Debug() RPC, which was written to prioritize speed and avoiding disruption of normal database operation over correctness of output. Accordingly, it accesses global state without adhering to the normal locking/serialization mechanisms for access to that state. This means that the returned results can be incorrect or inconsistent, but that tradeoff was part of its original design. One of the pieces of information returned by SVOTE_Debug() is whether there is a current transaction on the database, and if so, whether it is a write transaction. The current transaction is stored as a global pointer to a transaction structure (ubik_currentTrans), so whether or not there is an ongoing transaction is a question of whether ubik_currentTrans is non-NULL; the type of transaction (read vs. write) is stored in a field in the pointed-to structure. However, we only ever create a transaction structure for ubik_currentTrans in the case of a write transaction, so checking the type stored in the transaction structure provides no value for this case! Because SVOTE_Debug() does not take any locks, it can run in parallel with a running transaction, and in particular, the end of that transaction. This means that the value of ubik_currentTrans can change between accesses, and thus that the state determined by the first access ("there is a current transaction") can be invalid by the time of the second access (which dereferences the pointer). In this case, an invalid pointer is dereferenced, leading to a segmentation fault and application crash. ACKNOWLEDGMENTS =============== Thanks to Andrew Deason for the detailed report and contributed patch. -----BEGIN PGP SIGNATURE----- iQG3BAEBCgAdFiEE2WGV4E2ARf9BYP0XKNmm82TrdRIFAl2vjWsACgkQKNmm82Tr dRLTfgwg1/96x8b3WpwMg4YUwE/RmFJZpKiI7/lscPcLsH3Jn4Ru72jqN5vUa9dW 6nCYLNqOeSPm0QDqQOz2bzle1HlcTYaCOoh446Y2kwGpBWicpyAm70SRkEiPgnVr UR0XmfqIw0s5h7S98VPJYWeyOE6eQiH2pdjHsyg5duwg09e/Rvw+XBR4L4VQPlvx JpK1Aa5V+1//n0egOhImFxFCMh6a9PBkuHsxjn9++f3TmM744qUbFM2SsW20OtTo IaC518yt9Eoeyw84MnKdTzRVa6gNFcRq7wp8ls9t8zY46Q3aDEAnipkOo+2OVy7e 2cLAZ4t6vvRJKH1FBbA58DsNM+wDoiKJO0+3xYquRmIs0EbkOVpE99XNu7FUX7w2 c0xCobqlozhbuJIluSV/XbyETvKvQHg7MtKPcDN8Hgf7e12UxgisfcD8uOjb1Toj bpx+Y6VX3Du/tW82lbZ5/1jXjiluDtAwDSHXLQbGO2JzAdtuSqiQNDpITXSUTwiH rzYCDiJT9PivIg== =s4yw -----END PGP SIGNATURE-----