]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
OPENAFS-SA-2019-003: ubik: Avoid unlocked ubik_currentTrans deref
authorAndrew Deason <adeason@sinenomine.net>
Mon, 16 Sep 2019 19:06:53 +0000 (14:06 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Tue, 22 Oct 2019 20:38:27 +0000 (16:38 -0400)
Currently, SVOTE_Debug/SVOTE_DebugOld examine some ubik internal state
without any locks, because the speed of these functions is more
important than accuracy.

However, one of the pieces of data we examine is ubik_currentTrans,
which we dereference to get ubik_currentTrans->type. ubik_currentTrans
could be set to NULL while this code is running, so there is a small
chance of this code causing a segfault, if SVOTE_Debug() is running
when the current transaction ends.

We only ever initialize ubik_currentTrans as a write transation (via
SDISK_Begin), so this check is pointless anyway. Accordingly, skip the
type check, and always assume that any active transaction is a write
transaction.  This means we only ever access ubik_currentTrans once,
avoiding any risk of the value changing between accesses (and we no
longer need to dereference it, anyway).

Note that, since ubik_currentTrans is not marked as 'volatile', some C
compilers, with certain options, can and do assume that its value will
not change between accesses, and thus only fetch the pointer value once.
This avoids the risk of NULL dereference (and thus, crash, if pointer
stores/loads are atomic), but the value pointed to by ubik_currentTrans->type
would be incorrect when the transaction ends during the execution of
SVOTE_Debug().

Reviewed-on: https://gerrit.openafs.org/13915
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit 6ec46ba7773089e1549d27a0d345afeca65c9472)

Change-Id: I634ddb27e7a8dbe5c9d1dacdc83070efa470b50b
Reviewed-on: https://gerrit.openafs.org/13918
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: Benjamin Kaduk <kaduk@mit.edu>
src/ubik/vote.c

index 87cfb3911e226333dafdca490cfbc7e116cf7383..3a8374e88fc57766ea1356b15a5222530a25f365 100644 (file)
@@ -441,10 +441,7 @@ SVOTE_Debug(struct rx_call * rxcall, struct ubik_debug * aparm)
 
     if (ubik_currentTrans) {
        aparm->currentTrans = 1;
-       if (ubik_currentTrans->type == UBIK_WRITETRANS)
-           aparm->writeTrans = 1;
-       else
-           aparm->writeTrans = 0;
+       aparm->writeTrans = 1;
     } else {
        aparm->currentTrans = 0;
     }
@@ -524,10 +521,7 @@ SVOTE_DebugOld(struct rx_call * rxcall,
 
     if (ubik_currentTrans) {
        aparm->currentTrans = 1;
-       if (ubik_currentTrans->type == UBIK_WRITETRANS)
-           aparm->writeTrans = 1;
-       else
-           aparm->writeTrans = 0;
+       aparm->writeTrans = 1;
     } else {
        aparm->currentTrans = 0;
     }