From 10440d6317438ae755940b9aaf2a0571d14d7aef Mon Sep 17 00:00:00 2001 From: jiangwei Date: Fri, 12 Sep 2025 10:14:20 +0800 Subject: [PATCH] fix: judge kernel thread from uid Signed-off-by: jiangwei --- include/subcommand_record.h | 2 +- include/utilities.h | 3 + src/subcommand_record.cpp | 35 ++++-------- src/utilities.cpp | 57 +++++++++++++++++++ .../common/native/subcommand_record_test.cpp | 8 +-- .../unittest/common/native/utilities_test.cpp | 34 +++++++++++ 6 files changed, 109 insertions(+), 30 deletions(-) diff --git a/include/subcommand_record.h b/include/subcommand_record.h index e10944f..0edb3b0 100644 --- a/include/subcommand_record.h +++ b/include/subcommand_record.h @@ -292,7 +292,7 @@ private: std::vector excludeProcessNameArgs_ = {}; std::set excludePids_ = {}; std::set excludeTids_ = {}; - std::unordered_set sensitiveServicePids_; + std::unordered_set kernelPids_; void CollectExcludeThread(); void SetExcludeHiperf(); diff --git a/include/utilities.h b/include/utilities.h index 3191e28..6fcd4e9 100644 --- a/include/utilities.h +++ b/include/utilities.h @@ -345,6 +345,9 @@ bool StringToUint64(const std::string &str, uint64_t &val); bool IsDirectoryExists(const std::string& fileName); bool CreateDirectory(const std::string& path, const mode_t mode); bool IsValidOutPath(const std::string& path); +bool IsKernelThread(const pid_t& pid); +bool GetUidFromPid(pid_t pid, uid_t& ruid); +bool GetStatusLineId(std::string& line, unsigned long& target); void AgeHiperflogFiles(); const std::string HMKERNEL = "HongMeng"; diff --git a/src/subcommand_record.cpp b/src/subcommand_record.cpp index f242181..237febc 100644 --- a/src/subcommand_record.cpp +++ b/src/subcommand_record.cpp @@ -72,14 +72,6 @@ static constexpr uint64_t CHECK_WAIT_TIME_MS = 200; static constexpr uint32_t MAX_SERVER_OUTPUT_WAIT_COUNT = 600; static std::atomic_bool g_callStop(false); -static std::set SENSITIVE_SERVICE = { - DEVHOST_FILE_NAME, - "hguard.elf", - "crypto.elf", - "auditmgr.elf", - "devmgr.elf" -}; - int GetClockId(const std::string &name) { static std::map mapClockid = { @@ -2223,7 +2215,7 @@ void SubCommandRecord::CollectSymbol(PerfRecordSample *sample) } serverPid = sample->GetServerPidof(i); - if (!isRoot_ && sensitiveServicePids_.find(static_cast(serverPid)) != sensitiveServicePids_.end()) { + if (!isRoot_ && kernelPids_.find(static_cast(serverPid)) != kernelPids_.end()) { // in func UpdateDevHostCallChains add offset_ to ips, need sub offset_ when symboling if (sample->data_.ips[i] > offset_) { sample->data_.ips[i] -= offset_; @@ -2389,23 +2381,16 @@ void SubCommandRecord::SetHM() const std::string basePath {"/proc/"}; std::vector subDirs = GetSubDirs(basePath); for (const auto &subDir : subDirs) { - if (sensitiveServicePids_.size() == SENSITIVE_SERVICE.size()) { - HIPERF_HILOGI(MODULE_DEFAULT, "sensitive service pid collect finish"); - break; - } if (!IsDigits(subDir)) { continue; } pid_t pid = std::stoll(subDir); - std::string cmdline = GetProcessName(pid); - for (const auto& service : SENSITIVE_SERVICE) { - if (cmdline == "/bin/" + service) { - if (service == DEVHOST_FILE_NAME) { - virtualRuntime_.SetDevhostPid(pid); - } - sensitiveServicePids_.insert(pid); - break; + if (IsKernelThread(pid)) { + std::string cmdline = GetProcessName(pid); + if (cmdline == "/bin/" + DEVHOST_FILE_NAME) { + virtualRuntime_.SetDevhostPid(pid); } + kernelPids_.insert(pid); } } } @@ -2530,12 +2515,12 @@ void SubCommandRecord::UpdateDevHostMaps(PerfEventRecord& record) { if (record.GetType() == PERF_RECORD_MMAP) { auto recordMmap = static_cast(&record); - if (sensitiveServicePids_.find(recordMmap->data_.pid) != sensitiveServicePids_.end()) { + if (kernelPids_.find(recordMmap->data_.pid) != kernelPids_.end()) { recordMmap->data_.addr += offset_; } } else if (record.GetType() == PERF_RECORD_MMAP2) { auto recordMmap2 = static_cast(&record); - if (sensitiveServicePids_.find(recordMmap2->data_.pid) != sensitiveServicePids_.end()) { + if (kernelPids_.find(recordMmap2->data_.pid) != kernelPids_.end()) { recordMmap2->data_.addr += offset_; } } @@ -2548,7 +2533,7 @@ void SubCommandRecord::UpdateDevHostCallChains(PerfEventRecord& record) const uint64_t BAD_IP_ADDRESS = 2; auto sample = static_cast(&record); serverPid = static_cast(sample->GetServerPidof(0)); - if (sensitiveServicePids_.find(serverPid) != sensitiveServicePids_.end()) { + if (kernelPids_.find(serverPid) != kernelPids_.end()) { sample->data_.ip += offset_; } for (u64 i = 0; i < sample->data_.nr; i++) { @@ -2556,7 +2541,7 @@ void SubCommandRecord::UpdateDevHostCallChains(PerfEventRecord& record) continue; } serverPid = static_cast(sample->GetServerPidof(i)); - if (sensitiveServicePids_.find(serverPid) != sensitiveServicePids_.end()) { + if (kernelPids_.find(serverPid) != kernelPids_.end()) { sample->data_.ips[i] += offset_; } } diff --git a/src/utilities.cpp b/src/utilities.cpp index 9de04ff..e356e67 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -36,6 +36,10 @@ #include "hiperf_hilog.h" #include "ipc_utilities.h" +#ifndef UID_MAX +#define UID_MAX UINT32_MAX +#endif + using namespace std::chrono; namespace OHOS { namespace Developtools { @@ -45,6 +49,8 @@ static const std::string USER_DOMESTIC_BETA = "beta"; static const std::string USER_TYPE_PARAM = "const.logsystem.versiontype"; static const std::string USER_TYPE_PARAM_GET = ""; static const std::string HIVIEW_CMDLINE = "/system/bin/hiview"; +const std::string UID_TAG = "Uid:"; +const int STATUS_ID_INDEX = 4; std::string CanonicalizeSpecPath(const char* src) { @@ -1134,6 +1140,57 @@ std::string GetDefaultPathByEnv(const std::string fileType) #endif return outputFilename; } + +bool GetStatusLineId(std::string& line, unsigned long& target) +{ + size_t start = line.find_first_of("\t") + 1; + size_t end = line.find_first_of("\t", start); + std::string targetStr = line.substr(start, end - start); + std::istringstream iss(targetStr); + unsigned long result = 0; + iss >> result; + if (iss.fail() || !iss.eof()) { + return false; + } + target = result; + return true; +} + +bool GetUidFromPid(pid_t pid, uid_t& ruid) +{ + std::string line; + std::string procStatusPath = "/proc/" + std::to_string(pid) + "/status"; + std::ifstream fileStream(procStatusPath); + + if (!fileStream.is_open()) { + HIPERF_HILOGE(MODULE_DEFAULT, "GetUidGidFromPid cannot open proc status file for pid: %{public}d", pid); + return false; + } + unsigned long statusId = 0; + while (std::getline(fileStream, line)) { + if (line.substr(0, STATUS_ID_INDEX) == UID_TAG) { + if (!GetStatusLineId(line, statusId)) { + HIPERF_HILOGE(MODULE_DEFAULT, "GetUidGidFromPid get uid failed"); + return false; + } + ruid = static_cast(statusId); + break; + } + } + fileStream.close(); + return true; +} + +bool IsKernelThread(const pid_t& pid) +{ + uid_t ruid = UID_MAX; + if (GetUidFromPid(pid, ruid)) { + if (ruid == 0) { + return true; + } + } + return false; +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/test/unittest/common/native/subcommand_record_test.cpp b/test/unittest/common/native/subcommand_record_test.cpp index 6bc5643..29363da 100644 --- a/test/unittest/common/native/subcommand_record_test.cpp +++ b/test/unittest/common/native/subcommand_record_test.cpp @@ -2540,7 +2540,7 @@ HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps1, TestSize.Level1) PerfRecordMmap recordIn {true, pid, tid, addr, len, pgoff, "testdatammap"}; SubCommandRecord cmd; - cmd.sensitiveServicePids_.insert(pid); + cmd.kernelPids_.insert(pid); cmd.offset_ = cmd.GetOffsetNum(); cmd.UpdateDevHostMaps(recordIn); EXPECT_EQ(recordIn.data_.addr, cmd.offset_ + addr); @@ -2561,7 +2561,7 @@ HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps2, TestSize.Level1) PerfRecordMmap recordIn {true, pid, tid, addr, len, pgoff, "testdatammap"}; SubCommandRecord cmd; - cmd.sensitiveServicePids_.insert(devhostPid); + cmd.kernelPids_.insert(devhostPid); cmd.offset_ = cmd.GetOffsetNum(); cmd.UpdateDevHostMaps(recordIn); EXPECT_EQ(recordIn.data_.addr, addr); @@ -2582,7 +2582,7 @@ HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps3, TestSize.Level1) PerfRecordMmap2 recordIn {true, pid, tid, addr, len, pgoff, testNum, testNum, testNum, testNum, testNum, "testdatammap2"}; SubCommandRecord cmd; - cmd.sensitiveServicePids_.insert(pid); + cmd.kernelPids_.insert(pid); cmd.offset_ = cmd.GetOffsetNum(); cmd.UpdateDevHostMaps(recordIn); EXPECT_EQ(recordIn.data_.addr, cmd.offset_ + addr); @@ -2604,7 +2604,7 @@ HWTEST_F(SubCommandRecordTest, UpdateDevHostMaps4, TestSize.Level1) PerfRecordMmap2 recordIn {true, pid, tid, addr, len, pgoff, testNum, testNum, testNum, testNum, testNum, "testdatammap2"}; SubCommandRecord cmd; - cmd.sensitiveServicePids_.insert(devhostPid); + cmd.kernelPids_.insert(devhostPid); cmd.offset_ = cmd.GetOffsetNum(); cmd.UpdateDevHostMaps(recordIn); EXPECT_EQ(recordIn.data_.addr, addr); diff --git a/test/unittest/common/native/utilities_test.cpp b/test/unittest/common/native/utilities_test.cpp index 613e2d1..362b87b 100644 --- a/test/unittest/common/native/utilities_test.cpp +++ b/test/unittest/common/native/utilities_test.cpp @@ -108,6 +108,25 @@ void UtilitiesTest::ExitThreads() printf("all threads exited\n"); } +pid_t GetPidFromApp(const std::string appPackage) +{ + pid_t res {-1}; + const std::string basePath {"/proc/"}; + const std::string cmdline {"/cmdline"}; + std::vector subDirs = GetSubDirs(basePath); + for (const auto &subDir : subDirs) { + if (!IsDigits(subDir)) { + continue; + } + std::string fileName {basePath + subDir + cmdline}; + if (IsSameCommand(ReadFileToString(fileName), appPackage)) { + res = std::stoul(subDir, nullptr); + return res; + } + } + return res; +} + /** * @tc.name: StringReplace * @tc.desc: @@ -1018,6 +1037,21 @@ HWTEST_F(UtilitiesTest, IsDebugableApp, TestSize.Level1) { EXPECT_FALSE(IsDebugableApp("hiperf_test_demo")); } + +/** + * @tc.name: GetUidFromPid + * @tc.desc: Test GetUidFromPid fun + * @tc.type: FUNC + */ +HWTEST_F(UtilitiesTest, GetUidFromPid, TestSize.Level1) +{ + const std::string hiviewName = "hiview"; + pid_t pid = GetPidFromApp(hiviewName); + EXPECT_NE(pid, -1); + uid_t uid = 0; + EXPECT_TRUE(GetUidFromPid(pid, uid)); + EXPECT_NE(uid, 0); +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS -- Gitee