From a418b8ea5341b6ce20c01994ee7a3e4a108e56e9 Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Tue, 14 Jan 2020 13:52:41 +0900 Subject: [PATCH] osquery: Remove process Signed-off-by: Sangwan Kwon --- src/osquery/CMakeLists.txt | 1 - src/osquery/core/init.cpp | 21 +-- src/osquery/core/system.cpp | 38 +--- src/osquery/devtools/printer.cpp | 1 - src/osquery/devtools/shell.cpp | 1 - src/osquery/filesystem/tests/filesystem.cpp | 11 -- src/osquery/include/osquery/system.h | 7 - src/osquery/main/main.cpp | 9 - src/osquery/process/CMakeLists.txt | 16 -- src/osquery/process/posix/process.cpp | 152 ---------------- src/osquery/process/posix/process_ops.cpp | 77 -------- src/osquery/process/process.h | 266 ---------------------------- src/osquery/registry/registry_factory.cpp | 1 - src/osquery/sql/virtual_table.cpp | 7 +- src/osquery/tests/test_util.cpp | 3 +- 15 files changed, 6 insertions(+), 605 deletions(-) delete mode 100644 src/osquery/process/CMakeLists.txt delete mode 100644 src/osquery/process/posix/process.cpp delete mode 100644 src/osquery/process/posix/process_ops.cpp delete mode 100644 src/osquery/process/process.h diff --git a/src/osquery/CMakeLists.txt b/src/osquery/CMakeLists.txt index c0e05fe..47aef40 100644 --- a/src/osquery/CMakeLists.txt +++ b/src/osquery/CMakeLists.txt @@ -49,7 +49,6 @@ ADD_SUBDIRECTORY(events) ADD_SUBDIRECTORY(filesystem) ADD_SUBDIRECTORY(logger) ADD_SUBDIRECTORY(plugins) -ADD_SUBDIRECTORY(process) ADD_SUBDIRECTORY(registry) ADD_SUBDIRECTORY(sql) ADD_SUBDIRECTORY(tables) diff --git a/src/osquery/core/init.cpp b/src/osquery/core/init.cpp index be40f24..4237b31 100644 --- a/src/osquery/core/init.cpp +++ b/src/osquery/core/init.cpp @@ -14,6 +14,8 @@ #include #include +#include + #ifdef WIN32 #include @@ -38,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -251,9 +252,6 @@ Initializer::Initializer(int& argc, // The 'main' thread is that which executes the initializer. kMainThreadId = std::this_thread::get_id(); - // Maintain a legacy thread id for Windows service stops. - kLegacyThreadId = platformGetTid(); - #ifndef WIN32 // Set the max number of open files. struct rlimit nofiles; @@ -352,19 +350,6 @@ Initializer::Initializer(int& argc, } } - // Initialize the status and results logger. - initStatusLogger(binary_, init_glog); - if (isWorker()) { - VLOG(1) << "osquery worker initialized [watcher=" - << PlatformProcess::getLauncherProcess()->pid() << "]"; - } else { - VLOG(1) << "osquery initialized [version=" << kVersion << "]"; - } - - if (default_flags) { - VLOG(1) << "Using default flagfile: " << kBackupDefaultFlagfile; - } - // Initialize the COM libs platformSetup(); } @@ -463,8 +448,6 @@ void Initializer::start() const { auto retcode = (isWorker()) ? EXIT_CATASTROPHIC : EXIT_FAILURE; requestShutdown(retcode); } - - sleepFor(kDatabaseRetryDelay); } // Ensure the database results version is up to date before proceeding diff --git a/src/osquery/core/system.cpp b/src/osquery/core/system.cpp index 8409e21..1ae042f 100644 --- a/src/osquery/core/system.cpp +++ b/src/osquery/core/system.cpp @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -300,9 +299,6 @@ Status checkStalePid(const std::string& content) { return Status::success(); } - PlatformProcess target(pid); - int status = 0; - // The pid is running, check if it is an osqueryd process by name. std::stringstream query_text; @@ -317,12 +313,7 @@ Status checkStalePid(const std::string& content) { if (q.rows().size() > 0) { // If the process really is osqueryd, return an "error" status. if (FLAGS_force) { - // The caller may choose to abort the existing daemon with --force. - // Do not use SIGQUIT as it will cause a crash on OS X. - status = target.kill() ? 0 : -1; - sleepFor(1000); - - return Status(status, "Tried to force remove the existing osqueryd"); + return Status(1, "Tried to force remove the existing osqueryd"); } return Status(1, "osqueryd (" + content + ") is already running"); @@ -357,32 +348,7 @@ Status createPidFile() { LOG(WARNING) << "Unable to remove the osqueryd pidfile"; } - // If no pidfile exists or the existing pid was stale, write, log, and run. - auto pid = std::to_string(PlatformProcess::getCurrentPid()); - VLOG(1) << "Writing osqueryd pid (" << pid << ") to " - << pidfile_path.string(); - auto status = writeTextFile(pidfile_path, pid, 0644); - return status; -} - -bool PlatformProcess::cleanup() const { - if (!isValid()) { - return false; - } - - size_t delay = 0; - size_t timeout = (FLAGS_alarm_timeout + 1) * 1000; - while (delay < timeout) { - int status = 0; - if (checkStatus(status) == PROCESS_EXITED) { - return true; - } - - sleepFor(200); - delay += 200; - } - // The requested process did not exit. - return false; + return Status(-1, "failed"); } #ifndef WIN32 diff --git a/src/osquery/devtools/printer.cpp b/src/osquery/devtools/printer.cpp index a427402..3576900 100644 --- a/src/osquery/devtools/printer.cpp +++ b/src/osquery/devtools/printer.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/src/osquery/devtools/shell.cpp b/src/osquery/devtools/shell.cpp index 19eabdc..0b56208 100644 --- a/src/osquery/devtools/shell.cpp +++ b/src/osquery/devtools/shell.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/src/osquery/filesystem/tests/filesystem.cpp b/src/osquery/filesystem/tests/filesystem.cpp index 88919d9..2eaa56c 100644 --- a/src/osquery/filesystem/tests/filesystem.cpp +++ b/src/osquery/filesystem/tests/filesystem.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -449,16 +448,6 @@ TEST_F(FilesystemTests, test_user_namespace_parser) { } #endif -TEST_F(FilesystemTests, test_read_proc) { - std::string content; - - if (isPlatform(PlatformType::TYPE_LINUX)) { - fs::path stat_path("/proc/" + std::to_string(platformGetPid()) + "/stat"); - EXPECT_TRUE(readFile(stat_path, content).ok()); - EXPECT_GT(content.size(), 0U); - } -} - TEST_F(FilesystemTests, test_read_symlink) { std::string content; diff --git a/src/osquery/include/osquery/system.h b/src/osquery/include/osquery/system.h index f731761..5e4623e 100644 --- a/src/osquery/include/osquery/system.h +++ b/src/osquery/include/osquery/system.h @@ -291,13 +291,6 @@ std::string getHostIdentifier(); Status createPidFile(); /** - * @brief Getter for determining Admin status - * - * @return A bool indicating if the current process is running as admin - */ -bool isUserAdmin(); - -/** * @brief Set the name of the thread * * @return If the name was set successfully diff --git a/src/osquery/main/main.cpp b/src/osquery/main/main.cpp index 3953e9d..aa10f0e 100644 --- a/src/osquery/main/main.cpp +++ b/src/osquery/main/main.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -57,10 +56,6 @@ int profile(int argc, char* argv[]) { query = std::string(argv[1]); } - if (osquery::FLAGS_profile_delay > 0) { - osquery::sleepFor(osquery::FLAGS_profile_delay * 1000); - } - // Perform some duplication from Initializer with respect to database setup. osquery::DatabasePlugin::setAllowOpen(true); osquery::RegistryFactory::get().setActive("database", "ephemeral"); @@ -77,10 +72,6 @@ int profile(int argc, char* argv[]) { } } - if (osquery::FLAGS_profile_delay > 0) { - osquery::sleepFor(osquery::FLAGS_profile_delay * 1000); - } - return 0; } diff --git a/src/osquery/process/CMakeLists.txt b/src/osquery/process/CMakeLists.txt deleted file mode 100644 index 27fa3e1..0000000 --- a/src/osquery/process/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved -# -# 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 - -ADD_OSQUERY_LIBRARY(osquery_process posix/process.cpp - posix/process_ops.cpp) diff --git a/src/osquery/process/posix/process.cpp b/src/osquery/process/posix/process.cpp deleted file mode 100644 index 715334d..0000000 --- a/src/osquery/process/posix/process.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed in accordance with the terms specified in - * the LICENSE file found in the root directory of this source tree. - */ - -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include - -#ifndef NSIG -#define NSIG 32 -#endif - -extern char** environ; - -namespace osquery { - -PlatformProcess::PlatformProcess(PlatformPidType id) : id_(id) {} - -bool PlatformProcess::operator==(const PlatformProcess& process) const { - return (nativeHandle() == process.nativeHandle()); -} - -bool PlatformProcess::operator!=(const PlatformProcess& process) const { - return (nativeHandle() != process.nativeHandle()); -} - -PlatformProcess::~PlatformProcess() {} - -int PlatformProcess::pid() const { - return id_; -} - -bool PlatformProcess::kill() const { - if (!isValid()) { - return false; - } - - int status = ::kill(nativeHandle(), SIGKILL); - return (status == 0); -} - -bool PlatformProcess::killGracefully() const { - if (!isValid()) { - return false; - } - - int status = ::kill(nativeHandle(), SIGTERM); - return (status == 0); -} - -ProcessState PlatformProcess::checkStatus(int& status) const { - int process_status = 0; - if (!isValid()) { - return PROCESS_ERROR; - } - - pid_t result = ::waitpid(nativeHandle(), &process_status, WNOHANG); - if (result < 0) { - if (errno == ECHILD) { - return PROCESS_EXITED; - } - process_status = -1; - return PROCESS_ERROR; - } - - if (result == 0) { - return PROCESS_STILL_ALIVE; - } - - if (WIFEXITED(process_status)) { - status = WEXITSTATUS(process_status); - return PROCESS_EXITED; - } - - // process's state has changed but the state isn't that which we expect! - return PROCESS_STATE_CHANGE; -} - -std::shared_ptr PlatformProcess::getCurrentProcess() { - pid_t pid = ::getpid(); - return std::make_shared(pid); -} - -int PlatformProcess::getCurrentPid() { - return PlatformProcess::getCurrentProcess()->pid(); -} - -std::shared_ptr PlatformProcess::getLauncherProcess() { - pid_t ppid = ::getppid(); - return std::make_shared(ppid); -} - -std::shared_ptr PlatformProcess::launchWorker( - const std::string& exec_path, int argc /* unused */, char** argv) { - auto worker_pid = ::fork(); - if (worker_pid < 0) { - return std::shared_ptr(); - } else if (worker_pid == 0) { - setEnvVar("OSQUERY_WORKER", std::to_string(::getpid()).c_str()); - ::execve(exec_path.c_str(), argv, ::environ); - - // Code should never reach this point - LOG(ERROR) << "osqueryd could not start worker process"; - ::exit(EXIT_CATASTROPHIC); - return std::shared_ptr(); - } - return std::make_shared(worker_pid); -} - -std::shared_ptr PlatformProcess::launchTestPythonScript( - const std::string& args) { - std::string osquery_path; - auto osquery_path_option = getEnvVar("OSQUERY_DEPS"); - if (osquery_path_option) { - osquery_path = *osquery_path_option; - } else { - if (!isPlatform(PlatformType::TYPE_FREEBSD)) { - osquery_path = "/usr/bin/env python"; - } else { - osquery_path = "/usr/local/bin/python"; - } - } - - // The whole-string, space-delimited, python process arguments. - auto argv = osquery_path + " " + args; - - std::shared_ptr process; - int process_pid = ::fork(); - if (process_pid == 0) { - // Start a Python script - ::execlp("sh", "sh", "-c", argv.c_str(), nullptr); - ::exit(0); - } else if (process_pid > 0) { - process.reset(new PlatformProcess(process_pid)); - } - - return process; -} -} // namespace osquery diff --git a/src/osquery/process/posix/process_ops.cpp b/src/osquery/process/posix/process_ops.cpp deleted file mode 100644 index 28366ee..0000000 --- a/src/osquery/process/posix/process_ops.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed in accordance with the terms specified in - * the LICENSE file found in the root directory of this source tree. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include - -namespace osquery { - -DECLARE_uint64(alarm_timeout); - -int platformGetUid() { - return ::getuid(); -} - -bool isLauncherProcessDead(PlatformProcess& launcher) { - if (!launcher.isValid()) { - return true; - } - - return (::getppid() != launcher.nativeHandle()); -} - -ModuleHandle platformModuleOpen(const std::string& path) { - return ::dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL); -} - -void* platformModuleGetSymbol(ModuleHandle module, const std::string& symbol) { - return ::dlsym(module, symbol.c_str()); -} - -std::string platformModuleGetError() { - return ::dlerror(); -} - -bool platformModuleClose(ModuleHandle module) { - return (::dlclose(module) == 0); -} - -void setToBackgroundPriority() { - setpriority(PRIO_PGRP, 0, 10); -} - -// Helper function to determine if thread is running with admin privilege. -bool isUserAdmin() { - return getuid() == 0; -} - -int platformGetPid() { - return static_cast(getpid()); -} - -int platformGetTid() { - return std::hash()(std::this_thread::get_id()); -} - -void platformMainThreadExit(int excode) { - exit(excode); -} -} diff --git a/src/osquery/process/process.h b/src/osquery/process/process.h deleted file mode 100644 index c0928da..0000000 --- a/src/osquery/process/process.h +++ /dev/null @@ -1,266 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed in accordance with the terms specified in - * the LICENSE file found in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include - -#include - -#include - -#include -#include -// FIXME(fmanco): env functions were split but most usages still include -// process.h. Once those includes are fixed this can be removed. -#include - -namespace osquery { - -/// Constant for an invalid process -const auto kInvalidPid = (PlatformPidType)-1; - -/// Used by Windows to wait on the main execution thread -extern unsigned long kLegacyThreadId; - -/** - * @brief Categories of process states adapted to be platform agnostic - * - * A process can have the following states. Unfortunately, because of operating - * system differences. A generic state change is not directly translatable on - * Windows. Therefore, PROCESS_STATE_CHANGE will only occur on POSIX systems. - */ -enum ProcessState { - PROCESS_ERROR = -1, - PROCESS_STILL_ALIVE = 0, - PROCESS_EXITED, - PROCESS_STATE_CHANGE -}; - -/** - * @brief Platform-agnostic process object. - * - * PlatformProcess is a specialized, platform-agnostic class that handles the - * process operation needs of osquery. - */ -class PlatformProcess : private boost::noncopyable { - public: - /// Default constructor marks the process as invalid - explicit PlatformProcess() : id_(kInvalidPid) {} - explicit PlatformProcess(PlatformPidType id); - -#ifdef WIN32 - /* - * @brief Constructor that accepts a pid_t - * - * Allow for the creation of a PlatformProcess object from a pid_t. On - * Windows, PlatformPidType is not a pid_t because it cannot be assumed that - * the PID will point to the expected process. After a process dies, the PID - * can be immediately reused. Using HANDLEs (as what is done now) mitigates - * this issue. - */ - explicit PlatformProcess(pid_t pid); -#endif - - PlatformProcess(const PlatformProcess& src) = delete; - PlatformProcess(PlatformProcess&& src) noexcept; - virtual ~PlatformProcess(); - - PlatformProcess& operator=(const PlatformProcess& process) = delete; - bool operator==(const PlatformProcess& process) const; - bool operator!=(const PlatformProcess& process) const; - - /** - * @brief Returns the process's ID - * - * Returns the associated process' process ID (on POSIX, pid() and - * nativeHandle() do not differ). - * - * NOTE: In most situations, this should ideally not be used on Windows when - * dealing with tracking process lifetimes. - */ - int pid() const; - - /** - * @brief Returns the native "handle" object of the process. - * - * On Windows, this is in the of a HANDLE. For POSIX, this is just the pid_t - * of the process. - */ - PlatformPidType nativeHandle() const { - return id_; - } - - /// Hard terminates the process - bool kill() const; - - /** - * @brief Attempt to kill a process gracefully, usually a child process. - */ - bool killGracefully() const; - - /** - * @brief Wait or cleanup a process, usually a child process. - * - * This will wait for a process to cleanup. Use this after requesting a - * graceful shutdown. - * - * @return true if the process was cleaned, otherwise false. - */ - bool cleanup() const; - - /// Returns whether the PlatformProcess object is valid - bool isValid() const { - return (id_ != kInvalidPid); - } - - virtual ProcessState checkStatus(int& status) const; - - /// Returns the current process - static std::shared_ptr getCurrentProcess(); - - /// Returns the pid of the current process - static int getCurrentPid(); - - /// Returns the launcher process (only works for worker processes) - static std::shared_ptr getLauncherProcess(); - - /** - * @brief Creates a new worker process. - * - * Launches a worker process given a worker executable path, number of - * arguments, and an array of arguments. All double quotes within each entry - * in the array of arguments will be supplanted with a preceding blackslash. - */ - static std::shared_ptr launchWorker( - const std::string& exec_path, int argc, char** argv); - - /** - * @brief Launches a new test Python script. - * - * This will launch a new Python process to run the specified script and - * script arguments. This is used within the test harnesses to run example - * TLS server scripts. - */ - static std::shared_ptr launchTestPythonScript( - const std::string& args); - - private: - /** - * @brief Stores the native handle denoting the process - * - * "Handle" of the process. On Windows, this will be a HANDLE. On POSIX - * systems, this will be a pid_t. - */ - PlatformPidType id_; -}; - -#ifdef WIN32 -/** - * @brief Handles the resource lifetime of a PSECURITY_DESCRIPTOR - * - * Class to handle the scope of a PSECURITY_DESCRIPTOR from - * GetSecurityInfo/GetNamedSecurityInfo class of functions (or any - * PSECURITY_DESCRIPTOR pointer where the buffer is allocated via LocalAlloc) - */ -class SecurityDescriptor { - public: - explicit SecurityDescriptor(PSECURITY_DESCRIPTOR sd) : sd_(sd) {} - - SecurityDescriptor(SecurityDescriptor&& src) noexcept { - sd_ = src.sd_; - std::swap(sd_, src.sd_); - } - - ~SecurityDescriptor() { - if (sd_ != nullptr) { - ::LocalFree(sd_); - sd_ = nullptr; - } - } - - private: - PSECURITY_DESCRIPTOR sd_{nullptr}; -}; -#endif - -/// Returns the current user's ID (UID on POSIX systems and RID for Windows) -int platformGetUid(); - -inline void sleepFor(size_t msec) { - std::chrono::milliseconds mduration(msec); - std::this_thread::sleep_for(mduration); -} - -/** - * @brief Returns a handle of the specified module path - * - * On POSIX, this invokes dlopen with RTLD_NOW and RTLD_LOCAL flags - */ -ModuleHandle platformModuleOpen(const std::string& path); - -/** - * @brief Returns a pointer of where the requested symbol exists - */ -void* platformModuleGetSymbol(ModuleHandle module, const std::string& symbol); - -/** - * @brief Returns a string of the last error - * - * On Windows, this returns the last error message which may not necessarily be - * from a module operation. It is suggested to call this immediately after a - * platformModule function for best accuracy. - */ -std::string platformModuleGetError(); - -/** - * @brief Closes the library handle - * - * On Windows, this will also try to unload the library. - */ -bool platformModuleClose(ModuleHandle module); - -/** - * @brief Checks to see if the launcher process is dead - * - * Note, this only works on worker processes. - */ -bool isLauncherProcessDead(PlatformProcess& launcher); - -/// Sets the current process to run with background scheduling priority. -void setToBackgroundPriority(); - -/** - * @brief Returns the current processes pid - * - * On Windows, returns the value of GetCurrentProcessId - * and on posix platforms returns getpid() - */ -int platformGetPid(); - -/** - * @brief Returns the current thread id - * - * On Windows, returns the value of GetCurrentThreadId - * and on posix platforms returns gettid() - */ -int platformGetTid(); - -/** - * @brief Allows for platform specific exit logic - * - * On Windows this makes use of a thread specific exit APIs - * to ensure that our main threads shutdown and notify the SCM - * thread so we can close the service cleanly. On posix this is - * just a stub to exit() - */ -void platformMainThreadExit(int excode); -} // namespace osquery diff --git a/src/osquery/registry/registry_factory.cpp b/src/osquery/registry/registry_factory.cpp index 316395e..c3227ba 100644 --- a/src/osquery/registry/registry_factory.cpp +++ b/src/osquery/registry/registry_factory.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/src/osquery/sql/virtual_table.cpp b/src/osquery/sql/virtual_table.cpp index f2b9352..ebddd4c 100644 --- a/src/osquery/sql/virtual_table.cpp +++ b/src/osquery/sql/virtual_table.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -822,10 +821,6 @@ static int xFilter(sqlite3_vtab_cursor* pVtabCursor, BaseCursor* pCur = (BaseCursor*)pVtabCursor; auto* pVtab = (VirtualTable*)pVtabCursor->pVtab; auto content = pVtab->content; - if (FLAGS_table_delay > 0 && pVtab->instance->tableCalled(*content)) { - // Apply an optional sleep between table calls. - sleepFor(FLAGS_table_delay); - } pVtab->instance->addAffectedTable(content); pCur->row = 0; @@ -845,7 +840,7 @@ static int xFilter(sqlite3_vtab_cursor* pVtabCursor, // for UID. This may be represented in the requirements, but otherwise // would benefit from specific notification to the caller. bool user_based_satisfied = !( - (content->attributes & TableAttributes::USER_BASED) > 0 && isUserAdmin()); + (content->attributes & TableAttributes::USER_BASED) > 0); // For event-based tables, help the caller if events are disabled. bool events_satisfied = diff --git a/src/osquery/tests/test_util.cpp b/src/osquery/tests/test_util.cpp index 83a9aa9..2102794 100644 --- a/src/osquery/tests/test_util.cpp +++ b/src/osquery/tests/test_util.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -96,7 +95,7 @@ void initTesting() { // Set safe default values for path-based flags. // Specific unittests may edit flags temporarily. - kTestWorkingDirectory += std::to_string(platformGetUid()) + "/"; + kTestWorkingDirectory += std::to_string(1234) + "/"; kFakeDirectory = kTestWorkingDirectory + kFakeDirectoryName; fs::remove_all(kTestWorkingDirectory); -- 2.7.4