diff options
author | Yurii Zubrytskyi <zyy@google.com> | 2021-03-11 21:38:58 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-03-11 21:38:58 +0000 |
commit | eb86831188d7587c017b849419bd66638a8f12bf (patch) | |
tree | 5bc8dd98c2543c15ca5490026615a59e30e9105e | |
parent | e2a5df97992cfa277823e360179bab9fcacd2464 (diff) | |
parent | 817c41a2264dd16c9614cebcc262e66cdf313a6a (diff) | |
download | incremental_delivery-eb86831188d7587c017b849419bd66638a8f12bf.tar.gz |
Merge "[incfs] Move the libhardening code into libziparchive" into sc-dev
-rw-r--r-- | incfs/Android.bp | 15 | ||||
-rw-r--r-- | incfs/tests/hardening_benchmark.cpp (renamed from libhardening/hardening_benchmark.cpp) | 24 | ||||
-rw-r--r-- | libhardening/Android.bp | 94 | ||||
-rw-r--r-- | libhardening/include/hardening/access.h | 48 | ||||
-rw-r--r-- | libhardening/include/hardening/signal_handling.h | 101 | ||||
-rw-r--r-- | libhardening/signal_handling.cpp | 87 |
6 files changed, 27 insertions, 342 deletions
diff --git a/incfs/Android.bp b/incfs/Android.bp index cb4cb1e..88b3abb 100644 --- a/incfs/Android.bp +++ b/incfs/Android.bp @@ -163,6 +163,21 @@ cc_test { require_root: true, } +cc_benchmark { + name: "hardening-benchmark", + defaults: ["libincfs_defaults"], + + srcs: [ + "tests/hardening_benchmark.cpp", + ], + static_libs: [ + "libziparchive_for_incfs", + "libutils", + "libincfs", + "libincfs-utils", + ], +} + cc_binary { name: "incfsdump", defaults: ["libincfs_defaults"], diff --git a/libhardening/hardening_benchmark.cpp b/incfs/tests/hardening_benchmark.cpp index 50f95bd..298198b 100644 --- a/libhardening/hardening_benchmark.cpp +++ b/incfs/tests/hardening_benchmark.cpp @@ -19,8 +19,8 @@ #include <benchmark/benchmark.h> #include <unistd.h> -#include "hardening/access.h" -#include "hardening/signal_handling.h" +#include "incfs_support/access.h" +#include "incfs_support/signal_handling.h" #include "util/map_ptr.h" static std::unique_ptr<TemporaryFile> makeFile() { @@ -53,7 +53,7 @@ static void TestSignal(benchmark::State& state) { int val; for (auto _ : state) { - HANDLE_SIGBUS({ break; }); + SCOPED_SIGBUS_HANDLER({ break; }); val += *mapping->data(); } } @@ -100,7 +100,7 @@ static void TestAccess(benchmark::State& state) { auto mapping = android::base::MappedFile::FromFd(tmp->fd, 0, 1, PROT_READ); int val = 0; for (auto _ : state) { - hardening::access(mapping->data(), [&](auto ptr) { val += *ptr; }); + incfs::access(mapping->data(), [&](auto ptr) { val += *ptr; }); } } BENCHMARK(TestAccess); @@ -109,7 +109,7 @@ static void TestAccessFast(benchmark::State& state) { auto tmp = makeFile(); auto mapping = android::base::MappedFile::FromFd(tmp->fd, 0, 1, PROT_READ); int val = 0; - hardening::access(mapping->data(), [&](auto ptr) { + incfs::access(mapping->data(), [&](auto ptr) { for (auto _ : state) { val += *ptr; } @@ -122,7 +122,7 @@ static void TestAccessVal(benchmark::State& state) { auto mapping = android::base::MappedFile::FromFd(tmp->fd, 0, 1, PROT_READ); int val = 0; for (auto _ : state) { - hardening::access(mapping->data(), [&](auto ptr) { return val += *ptr; }); + incfs::access(mapping->data(), [&](auto ptr) { return val += *ptr; }); } } BENCHMARK(TestAccessVal); @@ -131,9 +131,9 @@ static void TestAccessNested(benchmark::State& state) { auto tmp = makeFile(); auto mapping = android::base::MappedFile::FromFd(tmp->fd, 0, 1, PROT_READ); int val = 0; - hardening::access(nullptr, [&](auto) { + incfs::access(nullptr, [&](auto) { for (auto _ : state) { - hardening::access(mapping->data(), [&](auto ptr) { val += *ptr; }); + incfs::access(mapping->data(), [&](auto ptr) { val += *ptr; }); } }); } @@ -143,10 +143,10 @@ static void TestAccessDoubleNested(benchmark::State& state) { auto tmp = makeFile(); auto mapping = android::base::MappedFile::FromFd(tmp->fd, 0, 1, PROT_READ); int val = 0; - hardening::access(nullptr, [&](auto) { - hardening::access(nullptr, [&](auto) { + incfs::access(nullptr, [&](auto) { + incfs::access(nullptr, [&](auto) { for (auto _ : state) { - hardening::access(mapping->data(), [&](auto ptr) { val += *ptr; }); + incfs::access(mapping->data(), [&](auto ptr) { val += *ptr; }); } }); }); @@ -157,7 +157,7 @@ static void TestAccessError(benchmark::State& state) { auto [tmp, mapping] = makeEmptyFileMapping(); int val = 0; for (auto _ : state) { - hardening::access(mapping->data(), [&](auto ptr) { val += *ptr; }); + incfs::access(mapping->data(), [&](auto ptr) { val += *ptr; }); } } BENCHMARK(TestAccessError); diff --git a/libhardening/Android.bp b/libhardening/Android.bp deleted file mode 100644 index 3375c00..0000000 --- a/libhardening/Android.bp +++ /dev/null @@ -1,94 +0,0 @@ -// 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. - -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -cc_defaults { - name: "libhardening_defaults", - cpp_std: "c++2a", - cflags: ["-Werror", "-Wall", "-Wextra", "-Wno-unused-parameter"], - export_include_dirs: ["include/"], - local_include_dirs: ["include/"], - shared_libs: [ - "libbase", - "liblog", - ], - tidy: true, - tidy_checks: [ - "android-*", - "cert-*", - "clang-analyzer-security*", - "-cert-err34-c", - "clang-analyzer-security*", - // Disabling due to many unavoidable warnings from POSIX API usage. - "-google-runtime-int", - "-google-explicit-constructor", - // do not define variadic C function - JNI headers - "-cert-dcl50-cpp", - // operator=() does not handle self-assignment properly - all protobuf-generated classes - "-cert-oop54-cpp", - // do not call 'longjmp'; consider using exception handling instead - library relies on it - "-cert-err52-cpp", - ], -} - -cc_library_static { - name: "libhardening", - defaults: ["libhardening_defaults"], - host_supported: true, - vendor_available: true, - product_available: true, - recovery_available: true, - vendor_ramdisk_available: true, - native_bridge_supported: true, - vndk: { - enabled: true, - }, - srcs: [ - "signal_handling.cpp", - ], - export_include_dirs: ["include"], - local_include_dirs: ["include/hardening"], - - target: { - windows: { - enabled: true, - }, - linux_bionic: { - enabled: true, - }, - }, - - apex_available: [ - "//apex_available:platform", - "//apex_available:anyapex", - ], -} - -cc_benchmark { - name: "hardening-benchmark", - defaults: ["libhardening_defaults"], - - srcs: [ - "hardening_benchmark.cpp", - ], - static_libs: [ - "libhardening", - "libincfs-utils", - "libutils", - "libincfs", - ], -} diff --git a/libhardening/include/hardening/access.h b/libhardening/include/hardening/access.h deleted file mode 100644 index 63d48fa..0000000 --- a/libhardening/include/hardening/access.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ - -#pragma once - -#include <hardening/signal_handling.h> - -#include <optional> -#include <type_traits> - -namespace hardening { - -template <class Arg, class Func> -using func_result = std::remove_cvref_t<decltype(std::declval<Func>()(std::declval<Arg>()))>; - -template <class Arg, class Func> -constexpr auto is_void_func = std::is_same_v<func_result<Arg, Func>, void>; - -template <class Arg, class Func> -using optional_result = - std::conditional_t<is_void_func<Arg, Func>, bool, std::optional<func_result<Arg, Func>>>; - -template <class Ptr, class F> -auto access(Ptr ptr, F&& accessor) -> optional_result<Ptr, F> { - HANDLE_SIGBUS({ return {}; }); - - if constexpr (is_void_func<Ptr, F>) { - accessor(ptr); - return true; - } else { - return accessor(ptr); - } -} - -} // namespace hardening
\ No newline at end of file diff --git a/libhardening/include/hardening/signal_handling.h b/libhardening/include/hardening/signal_handling.h deleted file mode 100644 index 5d8c364..0000000 --- a/libhardening/include/hardening/signal_handling.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - */ -#pragma once - -#include <sys/types.h> - -#if !defined(__BIONIC__) - -// IncFS signal handling isn't needed anywhere but on Android as of now -#define HANDLE_SIGBUS(code) - -#else - -#ifndef LOG_TAG -#define LOG_TAG "hardening" -#endif - -#include <log/log.h> -#include <setjmp.h> -#include <signal.h> -#include <string.h> - -namespace hardening { - -struct JmpBufState final { - jmp_buf buf; - bool armed = false; - - JmpBufState() = default; - JmpBufState(const JmpBufState& other) { - if (other.armed) { - memcpy(&buf, &other.buf, sizeof(buf)); - armed = true; - } - } - - JmpBufState& operator=(const JmpBufState& other) { - if (other.armed) { - memcpy(&buf, &other.buf, sizeof(buf)); - armed = true; - } else { - armed = false; - } - return *this; - } -}; - -class ScopedBuf final { -public: - ScopedBuf(const JmpBufState& prev) : mPrev(prev) {} - ~ScopedBuf(); - - ScopedBuf(const ScopedBuf&) = delete; - -private: - const JmpBufState& mPrev; -}; - -#define HANDLE_SIGBUS(code) \ - hardening::SignalHandler::instance(); \ - auto& tlsBuf = hardening::SignalHandler::mJmpBuf; \ - hardening::JmpBufState oldBuf_macro = tlsBuf; \ - if (setjmp(tlsBuf.buf) != 0) { \ - ALOGI("%s: handling SIGBUS at line %d", __func__, __LINE__); \ - tlsBuf = oldBuf_macro; \ - { code; } \ - LOG_ALWAYS_FATAL("%s(): signal handler was supposed to return", __func__); \ - } \ - tlsBuf.armed = true; \ - hardening::ScopedBuf oldBufRestore_macro(oldBuf_macro); - -class SignalHandler final { -public: - static SignalHandler& instance(); - -private: - SignalHandler(); - inline static struct sigaction mOldSigaction = {}; - - static void handler(int sig, siginfo_t* info, void* ucontext); - -public: - inline static thread_local JmpBufState mJmpBuf = {}; -}; - -} // namespace hardening - -#endif diff --git a/libhardening/signal_handling.cpp b/libhardening/signal_handling.cpp deleted file mode 100644 index d9c5419..0000000 --- a/libhardening/signal_handling.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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. - */ - -#include "signal_handling.h" - -#if defined(__BIONIC__) - -#include <errno.h> - -namespace hardening { - -static void enableSignal(int code) { - sigset_t allowed; - sigemptyset(&allowed); - sigaddset(&allowed, code); - pthread_sigmask(SIG_UNBLOCK, &allowed, nullptr); -} - -ScopedBuf::~ScopedBuf() { - SignalHandler::mJmpBuf = mPrev; -} - -SignalHandler &SignalHandler::instance() { - static SignalHandler self; - return self; -} - -SignalHandler::SignalHandler() { - // ensure SIGBUS is unblocked, so the process won't get insta-killed - enableSignal(SIGBUS); - - const struct sigaction action = { - .sa_sigaction = &handler, - .sa_flags = SA_SIGINFO, - }; - if (sigaction(SIGBUS, &action, &mOldSigaction)) { - ALOGE("sigaction(SIGBUS) failed: %d", errno); - } -} - -void SignalHandler::handler(int sig, siginfo_t *info, void *ucontext) { - if (sig != SIGBUS) { - // ??? - return; - } - - if (!mJmpBuf.armed) { - // No error handler installed - run the previous one - if (mOldSigaction.sa_handler == SIG_DFL) { - // reset the action to default and re-raise the signal. It will kill the process - signal(sig, SIG_DFL); - raise(sig); - return; - } - if (mOldSigaction.sa_handler == SIG_IGN) { - // ignoring SIGBUS won't help us much, as we'll get back right here after retrying. - return; - } - if (mOldSigaction.sa_flags & SA_SIGINFO) { - mOldSigaction.sa_sigaction(sig, info, ucontext); - } else { - mOldSigaction.sa_handler(sig); - } - } - - // restore SIGBUS as signal handling blocks it before running the callback - enableSignal(SIGBUS); - - longjmp(mJmpBuf.buf, 1); -} - -} // namespace hardening - -#endif |