[fuzz] Make sure that we teardown for fuzzer injected errors. - In https://dawn-review.git.corp.google.com/c/dawn/+/302578 I was a bit aggressive at removing some of the handling for the fuzzers. This change reverts it a bit to ensure that if the error injector is enabled, that a DeviceLost error still forces the Vulkan backend to teardown. This addresses the potential UAF found in the fuzzer bug below. - Note that the bug shouldn't be reproducible in the wild. Bug: 503873145 Change-Id: Id53f9040078a2aea82e9621c6e7a8e7ead322097 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/309569 Auto-Submit: Loko Kung <lokokung@google.com> Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp index a154bc0..9d38791 100644 --- a/src/dawn/native/Device.cpp +++ b/src/dawn/native/Device.cpp
@@ -668,24 +668,24 @@ AppendDeviceLostMessage(error.get()); } - InternalErrorType allowedErrors = - InternalErrorType::Validation | InternalErrorType::DeviceLost | additionalAllowedErrors; - - if (type == InternalErrorType::DeviceLost) { + // If ErrorInjectorEnabled() then this may be an injected DeviceLost, not a real one. + bool deviceDefinitelyStopped = type == InternalErrorType::DeviceLost && !ErrorInjectorEnabled(); + if (deviceDefinitelyStopped) { + // If the device was lost naturally, the backend device has already stopped. mState = State::Disconnected; - } else if (!(allowedErrors & type)) { + } + + InternalErrorType allowedErrors = InternalErrorType::Validation | additionalAllowedErrors; + if (!(allowedErrors & type)) { // If we receive an error which we did not explicitly allow, assume the backend can't // recover and lose the device now. Cleanup for the device will be deferred until the last // external reference of the device is dropped, or an explicit call to Destroy. error->AppendContext("handling unexpected error type %s when allowed errors are %s.", type, allowedErrors); - // Transition to a non-alive state if we are currently alive so that the application can no - // longer use the device. + // Handle the remainder of this error as if it caused a device lost. State prev = State::Alive; mState.compare_exchange_strong(prev, State::BeingDisconnected, std::memory_order::acq_rel); - - // Handle the remainder of this error as if it caused a device lost. type = InternalErrorType::DeviceLost; }