1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci#include "faultlogger_service_ohos.h" 16020a203aSopenharmony_ci 17020a203aSopenharmony_ci#include <functional> 18020a203aSopenharmony_ci#include <string> 19020a203aSopenharmony_ci#include <vector> 20020a203aSopenharmony_ci 21020a203aSopenharmony_ci#include "if_system_ability_manager.h" 22020a203aSopenharmony_ci#include "ipc_skeleton.h" 23020a203aSopenharmony_ci#include "iservice_registry.h" 24020a203aSopenharmony_ci#include "system_ability_definition.h" 25020a203aSopenharmony_ci 26020a203aSopenharmony_ci#include "hiview_logger.h" 27020a203aSopenharmony_ci 28020a203aSopenharmony_ci#include "faultlog_info.h" 29020a203aSopenharmony_ci#include "faultlog_info_ohos.h" 30020a203aSopenharmony_ci#include "faultlog_query_result_inner.h" 31020a203aSopenharmony_ci#include "faultlog_query_result_ohos.h" 32020a203aSopenharmony_ci#include "faultlogger.h" 33020a203aSopenharmony_ci 34020a203aSopenharmony_ciDEFINE_LOG_LABEL(0xD002D11, "FaultloggerServiceOhos"); 35020a203aSopenharmony_cinamespace OHOS { 36020a203aSopenharmony_cinamespace HiviewDFX { 37020a203aSopenharmony_cinamespace { 38020a203aSopenharmony_ciconstexpr int32_t UID_SHELL = 2000; 39020a203aSopenharmony_ciconstexpr int32_t UID_ROOT = 0; 40020a203aSopenharmony_ciconstexpr int32_t UID_HIDUMPER = 1212; 41020a203aSopenharmony_ciconstexpr int32_t UID_HIVIEW = 1201; 42020a203aSopenharmony_ci} 43020a203aSopenharmony_civoid FaultloggerServiceOhos::ClearQueryStub(int32_t uid) 44020a203aSopenharmony_ci{ 45020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 46020a203aSopenharmony_ci queries_.erase(uid); 47020a203aSopenharmony_ci} 48020a203aSopenharmony_ci 49020a203aSopenharmony_ciint32_t FaultloggerServiceOhos::Dump(int32_t fd, const std::vector<std::u16string> &args) 50020a203aSopenharmony_ci{ 51020a203aSopenharmony_ci int32_t uid = IPCSkeleton::GetCallingUid(); 52020a203aSopenharmony_ci if ((uid != UID_SHELL) && (uid != UID_ROOT) && (uid != UID_HIDUMPER)) { 53020a203aSopenharmony_ci dprintf(fd, "No permission for uid:%d.\n", uid); 54020a203aSopenharmony_ci return -1; 55020a203aSopenharmony_ci } 56020a203aSopenharmony_ci 57020a203aSopenharmony_ci std::vector<std::string> cmdList; 58020a203aSopenharmony_ci for (auto arg : args) { 59020a203aSopenharmony_ci for (auto c : arg) { 60020a203aSopenharmony_ci if (!isalnum(c) && c != '-' && c != ' ' && c != '_' && c != '.') { 61020a203aSopenharmony_ci dprintf(fd, "string arg contain invalid char:%c.\n", c); 62020a203aSopenharmony_ci return -1; 63020a203aSopenharmony_ci } 64020a203aSopenharmony_ci } 65020a203aSopenharmony_ci } 66020a203aSopenharmony_ci std::transform(args.begin(), args.end(), std::back_inserter(cmdList), [](const std::u16string &arg) { 67020a203aSopenharmony_ci std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter; 68020a203aSopenharmony_ci return converter.to_bytes(arg); 69020a203aSopenharmony_ci }); 70020a203aSopenharmony_ci 71020a203aSopenharmony_ci auto service = GetOrSetFaultlogger(); 72020a203aSopenharmony_ci if (service == nullptr) { 73020a203aSopenharmony_ci dprintf(fd, "Service is not ready.\n"); 74020a203aSopenharmony_ci return -1; 75020a203aSopenharmony_ci } 76020a203aSopenharmony_ci 77020a203aSopenharmony_ci service->Dump(fd, cmdList); 78020a203aSopenharmony_ci return 0; 79020a203aSopenharmony_ci} 80020a203aSopenharmony_ci 81020a203aSopenharmony_civoid FaultloggerServiceOhos::StartService(OHOS::HiviewDFX::Faultlogger *service) 82020a203aSopenharmony_ci{ 83020a203aSopenharmony_ci GetOrSetFaultlogger(service); 84020a203aSopenharmony_ci sptr<ISystemAbilityManager> serviceManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 85020a203aSopenharmony_ci if (serviceManager == nullptr) { 86020a203aSopenharmony_ci HIVIEW_LOGE("Failed to find samgr, exit."); 87020a203aSopenharmony_ci return; 88020a203aSopenharmony_ci } 89020a203aSopenharmony_ci 90020a203aSopenharmony_ci static sptr<FaultloggerServiceOhos> instance = new FaultloggerServiceOhos(); 91020a203aSopenharmony_ci serviceManager->AddSystemAbility(DFX_FAULT_LOGGER_ABILITY_ID, instance); 92020a203aSopenharmony_ci HIVIEW_LOGI("FaultLogger Service started."); 93020a203aSopenharmony_ci} 94020a203aSopenharmony_ci 95020a203aSopenharmony_ciOHOS::HiviewDFX::Faultlogger *FaultloggerServiceOhos::GetOrSetFaultlogger( 96020a203aSopenharmony_ci OHOS::HiviewDFX::Faultlogger *service) 97020a203aSopenharmony_ci{ 98020a203aSopenharmony_ci static OHOS::HiviewDFX::Faultlogger *ref = nullptr; 99020a203aSopenharmony_ci if (service != nullptr) { 100020a203aSopenharmony_ci ref = service; 101020a203aSopenharmony_ci } 102020a203aSopenharmony_ci return ref; 103020a203aSopenharmony_ci} 104020a203aSopenharmony_ci 105020a203aSopenharmony_civoid FaultloggerServiceOhos::AddFaultLog(const FaultLogInfoOhos& info) 106020a203aSopenharmony_ci{ 107020a203aSopenharmony_ci auto service = GetOrSetFaultlogger(); 108020a203aSopenharmony_ci if (service == nullptr) { 109020a203aSopenharmony_ci return; 110020a203aSopenharmony_ci } 111020a203aSopenharmony_ci 112020a203aSopenharmony_ci int32_t uid = IPCSkeleton::GetCallingUid(); 113020a203aSopenharmony_ci HIVIEW_LOGD("info.uid:%{public}d uid:%{public}d info.pid:%{public}d", info.uid, uid, info.pid); 114020a203aSopenharmony_ci if (((uid != static_cast<int32_t>(getuid()))) && (uid != info.uid)) { 115020a203aSopenharmony_ci HIVIEW_LOGW("Fail to add fault log, mismatch uid:%{public}d(%{public}d)", uid, info.uid); 116020a203aSopenharmony_ci return; 117020a203aSopenharmony_ci } 118020a203aSopenharmony_ci 119020a203aSopenharmony_ci FaultLogInfo outInfo; 120020a203aSopenharmony_ci outInfo.time = info.time; 121020a203aSopenharmony_ci outInfo.id = info.uid; 122020a203aSopenharmony_ci outInfo.pid = info.pid; 123020a203aSopenharmony_ci auto fdDeleter = [] (int32_t *ptr) { 124020a203aSopenharmony_ci if (*ptr > 0) { 125020a203aSopenharmony_ci close(*ptr); 126020a203aSopenharmony_ci } 127020a203aSopenharmony_ci delete ptr; 128020a203aSopenharmony_ci }; 129020a203aSopenharmony_ci outInfo.pipeFd.reset(new int32_t(info.pipeFd), fdDeleter); 130020a203aSopenharmony_ci outInfo.faultLogType = info.faultLogType; 131020a203aSopenharmony_ci outInfo.fd = (info.fd > 0) ? dup(info.fd) : -1; 132020a203aSopenharmony_ci outInfo.module = info.module; 133020a203aSopenharmony_ci outInfo.reason = info.reason; 134020a203aSopenharmony_ci outInfo.summary = info.summary; 135020a203aSopenharmony_ci if (uid == UID_HIVIEW) { 136020a203aSopenharmony_ci outInfo.logPath = info.logPath; 137020a203aSopenharmony_ci } 138020a203aSopenharmony_ci outInfo.registers = info.registers; 139020a203aSopenharmony_ci outInfo.sectionMap = info.sectionMaps; 140020a203aSopenharmony_ci service->AddFaultLog(outInfo); 141020a203aSopenharmony_ci} 142020a203aSopenharmony_ci 143020a203aSopenharmony_cisptr<IRemoteObject> FaultloggerServiceOhos::QuerySelfFaultLog(int32_t faultType, int32_t maxNum) 144020a203aSopenharmony_ci{ 145020a203aSopenharmony_ci auto service = GetOrSetFaultlogger(); 146020a203aSopenharmony_ci if (service == nullptr) { 147020a203aSopenharmony_ci return nullptr; 148020a203aSopenharmony_ci } 149020a203aSopenharmony_ci 150020a203aSopenharmony_ci int32_t uid = IPCSkeleton::GetCallingUid(); 151020a203aSopenharmony_ci int32_t pid = IPCSkeleton::GetCallingPid(); 152020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 153020a203aSopenharmony_ci if ((queries_.find(uid) != queries_.end()) && 154020a203aSopenharmony_ci (queries_[uid]->pid == pid)) { 155020a203aSopenharmony_ci HIVIEW_LOGW("Ongoing query is still alive for uid:%d", uid); 156020a203aSopenharmony_ci return nullptr; 157020a203aSopenharmony_ci } 158020a203aSopenharmony_ci 159020a203aSopenharmony_ci auto queryResult = service->QuerySelfFaultLog(uid, pid, faultType, maxNum); 160020a203aSopenharmony_ci if (queryResult == nullptr) { 161020a203aSopenharmony_ci HIVIEW_LOGW("Fail to query fault log for uid:%d", uid); 162020a203aSopenharmony_ci return nullptr; 163020a203aSopenharmony_ci } 164020a203aSopenharmony_ci 165020a203aSopenharmony_ci sptr<FaultLogQueryResultOhos> resultRef = 166020a203aSopenharmony_ci new FaultLogQueryResultOhos(std::move(queryResult)); 167020a203aSopenharmony_ci auto queryStub = std::make_unique<FaultLogQuery>(); 168020a203aSopenharmony_ci queryStub->pid = pid; 169020a203aSopenharmony_ci queryStub->ptr = resultRef; 170020a203aSopenharmony_ci queries_[uid] = std::move(queryStub); 171020a203aSopenharmony_ci return resultRef->AsObject(); 172020a203aSopenharmony_ci} 173020a203aSopenharmony_ci 174020a203aSopenharmony_civoid FaultloggerServiceOhos::Destroy() 175020a203aSopenharmony_ci{ 176020a203aSopenharmony_ci auto service = GetOrSetFaultlogger(); 177020a203aSopenharmony_ci if (service == nullptr) { 178020a203aSopenharmony_ci return; 179020a203aSopenharmony_ci } 180020a203aSopenharmony_ci 181020a203aSopenharmony_ci int32_t uid = IPCSkeleton::GetCallingUid(); 182020a203aSopenharmony_ci HIVIEW_LOGI("Destroy Query from uid:%d", uid); 183020a203aSopenharmony_ci ClearQueryStub(uid); 184020a203aSopenharmony_ci} 185020a203aSopenharmony_ci} // namespace HiviewDFX 186020a203aSopenharmony_ci} // namespace OHOS