ADD_SUBDIRECTORY(filesystem)
ADD_SUBDIRECTORY(logger)
ADD_SUBDIRECTORY(plugins)
-ADD_SUBDIRECTORY(process)
ADD_SUBDIRECTORY(registry)
ADD_SUBDIRECTORY(sql)
ADD_SUBDIRECTORY(tables)
#include <stdio.h>
#include <time.h>
+#include <osquery/system.h>
+
#ifdef WIN32
#include <osquery/utils/system/system.h>
#include <osquery/events.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/flags.h>
-#include <osquery/process/process.h>
#include <osquery/registry.h>
#include <osquery/utils/info/version.h>
#include <osquery/utils/system/time.h>
// 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;
}
}
- // 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();
}
auto retcode = (isWorker()) ? EXIT_CATASTROPHIC : EXIT_FAILURE;
requestShutdown(retcode);
}
-
- sleepFor(kDatabaseRetryDelay);
}
// Ensure the database results version is up to date before proceeding
#include <osquery/filesystem/filesystem.h>
#include <osquery/flags.h>
#include <osquery/logger.h>
-#include <osquery/process/process.h>
#include <osquery/sql.h>
#include <osquery/system.h>
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;
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");
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
#include <osquery/core.h>
#include <osquery/devtools/devtools.h>
#include <osquery/flags.h>
-#include <osquery/process/process.h>
#include <osquery/utils/chars.h>
#include <osquery/utils/map_take.h>
#include <osquery/utils/system/env.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/flags.h>
#include <osquery/packs.h>
-#include <osquery/process/process.h>
#include <osquery/registry_factory.h>
#include <osquery/sql/virtual_table.h>
#include <osquery/utils/chars.h>
#include <osquery/flags.h>
#include <osquery/logger.h>
-#include <osquery/process/process.h>
#include <osquery/system.h>
#include <osquery/utils/info/platform_type.h>
}
#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;
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
#include <osquery/flags.h>
#include <osquery/logger.h>
#include <osquery/main/main.h>
-#include <osquery/process/process.h>
#include <osquery/registry_factory.h>
#include <osquery/sql/sqlite_util.h>
#include <osquery/system.h>
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");
}
}
- if (osquery::FLAGS_profile_delay > 0) {
- osquery::sleepFor(osquery::FLAGS_profile_delay * 1000);
- }
-
return 0;
}
+++ /dev/null
-# 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)
+++ /dev/null
-/**
- * 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 <errno.h>
-#include <signal.h>
-
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <vector>
-
-#include <osquery/logger.h>
-#include <osquery/process/process.h>
-#include <osquery/system.h>
-#include <osquery/utils/info/platform_type.h>
-
-#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> PlatformProcess::getCurrentProcess() {
- pid_t pid = ::getpid();
- return std::make_shared<PlatformProcess>(pid);
-}
-
-int PlatformProcess::getCurrentPid() {
- return PlatformProcess::getCurrentProcess()->pid();
-}
-
-std::shared_ptr<PlatformProcess> PlatformProcess::getLauncherProcess() {
- pid_t ppid = ::getppid();
- return std::make_shared<PlatformProcess>(ppid);
-}
-
-std::shared_ptr<PlatformProcess> PlatformProcess::launchWorker(
- const std::string& exec_path, int argc /* unused */, char** argv) {
- auto worker_pid = ::fork();
- if (worker_pid < 0) {
- return std::shared_ptr<PlatformProcess>();
- } 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<PlatformProcess>();
- }
- return std::make_shared<PlatformProcess>(worker_pid);
-}
-
-std::shared_ptr<PlatformProcess> 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<PlatformProcess> 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
+++ /dev/null
-/**
- * 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 <string>
-
-#include <dlfcn.h>
-#include <stdlib.h>
-
-#include <sys/resource.h>
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <boost/optional.hpp>
-
-#include <osquery/flags.h>
-#include <osquery/process/process.h>
-
-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<int>(getpid());
-}
-
-int platformGetTid() {
- return std::hash<std::thread::id>()(std::this_thread::get_id());
-}
-
-void platformMainThreadExit(int excode) {
- exit(excode);
-}
-}
+++ /dev/null
-/**
- * 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 <chrono>
-#include <memory>
-#include <string>
-#include <thread>
-
-#include <boost/noncopyable.hpp>
-
-#include <osquery/utils/system/system.h>
-
-#include <osquery/core.h>
-#include <osquery/system.h>
-// FIXME(fmanco): env functions were split but most usages still include
-// process.h. Once those includes are fixed this can be removed.
-#include <osquery/utils/system/env.h>
-
-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<PlatformProcess> getCurrentProcess();
-
- /// Returns the pid of the current process
- static int getCurrentPid();
-
- /// Returns the launcher process (only works for worker processes)
- static std::shared_ptr<PlatformProcess> 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<PlatformProcess> 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<PlatformProcess> 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
#include <sstream>
#include <osquery/logger.h>
-#include <osquery/process/process.h>
#include <osquery/flags.h>
#include <osquery/registry.h>
#include <osquery/utils/conversions/split.h>
#include <osquery/core.h>
#include <osquery/flags.h>
#include <osquery/logger.h>
-#include <osquery/process/process.h>
#include <osquery/registry_factory.h>
#include <osquery/sql/dynamic_table_row.h>
#include <osquery/sql/virtual_table.h>
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;
// 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 =
#include <osquery/utils/system/time.h>
#include <osquery/utils/conversions/tryto.h>
-#include <osquery/process/process.h>
#include <osquery/tests/test_util.h>
#include <osquery/utils/info/platform_type.h>
// 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);