TEST_F(FilesystemTests, test_safe_permissions) { // For testing we can request a different directory path. EXPECT_TRUE(safePermissions("/", kFakeDirectory + "/door.txt")); // A file with a directory.mode & 0x1000 fails. EXPECT_FALSE(safePermissions("/tmp", kFakeDirectory + "/door.txt")); // A directory for a file will fail. EXPECT_FALSE(safePermissions("/", kFakeDirectory + "/deep11")); // A root-owned file is appropriate EXPECT_TRUE(safePermissions("/", "/dev/zero")); }
void WatcherRunner::createWorker() { { WatcherLocker locker; if (Watcher::getState(Watcher::getWorker()).last_respawn_time > getUnixTime() - getWorkerLimit(RESPAWN_LIMIT)) { LOG(WARNING) << "osqueryd worker respawning too quickly: " << Watcher::workerRestartCount() << " times"; Watcher::workerRestarted(); // The configured automatic delay. size_t delay = getWorkerLimit(RESPAWN_DELAY) * 1000; // Exponential back off for quickly-respawning clients. delay += pow(2, Watcher::workerRestartCount()) * 1000; pauseMilli(delay); } } // Get the path of the current process. auto qd = SQL::selectAllFrom("processes", "pid", EQUALS, INTEGER(PlatformProcess::getCurrentProcess()->pid())); if (qd.size() != 1 || qd[0].count("path") == 0 || qd[0]["path"].size() == 0) { LOG(ERROR) << "osquery watcher cannot determine process path for worker"; Initializer::requestShutdown(EXIT_FAILURE); return; } // Set an environment signaling to potential plugin-dependent workers to wait // for extensions to broadcast. if (Watcher::hasManagedExtensions()) { setEnvVar("OSQUERY_EXTENSIONS", "true"); } // Get the complete path of the osquery process binary. boost::system::error_code ec; auto exec_path = fs::system_complete(fs::path(qd[0]["path"]), ec); if (!safePermissions( exec_path.parent_path().string(), exec_path.string(), true)) { // osqueryd binary has become unsafe. LOG(ERROR) << RLOG(1382) << "osqueryd has unsafe permissions: " << exec_path.string(); Initializer::requestShutdown(EXIT_FAILURE); return; } auto worker = PlatformProcess::launchWorker(exec_path.string(), argc_, argv_); if (worker == nullptr) { // Unrecoverable error, cannot create a worker process. LOG(ERROR) << "osqueryd could not create a worker process"; Initializer::shutdown(EXIT_FAILURE); return; } Watcher::setWorker(worker); Watcher::resetWorkerCounters(getUnixTime()); VLOG(1) << "osqueryd watcher (" << PlatformProcess::getCurrentProcess()->pid() << ") executing worker (" << worker->pid() << ")"; }
bool WatcherRunner::createExtension(const std::string& extension) { { WatcherLocker locker; if (Watcher::getState(extension).last_respawn_time > getUnixTime() - getWorkerLimit(RESPAWN_LIMIT)) { LOG(WARNING) << "Extension respawning too quickly: " << extension; // Unlike a worker, if an extension respawns to quickly we give up. return false; } } // Check the path to the previously-discovered extension binary. boost::system::error_code ec; auto exec_path = fs::system_complete(fs::path(extension), ec); if (!safePermissions( exec_path.parent_path().string(), exec_path.string(), true)) { // Extension binary has become unsafe. LOG(WARNING) << RLOG(1382) << "Extension binary has unsafe permissions: " << extension; return false; } auto ext_process = PlatformProcess::launchExtension(exec_path.string(), extension, Flag::getValue("extensions_socket"), Flag::getValue("extensions_timeout"), Flag::getValue("extensions_interval"), Flag::getValue("verbose")); if (ext_process == nullptr) { // Unrecoverable error, cannot create an extension process. LOG(ERROR) << "Cannot create extension process: " << extension; Initializer::shutdown(EXIT_FAILURE); } Watcher::setExtension(extension, ext_process); Watcher::resetExtensionCounters(extension, getUnixTime()); VLOG(1) << "Created and monitoring extension child (" << ext_process->pid() << "): " << extension; return true; }