diff --git a/src/cgproxyd.hpp b/src/cgproxyd.hpp index 6214de5..25f0694 100644 --- a/src/cgproxyd.hpp +++ b/src/cgproxyd.hpp @@ -92,15 +92,19 @@ class cgproxyd { v = config.program_noproxy; if (find(v.begin(), v.end(), path) != v.end()) { - info("execsnoop noproxy: %d %s", pid, path); - free(path); - return attach(pid, config.cgroup_noproxy_preserved); + if (CGROUP::getCgroup(pid) != config.cgroup_noproxy_preserved) { + info("execsnoop noproxy: %d %s", pid, path); + free(path); + return attach(pid, config.cgroup_noproxy_preserved); + } } v = config.program_proxy; if (find(v.begin(), v.end(), path) != v.end()) { - info("execsnoop proxied: %d %s", pid, path); - free(path); - return attach(pid, config.cgroup_proxy_preserved); + if (CGROUP::getCgroup(pid) != config.cgroup_proxy_preserved) { + info("execsnoop proxied: %d %s", pid, path); + free(path); + return attach(pid, config.cgroup_proxy_preserved); + } } free(path); return 0; @@ -208,16 +212,20 @@ class cgproxyd { } void processRunningProgram() { - debug("process running program") for (auto &path : - config.program_noproxy) for (auto &pid : - bash_pidof(path)) { - int status = attach(pid, config.cgroup_noproxy_preserved); - if (status == 0) info("noproxy running process %d %s", pid, path.c_str()); - } + debug("process running program"); + for (auto &path : config.program_noproxy) + for (auto &pid : bash_pidof(path)) { + if (CGROUP::getCgroup(pid) != config.cgroup_noproxy_preserved) { + int status = attach(pid, config.cgroup_noproxy_preserved); + if (status == 0) info("noproxy running process %d %s", pid, path.c_str()); + } + } for (auto &path : config.program_proxy) for (auto &pid : bash_pidof(path)) { - int status = attach(pid, config.cgroup_proxy_preserved); - if (status == 0) info("proxied running process %d %s", pid, path.c_str()); + if (CGROUP::getCgroup(pid) != config.cgroup_proxy_preserved) { + int status = attach(pid, config.cgroup_proxy_preserved); + if (status == 0) info("proxied running process %d %s", pid, path.c_str()); + } } } @@ -302,4 +310,4 @@ int main(int argc, char *argv[]) { return d.start(); } } // namespace CGPROXY::CGPROXYD -#endif \ No newline at end of file +#endif diff --git a/src/cgroup_attach.cpp b/src/cgroup_attach.cpp index 09b0e0a..1f64169 100644 --- a/src/cgroup_attach.cpp +++ b/src/cgroup_attach.cpp @@ -15,12 +15,6 @@ namespace CGPROXY::CGROUP { string cgroup2_mount_point = get_cgroup2_mount_point(); -bool exist(string path) { - struct stat st; - if (stat(path.c_str(), &st) != -1) { return S_ISDIR(st.st_mode); } - return false; -} - string get_cgroup2_mount_point() { stringstream buffer; FILE *fp = popen("findmnt -t cgroup2 -n -o TARGET", "r"); @@ -33,6 +27,24 @@ string get_cgroup2_mount_point() { return s; } +string getCgroup(const pid_t &pid) { return getCgroup(to_str(pid)); } + +string getCgroup(const string &pid) { + string cgroup_f = to_str("/proc/", pid, "/cgroup"); + if (!fileExist(cgroup_f)) return ""; + char buf[128]; + FILE *f = fopen(cgroup_f.c_str(), "r"); + int id; + char cgroup[256]; + while (fgets(buf, 128, f) != NULL) { + if (buf[0] == '0') { + if (sscanf(buf, "%*i::%s", cgroup) == 1) return cgroup; + error("sscanf %s failed", buf); + } + } + return ""; +} + bool validate(string pid, string cgroup) { bool pid_v = validPid(pid); bool cg_v = validCgroup(cgroup); @@ -50,14 +62,13 @@ int attach(const string pid, const string cgroup_target) { debug("attaching %s to %s", pid.c_str(), cgroup_target.c_str()); - int status; if (!validate(pid, cgroup_target)) return_error; if (cgroup2_mount_point.empty()) return_error; string cgroup_target_path = cgroup2_mount_point + cgroup_target; string cgroup_target_procs = cgroup_target_path + "/cgroup.procs"; // check if exist, we will create it if not exist - if (!exist(cgroup_target_path)) { + if (!dirExist(cgroup_target_path)) { if (mkdir(cgroup_target_path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) { debug("created cgroup %s success", cgroup_target.c_str()); @@ -69,6 +80,11 @@ int attach(const string pid, const string cgroup_target) { // return_error } + if (getCgroup(pid) == cgroup_target) { + debug("%s already in %s", pid.c_str(), cgroup_target.c_str()); + return_success; + } + // put pid to target cgroup ofstream procs(cgroup_target_procs, ofstream::app); if (!procs.is_open()) { @@ -91,4 +107,4 @@ int attach(const int pid, const string cgroup_target) { return attach(to_str(pid), cgroup_target); } -} // namespace CGPROXY::CGROUP \ No newline at end of file +} // namespace CGPROXY::CGROUP diff --git a/src/cgroup_attach.h b/src/cgroup_attach.h index 62560db..34f81be 100644 --- a/src/cgroup_attach.h +++ b/src/cgroup_attach.h @@ -7,12 +7,13 @@ using namespace std; namespace CGPROXY::CGROUP { extern string cgroup2_mount_point; -bool exist(string path); bool validate(string pid, string cgroup); string get_cgroup2_mount_point(); +string getCgroup(const pid_t &pid); +string getCgroup(const string &pid); int attach(const string pid, const string cgroup_target); int attach(const int pid, const string cgroup_target); } // namespace CGPROXY::CGROUP -#endif \ No newline at end of file +#endif