diff options
author | Ytai Ben-tsvi <ytai@google.com> | 2020-03-20 05:54:08 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-03-20 05:54:08 +0000 |
commit | 6c6ea89e914bb60023638cd12fd111b18df9c930 (patch) | |
tree | 398b106e0bee8cdd41cbbeb24d2210c467ff3fe7 | |
parent | 01102840bc362208e1ec2e8d50e10f460af158f1 (diff) | |
parent | 166a84bfe31457fe44dcb90294d33089d2a3f428 (diff) | |
download | frameworks_av-6c6ea89e914bb60023638cd12fd111b18df9c930.tar.gz frameworks_av-6c6ea89e914bb60023638cd12fd111b18df9c930.tar.bz2 frameworks_av-6c6ea89e914bb60023638cd12fd111b18df9c930.zip |
Merge "[DO NOT MERGE] Crash the process when midi extraction times out" into qt-qpr1-dev
-rw-r--r-- | media/extractors/midi/Android.bp | 5 | ||||
-rw-r--r-- | media/extractors/midi/MidiExtractor.cpp | 12 | ||||
-rw-r--r-- | media/libwatchdog/Android.bp | 35 | ||||
-rw-r--r-- | media/libwatchdog/Watchdog.cpp | 63 | ||||
-rw-r--r-- | media/libwatchdog/include/watchdog/Watchdog.h | 49 | ||||
-rw-r--r-- | services/mediaextractor/seccomp_policy/mediaextractor-arm.policy | 3 | ||||
-rw-r--r-- | services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy | 3 | ||||
-rw-r--r-- | services/mediaextractor/seccomp_policy/mediaextractor-x86.policy | 3 | ||||
-rw-r--r-- | services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy | 3 |
9 files changed, 174 insertions, 2 deletions
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp index 7d42e703f3..91ce78eb9d 100644 --- a/media/extractors/midi/Android.bp +++ b/media/extractors/midi/Android.bp @@ -14,7 +14,9 @@ cc_library_shared { static_libs: [ "libmedia_midiiowrapper", "libsonivox", - "libstagefright_foundation" + "libstagefright_foundation", + "libwatchdog", + "libbase", ], name: "libmidiextractor", relative_install_path: "extractors", @@ -35,5 +37,4 @@ cc_library_shared { "signed-integer-overflow", ], }, - } diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp index 9f4f9e69b4..d0efb2f652 100644 --- a/media/extractors/midi/MidiExtractor.cpp +++ b/media/extractors/midi/MidiExtractor.cpp @@ -26,6 +26,7 @@ #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <libsonivox/eas_reverb.h> +#include <watchdog/Watchdog.h> namespace android { @@ -116,6 +117,7 @@ media_status_t MidiSource::read( MediaBufferHelper **outBuffer, const ReadOptions *options) { ALOGV("MidiSource::read"); + MediaBufferHelper *buffer; // process an optional seek request int64_t seekTimeUs; @@ -139,6 +141,8 @@ status_t MidiSource::init() } // MidiEngine +using namespace std::chrono_literals; +static constexpr auto kTimeout = 10s; MidiEngine::MidiEngine(CDataSource *dataSource, AMediaFormat *fileMetadata, @@ -147,6 +151,8 @@ MidiEngine::MidiEngine(CDataSource *dataSource, mEasHandle(NULL), mEasConfig(NULL), mIsInitialized(false) { + Watchdog watchdog(kTimeout); + mIoWrapper = new MidiIoWrapper(dataSource); // spin up a new EAS engine EAS_I32 temp; @@ -186,6 +192,8 @@ MidiEngine::MidiEngine(CDataSource *dataSource, } MidiEngine::~MidiEngine() { + Watchdog watchdog(kTimeout); + if (mEasHandle) { EAS_CloseFile(mEasData, mEasHandle); } @@ -217,12 +225,16 @@ status_t MidiEngine::releaseBuffers() { } status_t MidiEngine::seekTo(int64_t positionUs) { + Watchdog watchdog(kTimeout); + ALOGV("seekTo %lld", (long long)positionUs); EAS_RESULT result = EAS_Locate(mEasData, mEasHandle, positionUs / 1000, false); return result == EAS_SUCCESS ? OK : UNKNOWN_ERROR; } MediaBufferHelper* MidiEngine::readBuffer() { + Watchdog watchdog(kTimeout); + EAS_STATE state; EAS_State(mEasData, mEasHandle, &state); if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) { diff --git a/media/libwatchdog/Android.bp b/media/libwatchdog/Android.bp new file mode 100644 index 0000000000..2bdf17262c --- /dev/null +++ b/media/libwatchdog/Android.bp @@ -0,0 +1,35 @@ +// Copyright 2020 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. + +cc_library { + name: "libwatchdog", + srcs: [ + "Watchdog.cpp", + ], + export_include_dirs: ["include"], + shared_libs: [ + "liblog", + ], + static_libs: [ + "libbase", + ], + target: { + windows: { + enabled: false, + }, + darwin: { + enabled: false, + }, + }, +} diff --git a/media/libwatchdog/Watchdog.cpp b/media/libwatchdog/Watchdog.cpp new file mode 100644 index 0000000000..bb012b9429 --- /dev/null +++ b/media/libwatchdog/Watchdog.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 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. + */ + +#define LOG_TAG "Watchdog" + +#include <watchdog/Watchdog.h> + +#include <android-base/logging.h> +#include <android-base/threads.h> +#include <signal.h> +#include <time.h> +#include <cstring> +#include <utils/Log.h> + +namespace android { + +Watchdog::Watchdog(::std::chrono::steady_clock::duration timeout) { + // Create the timer. + struct sigevent sev; + sev.sigev_notify = SIGEV_THREAD_ID; + sev.sigev_notify_thread_id = base::GetThreadId(); + sev.sigev_signo = SIGABRT; + sev.sigev_value.sival_ptr = &mTimerId; + int err = timer_create(CLOCK_MONOTONIC, &sev, &mTimerId); + if (err != 0) { + PLOG(FATAL) << "Failed to create timer"; + } + + // Start the timer. + struct itimerspec spec; + memset(&spec, 0, sizeof(spec)); + auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout); + LOG_ALWAYS_FATAL_IF(timeout.count() <= 0, "Duration must be positive"); + spec.it_value.tv_sec = ns.count() / 1000000000; + spec.it_value.tv_nsec = ns.count() % 1000000000; + err = timer_settime(mTimerId, 0, &spec, nullptr); + if (err != 0) { + PLOG(FATAL) << "Failed to start timer"; + } +} + +Watchdog::~Watchdog() { + // Delete the timer. + int err = timer_delete(mTimerId); + if (err != 0) { + PLOG(FATAL) << "Failed to delete timer"; + } +} + +} // namespace android diff --git a/media/libwatchdog/include/watchdog/Watchdog.h b/media/libwatchdog/include/watchdog/Watchdog.h new file mode 100644 index 0000000000..2819f8a270 --- /dev/null +++ b/media/libwatchdog/include/watchdog/Watchdog.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 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. + */ + +#ifndef ANDROID_WATCHDOG_H +#define ANDROID_WATCHDOG_H + +#include <chrono> +#include <time.h> + +namespace android { + +/* + * An RAII-style object, which would crash the process if a timeout expires + * before the object is destroyed. + * The calling thread would be sent a SIGABORT, which would typically result in + * a stack trace. + * + * Sample usage: + * { + * Watchdog watchdog(std::chrono::milliseconds(10)); + * DoSomething(); + * } + * // If we got here, the function completed in time. + */ +class Watchdog final { +public: + Watchdog(std::chrono::steady_clock::duration timeout); + ~Watchdog(); + +private: + timer_t mTimerId; +}; + +} // namespace android + +#endif // ANDROID_WATCHDOG_H diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy index 38f9be6c7a..118072ec65 100644 --- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy +++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy @@ -41,6 +41,9 @@ getegid32: 1 getgroups32: 1 nanosleep: 1 getrandom: 1 +timer_create: 1 +timer_settime: 1 +timer_delete: 1 # for dynamically loading extractors pread64: 1 diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy index 8fd8787419..481e29e253 100644 --- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy +++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy @@ -30,6 +30,9 @@ rt_sigreturn: 1 getrlimit: 1 nanosleep: 1 getrandom: 1 +timer_create: 1 +timer_settime: 1 +timer_delete: 1 # for FileSource readlinkat: 1 diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy index 05915d11d9..15fb24e5ea 100644 --- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy +++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy @@ -39,6 +39,9 @@ getegid32: 1 getgroups32: 1 nanosleep: 1 getrandom: 1 +timer_create: 1 +timer_settime: 1 +timer_delete: 1 # for dynamically loading extractors getdents64: 1 diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy index e6a55d0586..4f2646c9cd 100644 --- a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy +++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy @@ -34,6 +34,9 @@ sched_setscheduler: 1 getrlimit: 1 nanosleep: 1 getrandom: 1 +timer_create: 1 +timer_settime: 1 +timer_delete: 1 # for dynamically loading extractors getdents64: 1 |