From 7da548578c25683fe0082283303e16961df312da Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Mon, 1 May 2017 14:16:41 -0700 Subject: [PATCH] init: add an initializer for keychord_id_ Add unit test to ensure all POD types of Service are initialized. Bug: 37855222 Test: Ensure bugreport is triggered via keychord properly. Test: New unit tests Change-Id: If2cfea15a74ab417a7b909a60c264cb8eb990de7 --- init/Android.mk | 1 + init/service.cpp | 2 ++ init/service.h | 12 ++++++-- init/service_test.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 init/service_test.cpp diff --git a/init/Android.mk b/init/Android.mk index de3d0760b..537bbee35 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -145,6 +145,7 @@ LOCAL_SRC_FILES := \ init_parser_test.cpp \ init_test.cpp \ property_service_test.cpp \ + service_test.cpp \ util_test.cpp \ LOCAL_SHARED_LIBRARIES += \ diff --git a/init/service.cpp b/init/service.cpp index 39f67090f..3a9f62228 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -158,6 +158,7 @@ Service::Service(const std::string& name, const std::vector& args) namespace_flags_(0), seclabel_(""), onrestart_(false, "", 0), + keychord_id_(0), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), priority_(0), @@ -182,6 +183,7 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, namespace_flags_(namespace_flags), seclabel_(seclabel), onrestart_(false, "", 0), + keychord_id_(0), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), priority_(0), diff --git a/init/service.h b/init/service.h index 634fe4e63..426577ffe 100644 --- a/init/service.h +++ b/init/service.h @@ -94,14 +94,19 @@ class Service { const std::set& classnames() const { return classnames_; } unsigned flags() const { return flags_; } pid_t pid() const { return pid_; } + int crash_count() const { return crash_count_; } uid_t uid() const { return uid_; } gid_t gid() const { return gid_; } - int priority() const { return priority_; } + unsigned namespace_flags() const { return namespace_flags_; } const std::vector& supp_gids() const { return supp_gids_; } const std::string& seclabel() const { return seclabel_; } const std::vector& keycodes() const { return keycodes_; } int keychord_id() const { return keychord_id_; } void set_keychord_id(int keychord_id) { keychord_id_ = keychord_id; } + IoSchedClass ioprio_class() const { return ioprio_class_; } + int ioprio_pri() const { return ioprio_pri_; } + int priority() const { return priority_; } + int oom_score_adjust() const { return oom_score_adjust_; } const std::vector& args() const { return args_; } private: @@ -181,6 +186,9 @@ class ServiceManager { public: static ServiceManager& GetInstance(); + // Exposed for testing + ServiceManager(); + void AddService(std::unique_ptr service); Service* MakeExecOneshotService(const std::vector& args); bool Exec(const std::vector& args); @@ -199,8 +207,6 @@ public: void DumpState() const; private: - ServiceManager(); - // Cleans up a child process that exited. // Returns true iff a children was cleaned up. bool ReapOneProcess(); diff --git a/init/service_test.cpp b/init/service_test.cpp new file mode 100644 index 000000000..4493f254a --- /dev/null +++ b/init/service_test.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 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 "service.h" + +#include +#include +#include +#include + +#include + +TEST(service, pod_initialized) { + constexpr auto memory_size = sizeof(Service); + alignas(alignof(Service)) char old_memory[memory_size]; + + for (std::size_t i = 0; i < memory_size; ++i) { + old_memory[i] = 0xFF; + } + + std::vector dummy_args{"/bin/test"}; + Service* service_in_old_memory = new (old_memory) Service("test_old_memory", dummy_args); + + EXPECT_EQ(0U, service_in_old_memory->flags()); + EXPECT_EQ(0, service_in_old_memory->pid()); + EXPECT_EQ(0, service_in_old_memory->crash_count()); + EXPECT_EQ(0U, service_in_old_memory->uid()); + EXPECT_EQ(0U, service_in_old_memory->gid()); + EXPECT_EQ(0U, service_in_old_memory->namespace_flags()); + EXPECT_EQ(0, service_in_old_memory->keychord_id()); + EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory->ioprio_class()); + EXPECT_EQ(0, service_in_old_memory->ioprio_pri()); + EXPECT_EQ(0, service_in_old_memory->priority()); + EXPECT_EQ(-1000, service_in_old_memory->oom_score_adjust()); + + for (std::size_t i = 0; i < memory_size; ++i) { + old_memory[i] = 0xFF; + } + + Service* service_in_old_memory2 = new (old_memory) + Service("test_old_memory", 0U, 0U, 0U, std::vector(), CapSet(), 0U, "", dummy_args); + + EXPECT_EQ(0U, service_in_old_memory2->flags()); + EXPECT_EQ(0, service_in_old_memory2->pid()); + EXPECT_EQ(0, service_in_old_memory2->crash_count()); + EXPECT_EQ(0U, service_in_old_memory2->uid()); + EXPECT_EQ(0U, service_in_old_memory2->gid()); + EXPECT_EQ(0U, service_in_old_memory2->namespace_flags()); + EXPECT_EQ(0, service_in_old_memory2->keychord_id()); + EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory2->ioprio_class()); + EXPECT_EQ(0, service_in_old_memory2->ioprio_pri()); + EXPECT_EQ(0, service_in_old_memory2->priority()); + EXPECT_EQ(-1000, service_in_old_memory2->oom_score_adjust()); +}