oeAware-manager/0003-fix-failed-to-connect-to-the-sdk-and-command-executi.patch
fly_1997 8c2082720c fix data free, plugin display, command plugin bugs
(cherry picked from commit 2ca264904491e249e48381aa6f19969427484d0a)
2024-12-06 15:53:22 +08:00

413 lines
12 KiB
Diff

From 51355e66be3eeec6ebe79faa88324c788e5a3829 Mon Sep 17 00:00:00 2001
From: fly_1997 <flylove7@outlook.com>
Date: Wed, 27 Nov 2024 05:13:26 +0800
Subject: [PATCH 3/5] fix failed to connect to the sdk and command execution is
stuck
---
src/common/utils.cpp | 16 ++++
src/common/utils.h | 1 +
.../collect/system/command/command_base.cpp | 48 +++++++++++-
.../collect/system/command/command_base.h | 9 +++
.../system/command/command_collector.cpp | 9 ++-
src/plugin/collect/system/kernel_config.cpp | 1 +
src/plugin_mgr/config.cpp | 17 -----
src/plugin_mgr/config.h | 1 -
src/plugin_mgr/message_manager.cpp | 76 +++++++++++++++++--
src/plugin_mgr/message_manager.h | 3 +-
src/sdk/oe_client.cpp | 12 ++-
11 files changed, 160 insertions(+), 33 deletions(-)
diff --git a/src/common/utils.cpp b/src/common/utils.cpp
index 4e12a57..a300a6a 100644
--- a/src/common/utils.cpp
+++ b/src/common/utils.cpp
@@ -156,4 +156,20 @@ std::vector<std::string> SplitString(const std::string &str, const std::string &
}
return tokens;
}
+bool CreateDir(const std::string &path)
+{
+ size_t pos = 0;
+ do {
+ pos = path.find_first_of("/", pos + 1);
+ std::string subPath = path.substr(0, pos);
+ struct stat buffer;
+ if (stat(subPath.c_str(), &buffer) == 0) {
+ continue;
+ }
+ if (mkdir(subPath.c_str(), S_IRWXU | S_IRWXG) != 0) {
+ return false;
+ }
+ } while (pos != std::string::npos);
+ return true;
+}
}
diff --git a/src/common/utils.h b/src/common/utils.h
index ba787fe..48b72bd 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -28,6 +28,7 @@ bool EndWith(const std::string &s, const std::string &ending);
std::string Concat(const std::vector<std::string>& strings, const std::string &split);
// Separate "str" with the separator "split"
std::vector<std::string> SplitString(const std::string &str, const std::string &split);
+bool CreateDir(const std::string &path);
}
#endif // !COMMON_UTILS_H
\ No newline at end of file
diff --git a/src/plugin/collect/system/command/command_base.cpp b/src/plugin/collect/system/command/command_base.cpp
index d5a30dd..bf658b8 100644
--- a/src/plugin/collect/system/command/command_base.cpp
+++ b/src/plugin/collect/system/command/command_base.cpp
@@ -10,6 +10,45 @@
* See the Mulan PSL v2 for more details.
******************************************************************************/
#include "command_base.h"
+#include <unistd.h>
+#include <sys/wait.h>
+
+int PopenProcess::Pclose()
+{
+ if (fclose(stream) == EOF) {
+ return -1;
+ }
+ stream = nullptr;
+ if (kill(pid, SIGTERM) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+void PopenProcess::Popen(const std::string &cmd)
+{
+ int pipeFd[2];
+ if (pipe(pipeFd) == -1) {
+ return;
+ }
+ pid = fork();
+ if (pid == -1) {
+ close(pipeFd[0]);
+ close(pipeFd[1]);
+ } else if (pid == 0) {
+ close(pipeFd[0]);
+ dup2(pipeFd[1], STDOUT_FILENO);
+ close(pipeFd[1]);
+ execl("/bin/bash", "bash", "-c", cmd.data(), nullptr);
+ _exit(1);
+ }
+ close(pipeFd[1]);
+ stream = fdopen(pipeFd[0], "r");
+ if (!stream) {
+ close(pipeFd[0]);
+ return;
+ }
+}
CommandBase::CommandBase()
{
@@ -23,18 +62,19 @@ CommandBase::CommandBase()
bool CommandBase::ValidateArgs(const oeaware::Topic& topic)
{
auto cmd = GetCommand(topic);
- FILE *pipe = popen(cmd.c_str(), "r");
- if (!pipe) {
+ PopenProcess p;
+ p.Popen(cmd);
+ if (!p.stream) {
return false;
}
char buffer[128];
bool isValid = false;
- if (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
+ if (fgets(buffer, sizeof(buffer), p.stream) != nullptr) {
if (strstr(buffer, "Linux") != nullptr || strstr(buffer, "procs") != nullptr) {
isValid = true;
}
}
- pclose(pipe);
+ p.Pclose();
return isValid;
}
diff --git a/src/plugin/collect/system/command/command_base.h b/src/plugin/collect/system/command/command_base.h
index eb75c49..a6d7627 100644
--- a/src/plugin/collect/system/command/command_base.h
+++ b/src/plugin/collect/system/command/command_base.h
@@ -44,4 +44,13 @@ public:
void Close();
};
+class PopenProcess {
+public:
+ int Pclose();
+ void Popen(const std::string &cmd);
+
+ FILE *stream;
+ pid_t pid;
+};
+
#endif
diff --git a/src/plugin/collect/system/command/command_collector.cpp b/src/plugin/collect/system/command/command_collector.cpp
index 6c54555..640a406 100644
--- a/src/plugin/collect/system/command/command_collector.cpp
+++ b/src/plugin/collect/system/command/command_collector.cpp
@@ -32,15 +32,16 @@ CommandCollector::CommandCollector(): oeaware::Interface()
void CommandCollector::CollectThread(const oeaware::Topic &topic, CommandBase* collector)
{
std::string cmd = collector->GetCommand(topic);
- FILE* pipe = popen(cmd.c_str(), "r");
- if (!pipe) {
+ PopenProcess p;
+ p.Popen(cmd);
+ if (!p.stream) {
return;
}
char buffer[256];
- while (collector->isRunning && fgets(buffer, sizeof(buffer), pipe) != nullptr) {
+ while (collector->isRunning && fgets(buffer, sizeof(buffer), p.stream) != nullptr) {
collector->ParseLine(std::string(buffer));
}
- pclose(pipe);
+ p.Pclose();
collector->Close();
}
diff --git a/src/plugin/collect/system/kernel_config.cpp b/src/plugin/collect/system/kernel_config.cpp
index 63aafea..6bdfc8a 100644
--- a/src/plugin/collect/system/kernel_config.cpp
+++ b/src/plugin/collect/system/kernel_config.cpp
@@ -113,6 +113,7 @@ static bool IsSymlink(const std::string &path)
}
return S_ISLNK(st.st_mode);
}
+
void KernelConfig::GetAllEth()
{
const std::string path = "/sys/class/net";
diff --git a/src/plugin_mgr/config.cpp b/src/plugin_mgr/config.cpp
index 341880b..8cd1432 100644
--- a/src/plugin_mgr/config.cpp
+++ b/src/plugin_mgr/config.cpp
@@ -15,23 +15,6 @@
#include "default_path.h"
namespace oeaware {
-bool CreateDir(const std::string &path)
-{
- size_t pos = 0;
- do {
- pos = path.find_first_of("/", pos + 1);
- std::string subPath = path.substr(0, pos);
- struct stat buffer;
- if (stat(subPath.c_str(), &buffer) == 0) {
- continue;
- }
- if (mkdir(subPath.c_str(), S_IRWXU | S_IRWXG) != 0) {
- return false;
- }
- } while (pos != std::string::npos);
- return true;
-}
-
bool CheckPluginList(YAML::Node pluginListItem)
{
if (pluginListItem["name"].IsNull()) {
diff --git a/src/plugin_mgr/config.h b/src/plugin_mgr/config.h
index 640ab00..19e6d33 100644
--- a/src/plugin_mgr/config.h
+++ b/src/plugin_mgr/config.h
@@ -130,7 +130,6 @@ private:
};
std::string GetPath();
-bool CreateDir(const std::string &path);
}
#endif
diff --git a/src/plugin_mgr/message_manager.cpp b/src/plugin_mgr/message_manager.cpp
index 1ffa4cc..bfa5b0c 100644
--- a/src/plugin_mgr/message_manager.cpp
+++ b/src/plugin_mgr/message_manager.cpp
@@ -11,6 +11,7 @@
******************************************************************************/
#include "message_manager.h"
#include <thread>
+#include <pwd.h>
#include <securec.h>
#include "default_path.h"
#include "utils.h"
@@ -41,15 +42,56 @@ int Epoll::EventWait(struct epoll_event *events, int maxEvents, int timeout)
return epoll_wait(epfd, events, maxEvents, timeout);
}
+static std::vector<std::string> GetUserFromGroup(const std::string &groupName)
+{
+ std::vector<std::string> users;
+ std::ifstream file("/etc/group");
+ if (!file.is_open()) {
+ return users;
+ }
+ std::string line;
+ size_t userPartIndex = 3;
+ while (std::getline(file, line)) {
+ std::vector<std::string> parts = SplitString(line, ":");
+ if (parts.size() > userPartIndex && parts[0] == groupName) {
+ std::vector<std::string> userParts = SplitString(parts[userPartIndex], ",");
+ users.insert(users.end(), userParts.begin(), userParts.end());
+ break;
+ }
+ }
+ file.close();
+ return users;
+}
+
+static int GetUid(const std::string &name)
+{
+ struct passwd pwd;
+ struct passwd *result;
+ char buf[1024];
+ int res = getpwnam_r(name.c_str(), &pwd, buf, sizeof(buf), &result);
+ if (res != 0 || result == nullptr) {
+ return -1;
+ }
+ return pwd.pw_uid;
+}
+
void TcpSocket::InitGroups()
{
std::vector<std::string> groupNames{"oeaware", "root"};
+ groups[0].emplace_back(0);
for (auto &groupName : groupNames) {
auto gid = GetGidByGroupName(groupName);
if (gid < 0) {
continue;
}
- groups.emplace_back(gid);
+ auto users = GetUserFromGroup(groupName);
+ for (auto &user : users) {
+ auto uid = GetUid(user);
+ if (uid < 0) {
+ continue;
+ }
+ groups[gid].emplace_back(uid);
+ }
}
}
@@ -68,6 +110,11 @@ bool TcpSocket::StartListen()
ERROR(logger, path << " chmod error!");
return false;
}
+ std::string cmd = "setfacl -m g:oeaware:rw " + path;
+ auto ret = system(cmd.c_str());
+ if (ret) {
+ WARN(logger, "failed to set the communication permission of the oeaware user group.");
+ }
if (domainSocket->Listen() < 0) {
ERROR(logger, "listen error!");
return false;
@@ -136,7 +183,6 @@ static void GetEventResult(Message &msg, EventResultQueue sendMessage)
}
const int DISCONNECTED = -1;
-const int DISCONNECTED_AND_UNSUBCRIBE = -2;
void TcpMessageHandler::Init(EventQueue newRecvMessage, EventResultQueue newSendMessage, EventQueue newRecvData)
{
@@ -240,6 +286,23 @@ void TcpMessageHandler::Start()
}
}
+bool TcpSocket::CheckFileGroups(const std::string &path)
+{
+ struct stat st;
+ if (lstat(path.c_str(), &st) < 0) {
+ return false;
+ }
+ for (auto &p : groups) {
+ bool ok = std::any_of(p.second.begin(), p.second.end(), [&](uid_t uid) {
+ return uid == st.st_uid;
+ });
+ if (ok) {
+ return true;
+ }
+ }
+ return false;
+}
+
void TcpSocket::SaveConnection()
{
struct sockaddr_un un;
@@ -255,12 +318,12 @@ void TcpSocket::SaveConnection()
memcpy_s(name, maxNameLength, un.sun_path, len);
name[len] = 0;
bool isSdk = false;
- if (strcmp(name, DEFAULT_SDK_CONN_PATH.c_str()) == 0) {
+ if (len > 0) {
isSdk = true;
}
// check permission
- if (isSdk && !CheckFileGroups(DEFAULT_SDK_CONN_PATH, groups)) {
- WARN(logger, "sdk permission error");
+ if (isSdk && !CheckFileGroups(name)) {
+ WARN(logger, "sdk permission error, " << name);
return;
}
if (!epoll->EventCtl(EPOLL_CTL_ADD, conn)) {
@@ -274,6 +337,9 @@ void TcpSocket::SaveConnection()
type |= CMD_CONN;
}
tcpMessageHandler.AddConn(conn, type);
+ if (isSdk) {
+ INFO(logger, "a sdk connection is established, " << name);
+ }
DEBUG(logger, "client connected!");
}
diff --git a/src/plugin_mgr/message_manager.h b/src/plugin_mgr/message_manager.h
index 38f544d..3c67096 100644
--- a/src/plugin_mgr/message_manager.h
+++ b/src/plugin_mgr/message_manager.h
@@ -73,12 +73,13 @@ private:
bool StartListen();
void SaveConnection();
void HandleEvents(struct epoll_event *events, int num);
+ bool CheckFileGroups(const std::string &path);
private:
log4cplus::Logger logger;
std::unique_ptr<DomainSocket> domainSocket;
std::unique_ptr<Epoll> epoll;
TcpMessageHandler tcpMessageHandler;
- std::vector<gid_t> groups;
+ std::unordered_map<int, std::vector<uid_t>> groups;
const int maxRequestNum = 20;
const int maxNameLength = 108;
};
diff --git a/src/sdk/oe_client.cpp b/src/sdk/oe_client.cpp
index 9452a37..040433a 100644
--- a/src/sdk/oe_client.cpp
+++ b/src/sdk/oe_client.cpp
@@ -80,7 +80,17 @@ void Impl::HandleRecv()
}
int Impl::Init()
{
- domainSocket = std::make_shared<DomainSocket>(DEFAULT_SDK_CONN_PATH);
+ auto home = getenv("HOME");
+ std::string homeDir;
+ if (home == nullptr) {
+ homeDir = "/var/run/oeAware";
+ } else {
+ homeDir = home;
+ homeDir += "/.oeaware";
+ }
+
+ CreateDir(homeDir);
+ domainSocket = std::make_shared<DomainSocket>(homeDir + "/oeaware-sdk.sock");
domainSocket->SetRemotePath(DEFAULT_SERVER_LISTEN_PATH);
resultQueue = std::make_shared<SafeQueue<Result>>();
int sock = domainSocket->Socket();
--
2.33.0