/* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "../includes/common.h" #include "../includes/memutils.h" using namespace android; char enable_selective_overload = ENABLE_NONE; int main(int argc, char* argv[]) { FAIL_CHECK(argc == 2); int32_t controlFd; const char* descriptorFilePath = argv[1]; controlFd = open(descriptorFilePath, O_RDWR | O_NONBLOCK | O_CLOEXEC); FAIL_CHECK(controlFd >= 0); struct mtp_event event; event.data = const_cast(""); event.length = 0; { // Memory for handle is being allocated here enable_selective_overload = ENABLE_ALL; std::unique_ptr handle(new MtpFfsCompatHandle(controlFd)); enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK; // handle->sendEvent() internally calls handle->doSendEvent() in a detached thread. // This will cause an use-after-free if handle goes out of scope before the thread completes // its execution. The fix adds a wait in handle->close() to wait till the detached thread is // fully executed. handle->sendEvent(event); handle->close(); } // Sleep is added here to make sure program does not exit before use after free occurs in // detached thread. // It is observed that 200 ms is required for UAF to get triggered. But to detect the // vulnerability in other slow devices, sleep of 1 second (1000 ms) is used here sleep(1); return EXIT_SUCCESS; }