【分布式账号】订阅UAF问题修复

Signed-off-by: swg3156201044 <shiweigang2@huawei.com>
This commit is contained in:
swg3156201044 2024-10-30 12:31:32 +00:00
parent 92973e0be6
commit 215279cab6
4 changed files with 144 additions and 9 deletions

View File

@ -18,6 +18,7 @@
#include <map>
#include <set>
#include "idistributed_account_event.h"
#include "idistributed_account_subscribe.h"
#include "singleton.h"
@ -37,7 +38,7 @@ private:
DistributedAccountSubscribeManager();
~DistributedAccountSubscribeManager() = default;
DISALLOW_COPY_AND_MOVE(DistributedAccountSubscribeManager);
bool OnAccountsChanged(const DistributedSubscribeRecordPtr &distributedSubscribeRecordPtr,
bool OnAccountsChanged(const sptr<IDistributedAccountEvent> &eventProxy,
const int id, DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE subscribeType);
private:

View File

@ -16,7 +16,6 @@
#include <pthread.h>
#include <thread>
#include "account_log_wrapper.h"
#include "idistributed_account_event.h"
#include "distributed_account_subscribe_death_recipient.h"
#include "distributed_account_subscribe_manager.h"
@ -115,12 +114,9 @@ ErrCode DistributedAccountSubscribeManager::UnsubscribeDistributedAccountEvent(
}
bool DistributedAccountSubscribeManager::OnAccountsChanged(
const DistributedSubscribeRecordPtr &distributedSubscribeRecordPtr, const int id,
DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE subscribeType)
const sptr<IDistributedAccountEvent> &eventProxy, const int id, DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE subscribeType)
{
auto distributedAccountEventProxy = iface_cast<IDistributedAccountEvent>(
distributedSubscribeRecordPtr->eventListener_);
if (distributedAccountEventProxy == nullptr) {
if (eventProxy == nullptr) {
ACCOUNT_LOGE("Get app account event proxy failed.");
return false;
}
@ -128,7 +124,7 @@ bool DistributedAccountSubscribeManager::OnAccountsChanged(
eventData.id_ = id;
eventData.type_ = subscribeType;
distributedAccountEventProxy->OnAccountsChanged(eventData);
eventProxy->OnAccountsChanged(eventData);
return true;
}
@ -138,7 +134,14 @@ ErrCode DistributedAccountSubscribeManager::Publish(const int id, DISTRIBUTED_AC
uint32_t sendCnt = 0;
for (auto it = subscribeRecords_.begin(); it != subscribeRecords_.end(); ++it) {
if ((*it)->types_.find(subscribeType) != (*it)->types_.end()) {
auto task = [this, it, id, subscribeType] { this->OnAccountsChanged((*it), id, subscribeType); };
auto eventProxy = iface_cast<IDistributedAccountEvent>((*it)->eventListener_);
if (eventProxy == nullptr) {
ACCOUNT_LOGE("Get eventProxy failed");
break;
}
auto task = [this, eventProxy, id, subscribeType] {
this->OnAccountsChanged(eventProxy, id, subscribeType);
};
std::thread taskThread(task);
pthread_setname_np(taskThread.native_handle(), THREAD_DISTRIBUTED_ACCOUNT_EVENT);
taskThread.detach();

View File

@ -155,11 +155,54 @@ ohos_unittest("OhosDataDealTest") {
part_name = "os_account"
}
ohos_unittest("OhosEventManagerMultipleThreadTest") {
branch_protector_ret = "pac_ret"
sanitize = {
cfi = true
cfi_cross_dso = true
debug = false
}
module_out_path = module_output_path
cflags_cc = []
include_dirs = [
"${services_path}/accountmgr/include",
"${os_account_dfx_path}/hidumper_adapter",
]
sources = [
"${services_path}/accountmgr/src/distributed_account_subscribe_death_recipient.cpp",
"${services_path}/accountmgr/src/distributed_account_subscribe_manager.cpp",
"ohos_account_event_manager_multiple_thread_test.cpp",
]
configs = [ "${services_path}/accountmgr/test:accountmgr_test_config" ]
deps = [
"${common_path}:libaccount_common",
"${innerkits_native_path}:libaccountkits",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
]
external_deps = [
"ability_base:base",
"ability_base:want",
"c_utils:utils",
"hilog:libhilog",
"ipc:ipc_single",
]
part_name = "os_account"
}
group("unittest") {
testonly = true
deps = [
":OhosDataDealTest",
":OhosEventManagerMultipleThreadTest",
":OhosServiceTest",
]
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 <gtest/gtest.h>
#include <gtest/hwext/gtest-multithread.h>
#include <string>
#include "account_log_wrapper.h"
#include "distributed_account_event_service.h"
#include "distributed_account_subscribe_manager.h"
namespace OHOS {
namespace AccountSA {
using namespace testing;
using namespace testing::mt;
using namespace testing::ext;
namespace {
constexpr int32_t TEST_COUNT = 100;
constexpr int32_t TEST_ID = 100;
constexpr DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE TEST_TYPE = DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE::LOGIN;
const char THREAD_OHOS_ACCOUNT_EVENT_TEST[] = "TestOhosAccountEvent";
IDistributedAccountSubscribe &mgr = DistributedAccountSubscribeManager::GetInstance();
} // namespace
class OhosAccountEventManagerTest : public testing::Test {
public:
static void SetUpTestCase(void) {}
static void TearDownTestCase(void) {}
void SetUp();
void TearDown() {}
};
void OhosAccountEventManagerTest::SetUp(void) __attribute__((no_sanitize("cfi")))
{
testing::UnitTest *test = testing::UnitTest::GetInstance();
ASSERT_NE(test, nullptr);
const testing::TestInfo *testinfo = test->current_test_info();
ASSERT_NE(testinfo, nullptr);
string testCaseName = string(testinfo->name());
ACCOUNT_LOGI("[SetUp] %{public}s start", testCaseName.c_str());
}
void TestPulishOhosAccountEvent()
{
for (int32_t i = 0; i < TEST_COUNT; i++) {
mgr.Publish(TEST_ID, TEST_TYPE);
}
}
void TestSubscribeOhosAccountEvent()
{
sptr<IRemoteObject> callbacks[TEST_COUNT];
for (int32_t i = 0; i < TEST_COUNT; i++) {
callbacks[i] = new (std::nothrow) DistributedAccountEventService(TEST_TYPE, nullptr);
mgr.SubscribeDistributedAccountEvent(TEST_TYPE, callbacks[i]);
}
auto task = [] { TestPulishOhosAccountEvent(); };
std::thread taskThread(task);
pthread_setname_np(taskThread.native_handle(), THREAD_OHOS_ACCOUNT_EVENT_TEST);
taskThread.detach();
for (int32_t i = 0; i < TEST_COUNT; i++) {
mgr.UnsubscribeDistributedAccountEvent(callbacks[i]);
}
}
/**
* @tc.name: OsAccountEventManagerTestTest001
* @tc.desc: Test multiple thread event manager
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(OhosAccountEventManagerTest, OhosAccountEventManagerMulTest001, TestSize.Level1)
{
TestSubscribeOhosAccountEvent();
}
} // namespace AccountSA
} // namespace OHOS