2015-06-30 21:16:43 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2014, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "osquery/events/kernel.h"
|
|
|
|
|
|
|
|
#include <osquery/logger.h>
|
2015-06-30 21:20:04 +00:00
|
|
|
#include <osquery/core.h>
|
2015-06-30 21:16:43 +00:00
|
|
|
|
|
|
|
namespace osquery {
|
|
|
|
|
2015-07-27 19:11:44 +00:00
|
|
|
static const size_t shared_buffer_size_bytes = (20 * (1 << 20));
|
2015-06-30 21:16:43 +00:00
|
|
|
static const int max_events_before_sync = 1000;
|
|
|
|
|
|
|
|
REGISTER(KernelEventPublisher, "event_publisher", "kernel");
|
|
|
|
|
|
|
|
Status KernelEventPublisher::setUp() {
|
|
|
|
try {
|
|
|
|
queue_ = new CQueue(shared_buffer_size_bytes);
|
|
|
|
} catch (const CQueueException &e) {
|
2015-06-30 21:20:04 +00:00
|
|
|
if (kToolType == OSQUERY_TOOL_DAEMON) {
|
2015-07-14 22:52:19 +00:00
|
|
|
LOG(INFO) << "Cannot connect to kernel. " << e.what();
|
2015-06-30 21:20:04 +00:00
|
|
|
}
|
2015-07-14 22:52:19 +00:00
|
|
|
queue_ = nullptr;
|
|
|
|
return Status(0, e.what());
|
2015-06-30 21:16:43 +00:00
|
|
|
}
|
|
|
|
if (queue_ == nullptr) {
|
|
|
|
return Status(1, "Could not allocate CQueue object.");
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status(0, "OK");
|
|
|
|
}
|
|
|
|
|
|
|
|
void KernelEventPublisher::configure() {
|
|
|
|
for (const auto &sub : subscriptions_) {
|
|
|
|
if (queue_ != nullptr) {
|
|
|
|
auto sc = getSubscriptionContext(sub->context);
|
2015-07-13 21:38:49 +00:00
|
|
|
queue_->subscribe(sc->event_type, sc->udata);
|
2015-06-30 21:16:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KernelEventPublisher::tearDown() {
|
|
|
|
if (queue_ != nullptr) {
|
|
|
|
delete queue_;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status KernelEventPublisher::run() {
|
2015-07-14 22:52:19 +00:00
|
|
|
if (queue_ == nullptr) {
|
|
|
|
return Status(1, "No kernel communication.");
|
|
|
|
}
|
2015-06-30 21:16:43 +00:00
|
|
|
try {
|
2015-06-30 21:20:04 +00:00
|
|
|
int drops = 0;
|
|
|
|
if ((drops = queue_->kernelSync(OSQUERY_DEFAULT)) > 0 &&
|
|
|
|
kToolType == OSQUERY_TOOL_DAEMON) {
|
2015-07-27 19:11:44 +00:00
|
|
|
LOG(WARNING) << "Dropping " << drops << " kernel events.";
|
2015-06-30 21:20:04 +00:00
|
|
|
}
|
2015-06-30 21:16:43 +00:00
|
|
|
} catch (const CQueueException &e) {
|
|
|
|
LOG(WARNING) << e.what();
|
|
|
|
}
|
|
|
|
|
|
|
|
int max_before_sync = max_events_before_sync;
|
|
|
|
KernelEventContextRef ec;
|
2015-06-30 21:20:04 +00:00
|
|
|
osquery_event_t event_type = OSQUERY_NULL_EVENT;
|
|
|
|
CQueue::event *event = nullptr;
|
|
|
|
while (max_before_sync > 0 && (event_type = queue_->dequeue(&event))) {
|
|
|
|
switch (event_type) {
|
|
|
|
case OSQUERY_PROCESS_EVENT:
|
|
|
|
ec = createEventContextFrom<osquery_process_event_t>(event_type, event);
|
|
|
|
fire(ec);
|
|
|
|
break;
|
2015-06-30 21:16:43 +00:00
|
|
|
default:
|
2015-06-30 21:20:04 +00:00
|
|
|
LOG(WARNING) << "Unknown kernel event received: " << event_type;
|
2015-06-30 21:16:43 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
max_before_sync--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status(0, "Continue");
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename EventType>
|
|
|
|
KernelEventContextRef KernelEventPublisher::createEventContextFrom(
|
2015-06-30 21:20:04 +00:00
|
|
|
osquery_event_t event_type, CQueue::event *event) const {
|
2015-06-30 21:16:43 +00:00
|
|
|
TypedKernelEventContextRef<EventType> ec;
|
|
|
|
|
|
|
|
ec = std::make_shared<TypedKernelEventContext<EventType> >();
|
|
|
|
ec->event_type = event_type;
|
2015-06-30 21:20:04 +00:00
|
|
|
ec->time = event->time.time;
|
|
|
|
ec->uptime = event->time.uptime;
|
|
|
|
memcpy(&(ec->event), event->buf, sizeof(EventType));
|
2015-07-27 19:11:44 +00:00
|
|
|
ec->flexible_data.insert(ec->flexible_data.begin(),
|
|
|
|
event->buf + sizeof(EventType),
|
|
|
|
event->buf + event->size);
|
2015-06-30 21:16:43 +00:00
|
|
|
|
2015-06-30 21:20:04 +00:00
|
|
|
return std::static_pointer_cast<KernelEventContext>(ec);
|
2015-06-30 21:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernelEventPublisher::shouldFire(const KernelSubscriptionContextRef &sc,
|
|
|
|
const KernelEventContextRef &ec) const {
|
|
|
|
return ec->event_type == sc->event_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace osquery
|